Синтаксический анализатор

Автор: Пользователь скрыл имя, 10 Мая 2011 в 21:35, лабораторная работа

Краткое описание

Цель работы:
Изучение основных понятий теории грамматик простого и операторного предшествования, ознакомление с алгоритмами синтаксического анализа (разбора) для некоторых классов КС-грамматик, получение практических навыков создания простейшего синтаксического анализатора для заданной грамматики операторного предшествования.

Файлы: 1 файл

отчет по 3лабе СА.docx

— 82.91 Кб (Скачать)

  begin

    { Позиция  начала лексемы - первый символ }

    iStart := 1;

    { Запоминаем  текущую строку }

    sCurStr := listFile[i];

    { Цикл  по всем символам текущей строки }

    iStr := Length(sCurStr);

    for j:=1 to iStr do

    begin

      { Увеличиваем общий счетчик символов }

      Inc(iAll);

      { Моделируем работу КА в зависимости от состояния

        автомата и текущего символа  входной строки }

      case posCur of

        AP_START:

        begin

          { В начальном состоянии запоминаем позицию

            начала лексемы }

          iStart := j;

          iStComm := iAll-1;

          case sCurStr[j] of

            'i': posCur := AP_IF1;

            't': posCur := AP_THEN1;

            'e': posCur := AP_ELSE1;

            ':': posCur := AP_ASSIGN;

            ';': listLex.Add(TLexem.CreateKey(LEX_SEMI,iAll,i,j));

            '=': AddKeyToList(LEX_EQ,AP_START);

            '>': AddKeyToList(LEX_GT,AP_START);

            '<': AddKeyToList(LEX_LT,AP_START);

            '0'..'9': posCur := AP_CONST;

            'A'..'Z','a'..'d','f'..'h','j'..'s',

            'u'..'z','_': posCur := AP_VAR;

            '{': begin posCur := AP_COMM;comm_pos:=i;end;

            ' ',#10,#13,#9: ;

            else posCur := AP_ERR;

          end{case list};

        end;

        AP_IF1:   KeyLetter('f',AP_IF2);

        AP_IF2:   KeyFinish(LEX_IF);

        AP_THEN1: KeyLetter('h',AP_THEN2);

        AP_THEN2: KeyLetter('e',AP_THEN3);

        AP_THEN3: KeyLetter('n',AP_THEN4);

        AP_THEN4: KeyFinish(LEX_THEN);

        AP_ELSE1: KeyLetter('l',AP_ELSE2);

        AP_ELSE2: KeyLetter('s',AP_ELSE3);

        AP_ELSE3: KeyLetter('e',AP_ELSE4);

        AP_ELSE4: KeyFinish(LEX_ELSE);

        AP_ASSIGN:

          case sCurStr[j] of

            '=': AddKeyToList(LEX_ASSIGN,AP_START);

            else posCur := AP_ERR;

          end{case list};

        AP_VAR:

          case sCurStr[j] of

            ':': AddVarToList(AP_ASSIGN,j);

            '=': AddVarKeyToList(LEX_EQ,AP_START);

            '>': AddVarKeyToList(LEX_GT,AP_START);

            '<': AddVarKeyToList(LEX_LT,AP_START);

            ';': AddVarKeyToList(LEX_SEMI,AP_START);

            '0'..'9','A'..'Z','a'..'z','_':

                 posCur := AP_VAR;

            '{': begin AddVarToList(AP_COMM,j);comm_pos:=i;end;

            ' ',#10,#13,#9: AddVarToList(AP_START,j);

            else posCur := AP_ERR;

          end{case list};

        AP_CONST:

          case sCurStr[j] of

            ':': AddConstToList(AP_ASSIGN,j);

            '=': AddConstKeyToList(LEX_EQ,AP_START);

            '>': AddConstKeyToList(LEX_GT,AP_START);

            '<': AddConstKeyToList(LEX_LT,AP_START);

            ';': AddConstKeyToList(LEX_SEMI,AP_START);

            '0'..'9': posCur := AP_CONST;

            '{': begin AddConstToList(AP_COMM,j);comm_pos:=i;end;

            ' ',#10,#13,#9: AddConstToList(AP_START,j);

            else posCur := AP_ERR;

          end{case list};

        AP_COMM:

          case sCurStr[j] of

            '}': posCur := AP_START;

          end{case list};

      end{case pos};

      { Проверяем, не достигнут ли конец строки }

      if j = iStr then

      begin

        { Конец строки - это конец текущей  лексемы }

        case posCur of

          AP_IF2:   AddKeyToList(LEX_IF,AP_START);

          AP_THEN4: AddKeyToList(LEX_THEN,AP_START);

          AP_ELSE4: AddKeyToList(LEX_ELSE,AP_START);

          AP_CONST: AddConstToList(AP_START,j+1);

          AP_ASSIGN: posCur := AP_ERR;

          AP_IF1,AP_THEN1,AP_THEN2,AP_THEN3,

          AP_ELSE1,AP_ELSE2,AP_ELSE3,AP_VAR:

                    AddVarToList(AP_START,j+1);

        end{case pos2};

      end;

      { Проверяем не была ли ошибка  в лексемах }

      if posCur = AP_ERR then

      begin

        { Если была ошибка, вычисляем позицию

          ошибочной лексемы }

        iStart := (j - iStart)+1;

        { и запоминаем ее в виде фиктивной лексемы в начале

          списка для детальной диагностики  ошибки }

        listLex.Insert(0,

                  TLexem.CreateInfo('Недопустимая лексема',

                                    iAll-iStart,i,iStart));

        { Если ошибка, прерываем цикл }

        Break;

      end;

    end{for j};

    { В конце строки увеличиваем общий счетчик символов

      на 2: конец строки и возврат  каретки }

    Inc(iAll,2);

    { Если ошибка, запоминаем номер ошибочной строки

      и прерываем цикл }

    if posCur = AP_ERR then

    begin

      Result := i+1;

      Break;

    end;

  end{for i};

  { Если комментарий не был закрыт, то это ошибка }

  if posCur = AP_COMM then

  begin

    listLex.Insert(0,

             TLexem.CreateInfo('Незакрытый комментарий',

                               iStComm,iCnt,iAll-iStComm));

    Result := comm_pos+1;

  end

  else

  if not (posCur in [AP_START,AP_ERR]) then

  { Если КА не в начальном состоянии-это неверная лексема }

  begin

    listLex.Insert(0,

               TLexem.CreateInfo('Незавершенная лексема',

                                 iAll-iStart,iCnt,iStart));

    Result := iCnt;

  end;

end; 

end. 
 
 

Вывод:

    В ходе лабораторной работы были изучены  основные понятия грамматик простого и операторного предшествования, а  также алгоритмы синтаксического  анализа. Получены практические навыки создания простейшего синтаксического  анализатора для заданной грамматики операторного предшествования.  

Информация о работе Синтаксический анализатор