Причина, по которой это терпит неудачу с LALR, заключается в том, что он имеет предвидение 1 (в отличие от Эрли, у которого неограниченное предвидение), и это путается между attribute_name
и string
.Как только он совпадает с другим (в данном случае attribute_name
), он не может откатиться назад и сопоставить другое правило.
Если вы используете более низкий приоритет для терминала attribute_name, он будет работать.Например:
attribute_name: ATTR
ATTR.0: /[A-Za-z_][A-Za-z_#0-9]*/
Но рекомендуется использовать один и тот же терминал для обоих, если это возможно, чтобы синтаксический анализатор мог думать за вас, а не лексера.Вы можете добавить дополнительную проверку, если это необходимо, после выполнения анализа.
Оба подхода (изменение приоритета или объединение терминалов) решат вашу проблему.