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


Рис.1.  Система регулярных выражений


Лексический акцептор для табличного способа реализации КА.

class fAutomatAsTable

{

      int index;  //собственный индекс автомата в массиве

      textReader& inp;  //входной поток литер

      string w;   //строка для накопления текста слова

      bool inputExists;

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

      vector<vector<int> >& controlTable; //управляющая таблица автомата

      charToIndex& charToI;  

//транслитератор для преобразования кода литеры в индекс колонки УТ

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

      int hasOther;

//конструкторы

public: fAutomatAsTable(int no, charToIndex& cToI, vector<vector<int> >& ctlTbl,textReader& tr)

: inp(tr), charToI(cToI), controlTable(ctlTbl) //создадим нужные объекты

{

      index = no; //запомним собственный индекс

      inputExists = true;

//и установим флажок актуальности входного потока

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

      hasOther=0;

}

public: fAutomatAsTable(charToIndex& cToI, vector<vector<int> >& ctlTbl, textReader& tr)

:  inp(tr), charToI(cToI), controlTable(ctlTbl)

{

      fAutomatAsTable(0, cToI, ctlTbl, tr);

}

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

public: void setOther(int flag){

      hasOther = flag;

}

//основной метод лексического акцептора - чтение одного слова из входного потока и формирование лексемы

public: lexem getLexem()

{

      int curState = -1, curChar = -1, colIndex;    

//объявление и инициализация локальных переменных

      if(inputExists) { //если входной поток актуален

            for(curState = 0; ; )  

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

            {

                  if((curChar = inp.read()) < 0)     

//читаем очередную входную литеру; если возвращен признак исчерпания входного потока (-1)

                  {

                        colIndex = 0;    

//то устанавливаем колонку УТ, соответствующую эпсилон

                        inputExists = false;   

// и сбрасываем флажок актуальности входного потока

                  }

                  else

                        colIndex = charToI.getIndexOfChar((char)curChar);   //преобразуем код литеры в индекс колонки УТ

                  if((colIndex < 0) || (colIndex >= (int)controlTable[curState].size()))    

//если индекс колонки находится за пределами УТ

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

                        if(hasOther!=0)

                  colIndex = (int)controlTable[curState].size()1;

//устанавливаем его на последнюю колонку, формируемую специально для реализации выражений other[+] в мультиавтоматном варианте

                        else

                        {

                              curState = -2147483647;

                              break;

                        }

                  curState = controlTable[curState][colIndex];     

//выбираем из УТ номер следующего состояния

                  if((curChar < 0)||(curState < 0))  

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

                        break;      //выходим из цикла

                  w.push_back((char)curChar);  

//добавляем литеру к тексту слова

            }

            if((curState&0xc0000000)==0xc0000000)

                  inp.back(curChar);

            else

                  w.push_back((char)curChar);  

//добавляем литеру к тексту слова

      }

      lexem retLexem;

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