Пред.Страница След.Страница  Раздел Содержание

6.8. Программная реализация лексического анализатора

В качестве примера программной реализации лексического анализатора на языке java ниже приведен класс Automaton, описывающий преобразователь, построенный в соответствии с диаграммой переходов, изображенной на рисунке 6.5.

 

package converter;

/*Класс представляет собой реализацию автоматного преобразователя. В нем создаются все объекты, необходимые для работы анализатора. Диаграмма переходов автомата реализуется в методе nextToken() с помощью переключателя. Для получения очередного символа входного потока вызывается метод nextSym() объекта Lexer. Выходные токены строятся методами makeSymToken() и makeIdnToken() объекта LexTab. Обнаруженные ошибки с помощью исключений передаются объекту Lexer. */

public class Automaton {

  public Token tk;

  public Lexer lr;

  public LexTab lt;

  public Buffer bf;

  int isym;

  char sym;

//Переменная state фиксирует состояние автомата

  private char state = 'I';

  String s;

  public Automaton() {

    bf = new Buffer();

    lt = new LexTab();

    lt.init();

  }

//Получение ссылки на объект Lexer

  public void init(Lexer ll){lr = ll;}

//Передача ссылки на объект LexTab

  public LexTab getLexTab(){return lt;}

/* Метод, моделирующий работу автоматного преобразователя.

Возвращает построенный токен. */

  public Token nextToken() throws LexBug{

    while(true){

      if ( (isym = lr.nextSym()) == -1)return Token.Toknull;

      sym = (char) isym;

//Переключатель, реализующий диаграмму переходов.

      switch (state) {

        case 'I':

          if (Character.isLetter(sym)) {

            bf.startBuf();

            bf.addBuf(sym);

            state = 'A';

            break;

            }

             //Распознавание терминальных символов

          else if (sym == '{' || sym == '}' || sym == ':' ||
                  
sym == ';' || sym == ',' || sym == '(' ||
                  
sym == ')' || sym == '=' || sym == '|' ||
                  
sym == '&' || sym == '~') {

               tk = lt.makeSymToken(sym);

               return tk;

              }

              else {

                   System.out.println(sym + "   "+ lr.linenum +"
                                                  "+ lr.symnum);

                   throw new LexBug("Automaton.nextToken()
                                :Недопустимый входной с
имвол");}

        case 'A':  if(Character.isLetterOrDigit(sym)){

                     bf.addBuf(sym);

                     state = 'A';

                     break;

                   }

                   //Распознавание символов завершения идентификатор

                   else if(sym == ':' || sym == '=' ||
                        sym == '&' || sym == '|' || sym == ')'

                     || sym == ',' || sym == ';' ){

                   tk = lt.makeIdnToken(bf.getAll());

                   //Возврат символа завершения во входной поток.

                   lr.restore(sym);

                   state = 'I';

                   return tk;

                   }

                   else { System.out.println(sym + "   "+
                               lr.linenum +"   "+ lr.symnum);

                     throw new LexBug("Automaton.nextToken() :
                           
Недопустимый  символ окончания
                                            
идентификатора");

                   }

        default: throw new LexBug("Automaton.nextToken() :
                             Недопустимый  символ состояния");

      }//end switch

 

    } // end while

 

Полный текст программной реализации классов лексического анализатора Lexer можно найти в файле Converter_src.rar. Ссылка на этот файл расположена в конце раздела 7.9. Файл нужно скопировать в свой каталог и, затем, разархивировать.

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

 

Текст примера на входе лексического преобразователя

 

{

  bool: a1, b1, c1, dd, ee, ff, x11 ;

  a1 = true; b1 = false; c1 = a1; dd = b1;

           

     ee = ~(a1 | ~(b1 & ~( c1 | ~(dd | ee & ff))));

}

 

Последовательность токенов на выходе лексического преобразователя

 

Token: S    1

 

Token: I    4

 

Token: S    5

Token: K    0

 

Token: S    11

 

Token: S    7

Token: S    4

 

Token: K    2

 

Token: S    8

Token: I    3

 

Token: S    3

 

Token: I    5

Token: S    10

 

Token: I    5

 

Token: S    6

Token: I    4

 

Token: S    11

 

Token: S    7

Token: S    10

 

Token: I    3

 

Token: S    8

Token: I    5

 

Token: S    3

 

Token: I    6

Token: S    10

 

Token: I    6

 

Token: S    6

Token: I    6

 

Token: S    11

 

Token: I    7

Token: S    10

 

Token: I    4

 

Token: S    5

Token: I    7

 

Token: S    3

 

Token: I    8

Token: S    10

 

Token: I    7

 

Token: S    9

Token: I    8

 

Token: S    11

 

Token: S    9

Token: S    10

 

Token: S    7

 

Token: S    9

Token: I    9

 

Token: S    8

 

Token: S    9

Token: S    3

 

Token: I    3

 

Token: S    3

Token: I    3

 

Token: S    6

 

Token: S    2

Token: S    11

 

Token: S    7

 

Token: @    7777777

Token: K    1

 

Token: S    8

 

 

Token: S    3

 

Token: I    4

 

 

 

Содержимое Lex Table

 

bool

true

false

a1

b1

c1

dd

ee

ff

x11

 

Пред.Страница След.Страница  Раздел Содержание