(Примечание: этот ответ был взят из исходной грамматики, а не из попытки удалить левую рекурсию, что имеет дополнительные проблемы. Нет необходимости удалять левую рекурсию из грамматики, предоставляемой LALR (1 ) генератор парсеров типа SableCC.)
Действительно, основной проблемой является производство:
something = {assert} assert expression comexpr?
Эта постановка любопытна, отчасти потому, что имя нетерминала («что-то») не дает никакого намека на то, что это такое, а главным образом потому, что обычно можно ожидать, что assert expression
будет утверждением, а не частью выражение. И something
явно получено из expression
:
expression = multiplication
multiplication = topower
topower = something
Но производство assert
заканчивается expression
. Это приводит к двусмысленности, так как
assert 4 + 3
может быть проанализирован как: (некоторые шаги для краткости опущены):
expression = expression plus multiplication
| | |
V | |
something | |
| | |
V | |
assert expression | |
| | | |
| V V V
assert 4 + 3
Или, более естественно, как:
expression = something
|
V
assert expression
| |
| V
| expression plus multiplication
| | | |
| V V V
assert 4 + 3
Первый анализ кажется маловероятным, потому что assert
не (насколько я могу догадаться) на самом деле не возвращает значение. (Хотя второе было бы более естественным, если бы оператор был сравнением, а не сложением.)
Не видя определения языка, который вы пытаетесь проанализировать, я не могу дать конкретного предложения о том, как это исправить, но я бы хотел сделать assert
оператором и переименовать something
к чему-то более описательному («термин» встречается часто, хотя я обычно использую «атом»).