Таблица 2. Часть управляющей таблицы автомата с одним состоянием
В управляющей таблице строки соответствуют верхнему элементу в стеке, а столбцы – текущему входному символу. В управляющей таблице используются следующие обозначения: Push – положить в стек, Pop – снять верхний символ из стека, Next – прочитать следующий входной символ, Stop – останов по окончанию восстановления разбора правильного предложения.
Программная реализация рекурсивного спуска:
//Part_6: синтаксический акцептор/анализатор
//Part_6_3: собственно восстановление дерева грамматического разбора
public boolean parse(){
if(la==null)return false;
curWordIndex=getWordIndex(); //возьмем индекс первого терминала
if(FirstOne()) //вызовем метод, разбирающий начальный нетерминал
if(curWordIndex==0) //если этот метод возвратил истину и весь входной поток прочитан
return true; //последовательность слов правильна, возвращаем истину
return false; //если что-то не так - вернем признак ошибки
}
//все далее следующие методы:
// - имеют имя нетерминала, разбором которого каждый из них занимается
// - возвращают логическое значение
// - содержат ровно столько последовательно выполняющихся блоков, сколько правил в грамматике есть для данного нетерминала
// - каждый блок выполняется только при условии, что текущий терминал принадлежит множеству выбора донного правила
// - внутри блока организована обработка правой части правила последовательно символ за символом слева направо;
// в зависимости от того, чем является каждый очередной символ, делается следующее:
// - для нетерминала - вызывается метод, имеющий его имя и, если от него получена ложь, то ложь возвращается выше;
// - для терминала - его индекс сравнивается с индексом текущего терминала, при несовпадении возвращается ложь (эта проверка не выполняется, если терминал есть первый символ правила),
// затем из входного потока читается следующий терминал; терминал указывается в примечании к оператору сравнения;
// - для действия - оно выполняется (пустая правая часть правила приравнивается к действию, для таких правил формируется {});
// если выполнена обработка всех символов правой части (и не была возвращена ложь), то возвращается истина
// - если не будет выполнен ни один блок (текущий терминал не принадлежит множеству выбора ни одного правила) - возвращается значение ложь
private boolean FirstOne(){cCnt+=1;
if((curWordIndex>=0)&&SelSet[0].get(curWordIndex)){
if(!objects())return false;
return functions();
}
return false;
}
private boolean objects(){cCnt+=1;
if((curWordIndex>=0)&&SelSet[1].get(curWordIndex)){
curWordIndex=getWordIndex();
if(curWordIndex!=1)return false;
curWordIndex=getWordIndex();
if(curWordIndex!=32)return false;
curWordIndex=getWordIndex();
if(!definitions())return false;
if(curWordIndex!=33)return false;
curWordIndex=getWordIndex();
return objects();
}
if((curWordIndex>=0)&&SelSet[2].get(curWordIndex)){{}return true;
}
return false;
}
private boolean definitions(){cCnt+=1;
if((curWordIndex>=0)&&SelSet[3].get(curWordIndex)){
if(!type())return false;
return restdef();
}
return false;
}
private boolean restdef(){cCnt+=1;
if((curWordIndex>=0)&&SelSet[4].get(curWordIndex)){
curWordIndex=getWordIndex();
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.