Предположим, program
- это символ верхнего уровня в грамматике. То есть, это нетерминал, который должен соответствовать входу парсера.
Конечно, возможно, что program
также будет соответствовать несколько раз, прежде чем ввод завершится. Например, грамматика может выглядеть примерно так:
%start program
%%
program: %empty
| program declaration
В этой грамматике нет способа внедрить действие, которое выполняется только тогда, когда входные данные полностью проанализированы. Я понимаю, это то, что вы хотите сделать.
Но очень просто создать нетерминал, действие которого будет выполнено только один раз, в конце разбора. Все, что нам нужно сделать, это вставить новую «единицу продукции» в начале грамматики:
%start start
%%
start : program { /* Completion action */ }
program: %empty
| program declaration
Поскольку start
не появляется в правой части любого произведения в грамматике, оно может быть уменьшено только в конце анализа, когда анализатор уменьшил символ %start
. Таким образом, даже несмотря на то, что производство явно не включает в себя конечный токен, мы знаем, что этот конечный токен является токеном предварительного просмотра при выполнении действия сокращения.
Производство единиц - производство, правая часть которого содержит только один Символ - часто используются для запуска действий в стратегических точках c разбора, и приведенное выше является лишь одним из примеров техники.