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

      }

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

public:

      lexem getLexem()

      {

            if(lexStk.size() <= 0) 

//если стек пуст - вернуть лексему с ошибкой

            {

                  Lexem.groupIndex = -2147483647;

                  return Lexem;

            }

            ignoreLastWord = true; 

//временно установим флажок, чтобы войти в цикл

            while(ignoreLastWord)  

//пока флажок установлен - читаем очередное слово

            {

                  ignoreLastWord = false;

//перед чтением следующего слова сбросим флажок

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

                  Lexem = lexAcceptor->getLexem();

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

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

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

                  switch(lexAcceptor->getIndex())

                  {

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

                  case /*^=currentAutomat.index^*/:  

// Автомат:

/*^=currentAutomat.name^*/

                        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^*/

                        }

                        break; /*^endFor^*/

                  }

            }

            return Lexem;

      }

/*^endIf^*/

/*^if(arrayOfAutomat.hasOneItem)^*/

//Part_4_5: одноавтоматный ЛА

private:

      fAutomat* lexAcceptor;  //лексический акцептор

      bool ignoreLastWord;   

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

      lexem Lexem;      //текущая лексема

//Part_4_7: конструктор одноавтоматного ЛА

public:

      lexAnalyzer(textReader& rdr)

      {

            ignoreLastWord = false;

            faState* state;

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

//дальше идет создание автомата, его состояний, выходящих из них дуг и запоминание всего этого в соответствующих местах

            lexAcceptor = new fAutomat(/*^=currentAutomat.states.count^*/,rdr);/*^forEach(currentState in currentAutomat.states)^*/

            state = new faState(/*^=currentState.arcs.count^*/);/*^forEach(currentArc in currentState.arcs)^*/

            state->setArc(/*^=currentArc.stateTo^*/,string("/*^=currentArc.mark^*/"));/*^endFor^*/

            lexAcceptor->setState(/*^=currentState.index^*/,state);/*^endfor^*/

      }

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

public:

      lexem getLexem()

      {

      ignoreLastWord = true;  //временно установим флажок, чтобы войти в цикл

while(ignoreLastWord)   //пока флажок установлен - читаем очередное слово

            {

                  ignoreLastWord = false;

//перед чтением следующего слова сбросим флажок

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

                  Lexem = lexAcceptor->getLexem();

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

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