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

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

                  switch(Lexem.groupIndex)

                  {

                  case -1: //EOF

Lexem.groupIndex=/*^=EndOfFile.indexForGrammar^*/;break;/*^forEach(finalState in currentAutomat.finalStates)^*/

case /*^=finalState.index^*/: ///*^=finalState.groupName^*//*^if(finalState.wordNameUseInGrammar)^*/

Lexem.groupIndex=/*^=finalState.indexForGrammar^*/;/*^endIf^*/

                        /*^=finalState.action^*/break;/*^endFor^*/

                  }

            }

            return Lexem;

      }/*^endIf^*/

};

//end of Part_4

Для табличного способа:

class lexAnalyzer

{

textReader& inp;  //входной поток

WTStack<fAutomat> lexStk;//стек для хранения лексических акцепторов

vector<fAutomat> lexAcceptors;//массив лексических акцепторов

//набор соответствующих транслитераторов:

/*^forEach(currentAutomat in arrayOfAutomat)^*/

charToIndex charToI

/*^=currentAutomat.index^*/;/*^endFor^*/

//и управляющих таблиц:/*^forEach(currentAutomat in arrayOfAutomat)^*/

vector<vector<int> > controlTable

/*^=currentAutomat.index^*/;/*^endFor^*/

fAutomat lexAcceptor;   //текущий (активный) лексический акцепторvector<charToIndex*> charToI;    //текущий транслитераторbool ignoreLastWord; 

//флажок необходимости не возвращать (игнорировать) последнюю обнаруженную лексему

lexem Lexem;      //лексема

//Part_3_2: конструктор мультиавтоматного ЛА

public:

      lexAnalyzer(textReader& rdr)

            : inp (rdr)

      {

            ClearMemory();    //очистка памяти

            vector<int> temp;

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

//далее - формирование всех управляющих таблиц

/*^forEach(currentAutomat in arrayOfAutomat)^*/

//УТ автомата /*^=currentAutomat.name^*/

/*^forEach(currentState in currentAutomat.statesOpt)^*/

/*^forEach(currentCell in currentState.cells)^*/temp.push_back(/*^=currentCell.stateTo^*/);/*^endFor^*/controlTable/*^=currentAutomat.index^*/.push_back(temp); temp.clear();/*^endFor^*//*^endFor^*/

//здесь - формирование транслитераторов

/*^forEach(currentAutomat in arrayOfAutomat)^*//*^if(currentAutomat.hasRangesOfChars)^*/

//транслитератор автомата

/*^=currentAutomat.name^*//*^forEach(currentRange in currentAutomat.rangesOfChar)^*/

charToI/*^=currentAutomat.index^*/.addRange('/*^=currentRange.firstChar^*/','/*^=currentRange.lastChar^*/',/*^=currentRange.columnIndex^*/);/*^endFor^*//*^endIf^*//*^endFor^*/

//и, наконец, - создание всех лексических акцепторов

/*^forEach(currentAutomat in arrayOfAutomat)^*/

//конечный автомат 

/*^=currentAutomat.name^*/lexAcceptors.push_back(new fAutomatAsTable(/*^=currentAutomat.index^*/,charToI/*^=currentAutomat.index^*/,controlTable/*^=currentAutomat.index^*/,rdr));/*^if(arrayOfAutomat.hasManyItems)^*/

//мультиавтоматный вариант

lexAcceptors[/*^=currentAutomat.index^*/]->setOther(/*^=currentAutomat.hasOtherColumn^*/);/*^endIf^*//*^endFor^*/

lexAcceptor = lexAcceptors[0];     

//текущим установим автомат с индексом 0

lexStk.push(lexAcceptor);     //и запомним его в стеке

      }

public:

      virtual ~lexAnalyzer()

      {

            ClearMemory();

      }

private:

      void ClearMemory()      //удаление всего

      {

            for(int i = 0; i < (int)lexAcceptors.size(); i++)

                  delete lexAcceptors[i];

            lexAcceptors.clear();

            lexAcceptor = NULL;

      }

//Part_3_3: распознавание слова и формирование лексемы

public:

      lexem getLexem()

      {

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