为什么我们在编译器中既需要先行符号又需要预读符号

时间:2019-04-11 20:23:43

标签: parsing compiler-construction

好吧,我正在阅读一些有关在编译器中进行解析的常见概念。.我遇到look ahead并阅读了ahead symbol,我搜索并阅读了它们,但是我被困住了,为什么我们都需要它们?会很感谢任何建议

  

先行符号:当在分析树中考虑的节点用于终端时,   终端匹配前瞻符号,然后我们在解析和   输入

     

预读符号:词法分析器可能需要读取一些字符   在决定要返回的令牌之前

2 个答案:

答案 0 :(得分:3)

其中之一与语法分析有关,并指向词法扫描程序要生成的下一个 token 。另一个不那么正式,是关于词法分析的,它引用输入流中的下一个 character 。应该清楚是哪个。

请注意,尽管大多数解析器仅需要单个前瞻标记,但词法分析必须回溯并不少见,这相当于检查了几个未使用的输入字符。

答案 1 :(得分:1)

我希望你的问题正确。

考虑C。

它有几个以相同方式开始的标点符号:

  • ++++=
  • ----=->
  • <<=<<<<=
  • ...

要弄清楚当您看到第一个+-<时是哪个,您需要在输入中向前看一个字符(然后可能是一个<<=的更多信息。

类似的事情可能会在更高层次上发生:

{
  ident1 ident2;
  ident3;
  ident4:;
}

此处ident1ident3ident4可以开始声明,表达式或标签。您无法立即分辨出哪个。您可以查阅现有的声明,以查看是否已经知道ident1ident3(作为类型或变量/函数/枚举),但是它仍然是模棱两可的,因为冒号可能跟在后面,如果冒号了标签,因为允许标签和类型/变量/函数/枚举(这两个名称空间不相交)使用相同的标识符,例如:

{
  typedef int ident1;
  ident1 ident2; // same as int ident2
  int ident3 = 0;
  ident3; // unused expression of value 0
  ident1:; // unused label
  ident2:; // unused label
  ident3:; // unused label
}

因此,您可能非常需要提前处理字符或令牌(或“未读”的字符)以应对此类情况。