Давайте создадим компилятор! :: Креншоу Джек
Страница:
36 из 382
Неудивительно, что мы начинаем с еще одной подпрограммы распознавания:
{–}
{ Recognize White Space }
function IsWhite(c: char): boolean;
begin
IsWhite := c in [' ', TAB];
end;
{–}
Нам также нужна процедура, «съедающая» символы пробела до тех пор, пока не найдет отличный от пробела символ:
{–}
{ Skip Over Leading White Space }
procedure SkipWhite;
begin
while IsWhite(Look) do
GetChar;
end;
{–}
Сейчас добавьте вызовы SkipWhite в Match, GetName и GetNum как показано ниже:
{–}
{ Match a Specific Input Character }
procedure Match(x: char);
begin
if Look <> x then Expected('''' + x + '''')
else begin
GetChar;
SkipWhite;
end;
end;
{–}
{ Get an Identifier }
function GetName: string;
var Token: string;
begin
Token := '';
if not IsAlpha(Look) then Expected('Name');
while IsAlNum(Look) do begin
Token := Token + UpCase(Look);
GetChar;
end;
GetName := Token;
SkipWhite;
end;
{–}
{ Get a Number }
function GetNum: string;
var Value: string;
begin
Value := '';
if not IsDigit(Look) then Expected('Integer');
while IsDigit(Look) do begin
Value := Value + Look;
GetChar;
end;
GetNum := Value;
SkipWhite;
end;
{–}
(Обратите внимание, как я немного реорганизовал Match без изменения функциональности.)
Наконец, мы должны пропустить начальные пробелы в том месте, где мы «запускаем помпу» в Init:
{–}
{ Initialize }
procedure Init;
begin
GetChar;
SkipWhite;
end;
{–}
Внесите эти изменения и повторно откомпилируйте программу. Вы обнаружите, что необходимо переместить Match ниже SkipWhite чтобы избежать сообщение об ошибке от компилятора Pascal. Протестируйте программу как всегда, чтобы удостовериться, что она работает правильно.
Поскольку мы сделали довольно много изменений в течение этого урока, ниже я воспроизвожу полный текст синтаксического анализатора:
{–}
program parse;
{–}
{ Constant Declarations }
const TAB = ^I;
CR = ^M;
{–}
{ Variable Declarations }
var Look: char; { Lookahead Character }
{–}
{ Read New Character From Input Stream }
procedure GetChar;
begin
Read(Look);
end;
{–}
{ Report an Error }
procedure Error(s: string);
begin
WriteLn;
WriteLn(^G, 'Error: ', s, '.
|< Пред. 34 35 36 37 38 След. >|