RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:9:30-18:00
你可能遇到了下面的问题
关闭右侧工具栏
LET'S BUILD A COMPILER!(5)
  • 作者:xiaoxiao
  • 发表时间:2020-12-23 10:57
  • 来源:未知

LET'S BUILD A COMPILER!(4)---第三部分:再论表达式续

空白字符

结束本章之前,我们再来讨论一下空白字符的问题。现在这个版本的分析器会在读到一个空白字符的地方停下来。这是相当不友好的行为。所以让我们消除这个最后的限制,使分析器的表现更有商业产品的味道。

处理空白字符的关键在于制定一条规则,规定分析器改如何处理对待输入的空白字符,并在整个分析器中都遵守它。目前为止,空白字符还是不被允许的,我们可以假定在每个分析动作之后,先行字符Look都包含的是个有意义的字符,然后可以立即验证这点。我们设计的方法就是基于上述原则。

具体来说,就是每个需要先行读取输入流的过程都必须忽略空白字符,并且最后Look变量中只能保留非空白字符。所幸,我们是用GetName,GetNum和Match完成大部分了输入操作,所以只有三个过程(再加上Init过程)需要修改。

首先,定义一个新的识别空白字符的过程。

{--------------------------------------------------------------}{ 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;{--------------------------------------------------------------}

现在,在Match,GetName和GetNum过程中调用SkipWhite:

{--------------------------------------------------------------}{ 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;{--------------------------------------------------------------}