【问题标题】:Boundary between Lexer and ParserLexer 和 Parser 之间的边界
【发布时间】:2017-08-06 12:01:59
【问题描述】:

我正在做一个宠物项目,我必须实现一个词法分析器/解析器。我正在阅读有关该主题的内容并制作一个简单的数学解析器的原型,以便我理解。

有些东西我还是不太明白,它是词法分析器和解析器之间的边界。考虑以下语法错误的表达式:

+1.234.2 + pi

我目前正在将其转换为以下内容:

UnaryPlusOperatorToken: Lexeme "+" Pos: 1
NumberToken: Lexeme "1.234.2" Pos: 2
TriviaToken: Lexeme " " Pos: 9
BinaryAddToken: Lexeme "+" Pos: 10
TriviaToken: Lexeme " " Pos: 11
ConstantToken. Lexeme "pi" Pos: 12

好的,这里有几件事:

  1. 词法分析器是否应该真正关心NumberToken 中错误的额外小数点,并在我正在遍历整个解析上下文的“错误包”中添加一个错误,还是应该是稍后捕获此问题的解析器?
  2. 词法分析器应该区分“+”在一种情况下是一元运算符还是在另一种情况下是二元运算符?还是应该简单地生成一个PlusToken,然后让解析器找出它是什么?

我发现很难理解两者之间的界限在哪里。

【问题讨论】:

  • 恕我直言 1. NumberToken 应该是“1.234”,后跟一个“InvalidToken: .” 2. 解释是解析器的工作。

标签: parsing lexer compiler-construction


【解决方案1】:

这是我的看法:

词法分析器是否应该真正关心 NumberToken 中错误的额外小数点,并将错误添加到我正在遍历整个解析上下文的“错误包”中,还是应该由解析器稍后捕获?

让我们看看你的选择是什么,并比较优缺点:

  • 如果您在小数点后第二位停止扫描,您的解析器将获得以下两个令牌:1.234 .2 并且必须发出“意外令牌”之类的错误。

  • 如果词法分析器将1.234.2 扫描为单个标记,您将很容易发出“无效号码”之类的错误。

第二种选择会发出更好的错误消息,并且与第一种选择一样易于实施,所以我会说这是更好的解决方案。你这里有一个无效的令牌,这样对待它。

词法分析器应该区分“+”在一种情况下是一元运算符还是在另一种情况下是二元运算符?还是应该简单地生成一个 PlusToken,然后让解析器找出它是什么?

不。词法分析器应该只输出一个+ 标记。在解析器规则的上下文中进一步解释该标记的含义是解析器的角色。


词法分析器和解析器之间的限制有时可能非常模糊。虽然有些顾虑很容易出现在任何一方而没有任何问题,但如果你打错电话,其他顾虑会在以后咬你,所以在做出设计选择时要格外小心。

【讨论】:

  • 谢谢!那么我是否应该理解词法分析器根本不应该在解析上下文中添加错误并让解析器稍后完成这项工作?
  • 词法分析器肯定会发出错误,但这些错误大多属于“格式错误的标记”类型。像“这个令牌不属于这里”这样的错误最好留给解析器处理。但同样,这取决于。例如,假设您想禁止像 4--2 这样的表达式(而不是像 4-(-2) 那样解析它们),直接从词法分析器处理标记序列 - - 可能更容易,但是取决于您的实施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 2016-09-10
相关资源
最近更新 更多