retLexem.groupIndex = (curState >= 0 ? -2147483647 : curState | 0x40000000); //сформируем индекс группы слов
if( (curState = (int)w.length()) > 0 )
//если слово содержит хотя бы одну литеру
{
retLexem.textOfWord.append(w); //перепишем его в лексему
w.erase(0,curState);
//и подготовим строку для накопления текста следующего слова
}
return retLexem; //вернем лексему
}
public: int getIndex()
{
return index;
}
};
Лексический акцептор для графового способа реализации КА.
class fAutomat
{
int index; //собственный индекс акцептора (имеет смысл в мультиавтоматном варианте)
vector<faState*> states; //множество состояний графа
textReader& inp; //входной поток литер
string w; //накопитель текста слова
bool inputExists; //флажок состояния входного потока
//конструктор одноавтоматного варианта
public: fAutomat(int nodesCount, textReader& Inp)
: states(nodesCount), inp(Inp)
{
fAutomat(0, nodesCount, Inp);
}
//конструктор мультиавтоматного варианта
public: fAutomat(int ind, int nodesCount,textReader& Inp)
: states(nodesCount), inp(Inp)
{
for (int i = 0; i < nodesCount; i++)
states[i] = NULL;
//заполним нулями массив состояний (вершин графа)
index = ind; //запомним собственный индекс
inputExists = true;
//установим флажок, что входной поток не исчерпан
}
//сохранение заданного состояния (вершины)
public: void setState(size_t no, faState* st)
{
if((no >= 0) && ( no < states.size()))
//если номер состояния в заданных пределах
states[no] = st; //сохраним состояние в массиве
} //иначе ничего не делаем
//основной метод лексического акцептора - чтение одного слова из входного потока и формирование лексемы
public: lexem fAutomat::getLexem()
{
int curState = -1;
//текущее состояние (-1 на случай, если входной поток ранее был исчерпан)
int curChar = -1;
//текущая литера (-1 на случай, если входной поток ранее был исчерпан)
int newState;
if(inputExists) //если входной поток существует
for(curState = 0; curState>=0; )
//запускаем цикл имитации работы конечного автомата, выполняющийся до тех пор, пока не было перехода в финальное состояние или не обнаружена ошибка
{
try
{
curChar = inp.read();
//пытаемся получить очередную литеру
}
catch(...) //(exception &e)
{
curChar = -1;
//если это не удалось, формируем значение кода литеры -1
}
if(curChar == -1) //если код литеры равен -1
{
inputExists = false;
//сбрасываем флажок существования входного потока
//и формируем текущее состояние
//-1, если конец входного потока обнаружен в момент запуска автомата
//и номер финального состояния, в которое из текущего есть переход по эпсилон в противном случае
//(возможен случай, когда такого перехода нет, тогда получим значение -2147483647)
newState = (curState == 0 ? -1 : states[curState]->getFinalState());
}
else //если код литеры получен
{
newState = states[curState]->getState((char)curChar); //получаем новый номер состояния
if((newState==-1)&&(curState==0))
newState=-2147483647;
}
//если номер нового состояния вне пределов массива состояний или код литеры меньше нуля - выйдем из цикла
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.