为什么在词法分析器规范中对换行符和空格的区别对待?

问题描述

我正在使用F#的fslex生成词法分析器。我很难理解教科书中的以下两行内容。为什么换行符(\ n)与空格不同?特别是,“ lexbuf.EndPos

rule Tokenize = parse
  | [' ' '\t' '\r'] { Tokenize lexbuf }
  | '\n'            { lexbuf.EndPos <- lexbuf.EndPos.NextLine; Tokenize lexbuf }

解决方法

rule本质上是一个将词法分析器缓冲区作为参数的函数。规则左侧的每个大小写均匹配 输入中的给定字符(例如'\n')或字符类别([' ' '\t' '\r'])。花括号{ ... }内的规则大小正确的表达式定义了 action 。您粘贴的定义的目的似乎是 tokenizer

表达式Tokenize lexbuf是对Tokenize规则的递归调用。本质上,此规则忽略空白字符。为什么?因为令牌生成器旨在简化输入。空格在编程语言中通常没有任何意义,因此此规则将其过滤掉。标记化的输入通常会使以后编写解析器更加简单。您最终将需要在Tokenize规则中添加其他大小写(例如,用于关键字,赋值语句和其他表达式),以产生完整的词法分析器定义。

第二个规则,即与\n匹配的规则,也忽略了空格,但是正如您正确指出的那样,它做了一些不同的事情。它的工作是在递归调用lexbuf.EndPos之前,用下一行的结尾lexbuf.EndPos.NextLine)来更新行的结尾(Tokenize)的位置。再次。为什么?大概是这样,以便在下一次递归调用时结束位置正确。

由于您仅在此处显示一个词法分析器片段,因此我只能猜测lexbug.EndPos的用途,但是保留该信息以用于诊断目的是很常见的。