Код также смотрится намного лучше,по крайней мере в том смысле, что DoMain и DoProc выглядят более похоже:
{–}
{ Parse and Translate a Main Program }
procedure DoMain;
var N: char;
begin
Match('P');
N := GetName;
Fin;
if InTable(N) then Duplicate(N);
Prolog;
BeginBlock;
end;
{–}
.
.
.
{–}
{ Parse and Translate Global Declarations }
procedure TopDecls;
begin
while Look <> '.' do begin
case Look of
'v': Decl;
'p': DoProc;
'P': DoMain;
else Abort('Unrecognized Keyword ' + Look);
end;
Fin;
end;
end;
{–}
{ Main Program }
begin
Init;
TopDecls;
Epilog;
end.
{–}
Так как объявление основной программы теперь внутри цикла TopDecl, возникают некоторые трудности. Как мы можем гарантировать, что она – последняя в файле? И выйдем ли мы когда либо из цикла? Мой ответ на второй вопрос, как вы можете видеть, – в том, чтобы вернуть нашего старого друга точку. Как только синтаксический анализатор увидит ее дело сделано.
Ответ на первый вопрос: он зависит от того, насколько мы хотим защищать программиста от глупых ошибок. В коде, который я показал, нет ничего, предохраняющего программиста от добавления кода после основной программы... даже другой основной программы. Код просто не будет доступен. Однако, мы могли бы обращаться к нему через утверждение FORWARD, которое мы предоставим позже.