Вы должны прочитать о парсерах LR или shift-lower.Они собирают дерево разбора снизу вверх.В случае функции main
она выглядит следующим образом:
- сдвиг
int
в стек в качестве токена терминала TYPE - сдвиг
main
в стек в качестве ИДЕНТИФИКАТОРАтерминальный токен - сдвиг
(
в стек - сдвиг
)
в стек - удаление
(
и )
и замена на ARGLIST non-терминальный токен - сдвиг
{
в стек - сдвиг
}
в стек - удалить их и заменить на нетерминальный токен STMT_BLOCK
- удалите токены TYPE, IDENTIFIER, ARGLIST и STMT_BLOCK и замените их токеном FUNCTION_DEF.
Конечно, каждый раз, когда выполняется замена, он создает новый фрагмент дерева разбора и присоединяет егона новый токен.(Я составил эти имена токенов.)
Он работает под управлением конечного автомата, который распознает шаблон токенов в стеке и вместе со следующим (единственным) токеном ввода решает, следует ли сдвигатьследующий токен или примените одно из правил грамматики, чтобы свести группу токенов в стеке в один.FSM построен генератором синтаксического анализатора из списка правил грамматики.
Он называется LR, потому что он читает входные токены слева, но применяет правила грамматики справа.Это отличается от LL, или рекурсивного спуска, который применяет грамматические правила слева.Паскаль является языком LL (1).C не является LL (1), поэтому требует анализатор LR (1).Это позволяет C, например, вставлять практически все в вложенные скобки, не путая синтаксический анализатор.
Надеюсь, это поможет вам увидеть, что происходит.