Похоже, ваша грамматика немного нарушена. Предположим, что кто-то выбирает вывод, подобный следующему:
program --> endstart <statement> endstart
--> endstart <read> endstart
--> endstart read <var>
Используя текущую грамматику, вы не сможете использовать рекурсию для продолжения предложения на языке, поскольку после того, как нетерминальный var был полностью выведен, не будет никаких обратных ссылок на нетерминальный оператор < / em>.
Я бы рассмотрел следующую грамматику в соответствии с вашими потребностями:
<statement> --> <read> | <compute>
<read> --> read <var> <statement> | read <var>
<compute> --> compute <print> <statement> | compute <print> | compute <statement> | compute
<print> --> print <var>
<var> --> <letter> | <letter><var>
<letter> --> A|B|C|...
Теперь давайте вывести предложение «endstart read SAM read TED compute compute print FRED compute read TIM endstart», используя подстановку LHS:
program --> endstart <statement> endstart
--> endstart <read> endstart endstart
--> endstart read <var> <statement> endstart
--> endstart read <letter><var> <statement> endstart
--> endstart read S<var> <statement> endstart
--> endstart read S<letter><var> <statement> endstart
--> endstart read SA<var> <statement> endstart
--> endstart read SA<letter> <statement> endstart
--> endstart read SAM <statement> endstart
--> endstart read SAM <read> endstart
--> endstart read SAM read <var> <statement> endstart
--> endstart read SAM read <letter><var> <statement> endstart
--> endstart read SAM read T<var> <statement> endstart
--> endstart read SAM read T<letter><var> <statement> endstart
--> endstart read SAM read TE<var> <statement> endstart
--> endstart read SAM read TE<letter> <statement> endstart
--> endstart read SAM read TED <statement> endstart
--> endstart read SAM read TED <compute> endstart
--> endstart read SAM read TED compute <statement> endstart
--> endstart read SAM read TED compute <compute> endstart
--> endstart read SAM read TED compute compute <print> <statement> endstart
--> endstart read SAM read TED compute compute print <var> <statement> endstart
... play the same game to spell out FRED ...
--> endstart read SAM read TED compute compute print FRED <statement> endstart
--> endstart read SAM read TED compute compute print FRED compute <statement> endstart
--> endstart read SAM read TED compute compute print FRED compute <read> endstart
--> endstart read SAM read TED compute compute print FRED compute read <var> endstart
... play the same game to spell out TIM ...
--> endstart read SAM read TED compute compute print FRED compute read TIM endstart
Теперь, когда у нас есть вывод, можно решить проблему двусмысленности. Вам следует задать вопрос, есть ли в грамматике дополнительное дерево синтаксического анализа. Уловка заключается в том, чтобы смотреть на грамматику и пытаться идентифицировать любые нетерминалы, у которых есть продукты, которые содержат экземпляр самого себя, который может привести к тому или иному пути. Считать
<statement> --> <statement><statement> | some_terminal
Для такого рода продукции синтаксический анализатор должен решить, по какому пути идти вниз (в данном случае, какой оператор заменить первым). Если в вашей грамматике нет произведений с таким свойством, обычно это однозначно.
И отвечу на ваш вопрос - нет, исправленная грамматика не неоднозначна.
person
8bitoverflow
schedule
14.01.2015