96
{ Main Program }
begin
Init;
DoProgram;
end.
Пара комментариев:
•
Форма синтаксического анализатора выражений, использующего FirstTerm и т.п.,
немного отличается от того, что вы видели ранее. Это еще одна вариация на ту
же самую тему. Не позволяйте им вертеть вами... изменения необязательны для
того, что бу дет дальше.
•
Заметьте, что как обычно я добавил вызовы Fin в стратегических местах для
поддержки множественных строк.
Прежде чем приступить к добавлению сканера, сначала скопируйте этот файл и
проверьте, что он действительно корректно выполняет анализ. Не забудьте "кода": "i" для
IF, "l" для ELSE и "e" для ELSE или ENDIF.
Если программа работает, тогда давайте поспешим. При добавлении модулей сканера
в программу поможет систематический план. Во всех синтаксических анализаторах,
которые мы написали до этого времени, мы придерживались соглашения, что текущий
предсказывающий символ должен всегда быть непустым символом. Мы предварительно
загружали предсказывающий символ в Init и после этого оставляли "помпу запущенной".
Чтобы позволить программе работать правильно с новыми строками мы должны ее
немного модифицировать и обрабатывать символ новой строки как допустимый токен.
В многосимвольной версии правило аналогично: текущий предсказыващий символ
должен всегда оставаться на начале следующей лексемы или на новой строке.
Многосимвольная версия показана ниже. Чтобы получить ее я сделал следующие
изменения:
•
Добавлены переменные Token и Value и определения типов, необходимые для
Lookup.
•
Добавлено определение KWList и KWcode.
•
Добавлен Lookup.
•
GetName и GetNum заменены их многосимвольными версиями. (Обратите
внимание, что вызов Lookup был перемещен из GetName, так что он не будет
выполняться внутри выражений).
•
Создана новая, рудиментарная Scan, которая вызывает GetName затем
сканирует ключевые слова.
•
Создана новая процедура MatchString, которая ищет конкретное ключевое слово.
Заметьте, что в отличие от Match, MatchString не считывает следующее
ключевое слово.
•
Изменен Block для вызова Scan.
•
Немного изменены вызовы Fin. Fin теперь вызывается из GetName.