Лексика языков программирования. Конечные автоматы без памяти для обнаружения слов в тексте программы, страница 4

                  if(((curState=newState) < 0)||(curState >= (int)states.size())||(curChar < 0))

                        break;

                  w.push_back((char)curChar);  

//если по этой литере был выполнен переход в рабочее состояние - добавим ее к тексту слова

            }

            if((curState < -1) && (curState > -2147483647))      //если не EndOfFile и не ошибка (в частности ошибкой является случай, когда curState>=0)

                  inp.back(curChar);      //вернем литеру во входной поток

            lexem retLexem;   //образуем новую лексему

            retLexem.wordIndex = 0;       //индекс слова установим в 0

            retLexem.groupIndex = (curState >= 0 ? -2147483647 : curState);      //сформируем индекс группы слов

            if((curState = (int)w.length()) > 0)     //если слово содержит хотя бы одну литеру

            {

                  retLexem.textOfWord.append(w);     

//поместим текст слова в лексему

                  w.erase(0,curState);   

//и подготовимся к накоплению текста следующего слова

            }

            return retLexem;  //вернем лексему

}

public: int getIndex()  //возвращает индекс акцептора, нужен в мультиавтоматном варианте

{

      return index;

}

};

Сравнение реализации конечных автоматов, управляемых различными способами, между собой:

1.  В плане написания алгоритма на каком-то языке (в частности на C++) для каждого из этих способов. Код по объему окажется приблизительно одинаковой, как в одном, так и другом способе нужны дополнительные классы (для таблиц это класс (преобразователь кода символа в индекс), а для графа это класс (дуга графа состояний и переходов конечного автомата)). Сложность алгоритмов тоже приблизительно одинаковая.

2.  Для восприятия и понимая, лучше подходит графовой способ, чем табличный. Это возможно обусловлено, тем, что графой способ отображается в виде рисунка и содержит меньше чисел, чем табличный.

3.  Но табличный способ отображает все переходы в полном объеме, часто графовом способом не все видно наглядно. Когда из графогово способа, переходят к табличному способу, становиться видно автомат полностью определенный или нет.

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


4.Изучил реализацию вызова действий, определенных в лексических правилах и алгоритм работы формирователя лексем (см. ст. 8-9  для табличного способа, ст. 10-11 для графового способа).

          Вызов действий, определенных в лексических правил:

public:

      lexem getLexem()

      {

                  if(lexStk.size()<=0)    //если стек пуст - вернем лексему-ошибку

                  {

                        Lexem.groupIndex = -2147483647;

                        return Lexem;

                  }

ignoreLastWord = true; 

//для входа в основной цикл установим флажок игнорирования слова

                  while(ignoreLastWord)

                  {

                        ignoreLastWord = false;

//и сбросим его (возможно, он будет установлен действием)

                        //вызов лексического акцептора:

                        Lexem = lexAcceptor->getLexem();   

//получим лексему от текущего лексического акцептора

//для каждого автомата и каждой группы слов обеспечим возможность выполнения действий (имена автоматов и групп слов в примечаниях)

//индексы групп слов, имена которых используются в грамматике, преобразуются в те значения, который присвоил им построитель синтаксического акцептора

//в действиях, в частности, может быть взведен флажок ignoreLastWord и изменены поля лексемы, установленные акцептором