Давайте создадим компилятор! :: Креншоу Джек
Страница:
129 из 382
Во всех синтаксических анализаторах, которые мы написали до этого времени, мыпридерживались соглашения, что текущий предсказывающий символ должен всегда быть непустым символом. Мы предварительно загружали предсказывающий символ в Init и после этого оставляли «помпу запущенной». Чтобы позволить программе работать правильно с новыми строками мы должны ее немного модифицировать и обрабатывать символ новой строки как допустимый токен.
В многосимвольной версии правило аналогично: текущий предсказыващий символ должен всегда оставаться на начале следующей лексемы или на новой строке.
Многосимвольная версия показана ниже. Чтобы получить ее я сделал следующие изменения:
• Добавлены переменные Token и Value и определения типов, необходимые для Lookup.
• Добавлено определение KWList и KWcode.
• Добавлен Lookup.
• GetName и GetNum заменены их многосимвольными версиями. (Обратите внимание, что вызов Lookup был перемещен из GetName, так что он не будет выполняться внутри выражений).
• Создана новая, рудиментарная Scan, которая вызывает GetName затем сканирует ключевые слова.
• Создана новая процедура MatchString, которая ищет конкретное ключевое слово. Заметьте, что в отличие от Match, MatchString не считывает следующее ключевое слово.
• Изменен Block для вызова Scan.
• Немного изменены вызовы Fin. Fin теперь вызывается из GetName.
Программа полностью:
{–}
program KISS;
{–}
{ Constant Declarations }
const TAB = ^I;
CR = ^M;
LF = ^J;
{–}
{ Type Declarations }
type Symbol = string[8];
SymTab = array[1..
|< Пред. 127 128 129 130 131 След. >|