Единственное, что я собирался предложить, помимо введения воображаемых токенов, чтобы убедиться, что ваша древовидная грамматика производит «уникальный AST», и упрощение expression
в дереве -граммы, которую вы оба ужесделал (опять же: хорошо сделано!), это то, что вы не должны использовать буквенные токены внутри грамматики вашего синтаксического анализатора.Особенно, если они не могут быть сопоставлены с другими правилами лексера.Например, все ваши зарезервированные слова (например, for
, while
, end
и т. Д.) Также могут соответствовать правилу лексера IDENTIFIER
.Лучше создавать явные токены внутри лексера (и поместить эти правила перед правилом IDENTIFIER
!):
...
FOR : 'for';
WHILE : 'while';
END : 'end';
...
IDENTIFIER
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
...
В идеале, грамматика дерева не содержит никаких токенов в кавычках.AFAIK, вы не можете импортировать грамматику X
внутри грамматики Y
правильно: буквенные маркеры внутри грамматики X
тогда недоступны в грамматике Y
.И когда вы разбиваете свою объединенную грамматику на грамматику синтаксического анализатора и лексера, эти буквальные токены не допускаются.С такими маленькими грамматиками, как ваша, эти последние замечания вас не касаются (и вы можете оставить свою грамматику «как есть»), но помните их, когда создаете большие грамматики.
Удачи!
РЕДАКТИРОВАТЬ
Воображаемые токены полезны не только тогда, когда нет настоящего токена, который можно сделать корнем дерева.То, как я смотрю на воображаемые токены, состоит в том, что они делают ваше дерево «уникальным», так что грамматика дерева может «ходить» по вашему дереву только одним возможным способом.Возьмите к примеру вычитание и унарный минус.Если бы вы не создали воображаемый токен с именем UNARY_MINUS
, а просто сделали это:
unary_operation
: '-' primary -> ^('-' primary)
| 'not' primary -> ^('not' primary)
| primary
;
, то в вашей грамматике дерева было бы что-то вроде этого:
expression
: ^('-' expression expression)
| ...
| ^('-' expression)
| ...
;
Теперь и вычитание, и унарный минус начинаются с одинаковых токенов, которые древовидная грамматика не любит!Это легко увидеть на этом примере -
(минус), но могут быть довольно сложные случаи (даже с такими маленькими грамматиками, как ваша!), Которые не так очевидны.Поэтому всегда разрешайте анализатору создавать «уникальные деревья» при переписывании в AST.
Надеюсь, что это проясняет (немного).