Parsing 那么这些语法和识别它的最小解析器呢?

Parsing 那么这些语法和识别它的最小解析器呢?,parsing,grammar,context-free-grammar,Parsing,Grammar,Context Free Grammar,我正在努力学习如何制作编译器。为了做到这一点,我读了很多关于上下文无关语言的书。但有些事情我自己还不能做到 因为这是我的第一个编译器,所以有一些我不知道的实践。我的问题是为了构建一个解析器生成器,而不是编译器,也不是词法分析器。有些问题可能是显而易见的 我读的书有:。显示的图片来自:。都来自斯坦福CS143班 以下是要点: (模棱两可/不模棱两可)和(左递归/右递归)如何影响对一种算法或另一种算法的需求?还有其他方法来限定语法吗 1) 歧义语法是具有多个解析树的语法。但是,选择最左边的派生还是

我正在努力学习如何制作编译器。为了做到这一点,我读了很多关于上下文无关语言的书。但有些事情我自己还不能做到

因为这是我的第一个编译器,所以有一些我不知道的实践。我的问题是为了构建一个解析器生成器,而不是编译器,也不是词法分析器。有些问题可能是显而易见的

我读的书有:。显示的图片来自:。都来自斯坦福CS143班

以下是要点:

(模棱两可/不模棱两可)和(左递归/右递归)如何影响对一种算法或另一种算法的需求?还有其他方法来限定语法吗

1) 歧义语法是具有多个解析树的语法。但是,选择最左边的派生还是最右边的派生不应该导致解析树的唯一性吗

[编辑:已回答]

2.1)但语法的歧义是否与k有关?我的意思是给出一个LR(2)语法,它对于LR(1)解析器是不明确的,对于LR(2)解析器是不明确的

[编辑:不,不是这样,LR(2)语法意味着解析器需要两个前瞻标记来选择要使用的正确规则。另一方面,不明确的语法可能导致多个解析树。]

2.2)所以,只要你能想象,LR(*)解析器将完全没有歧义语法,然后可以解析整个上下文无关语言集

[编辑:由Ira Baxter回答,LR(*)不如GLR强大,因为它不能处理多个解析树。]

3) 根据前面的答案,下面的内容可能自相矛盾。考虑到LR解析,歧义语法触发移位是否会减少冲突?一个明确的语法也能触发一个吗?同样,如何减少冲突

[编辑:就是这样,含糊不清的语法会导致移位-减少和减少-减少冲突。相反,如果没有冲突,则语法是单音的。]

4) 解析左递归语法的能力是LR(k)解析器优于LL(k)解析器的一个优势,这是它们之间的唯一区别吗

[编辑:是。]

5) 给出G1:

G1 :
S -> S + S
S -> S - S
S -> a
5.1)G1是左递归、右递归和不明确的,对吗?这是LR(2)语法吗?有人会毫不含糊地说:

G2 :
S -> S + a
S -> S - a
S -> a
5.2)G2是否仍然模棱两可?G2的解析器需要两个lookahead吗?通过因子分解,我们有:

G3 :
S -> S V
V -> + a
V -> - a
S -> a
5.3)现在,G3的解析器是否只需要一个前瞻?进行这些转换的对应部分是什么?LR(1)是所需的最小解析器吗

5.4)G1是左递归的,为了使用LL解析器对其进行解析,需要将其转换为右递归语法:

G4 :
S -> a + S
S -> a - S
S -> a
然后

5.5)G4是否至少需要一个LL(2)解析器?G5只能被LL(1)解析器解析,G1-G5定义了相同的语言,而这种语言是(a(+/-a)^n)。这是真的吗

5.6)对于每个语法G1到G5,它所属的最小集合是什么

6) 最后,由于许多不同的语法可以定义同一种语言,那么如何选择语法和相关的解析器呢?生成的解析树是否重要?解析树的影响是什么

我问了很多问题,我并不期望得到一个完整的答案,不管怎样,任何帮助都将不胜感激

谢谢阅读

“许多语法可能定义相同的语言,人们如何选择……”

通常,您会选择满足以下条件的一个:

  • 概念上尽可能简单(含义:比其他人小)
  • 尽可能跟踪langauge参考手册中的术语
  • 最小弯曲量以满足解析器生成器的约束
最后一个问题可能会把概念上的简单性搞得一团糟,各种解析器样式的图表显示了您所面临的不同问题的数量,这取决于您对生成器的选择。更糟糕的是,在你真正选择语法之前,往往就已经做出了选择


最小化语法弯曲的一种方法是选择一个处理完全上下文无关语法的解析器生成器。有这个非常显著的优势。我已经使用它15年了,已经用它做了很多真正的语言。

thx。因此,使用GLR,它将能够解析任何CFG,语法尽可能简单,给出一个类似的简单解析树。然后出现一个问题:GLR=LR(*)吗?此外,通过使用GLR解析器,您将不需要使用语法来减少弯曲量,对吗?从技术上说是的。有一些CFG导致GLR具有指数行为,因此仍然需要弯曲一些。一般来说,这种行为非常罕见。在构建解析器时,您会发现有时您希望添加超出CFG功能范围的语义约束(考虑通过匹配行号将多个Fortran do循环头匹配到同一个CONTINUE语句),因此您仍然需要对语法进行一些修改。但最终,使用GLR时,语法的弯曲程度要小得多。是的,GLR具有“无限前瞻性”,它可以做LR(*)可以做的任何事情。LR(*)不处理歧义语法。许多真正的语言(包括C++,参见)都是模糊的,如果你只坚持语法。对于这样的语言,解析它和收集歧义,并在解析阶段完成时消除这些歧义通常更容易。否则,您将以类似经典的C/C++编译器攻击的方式结束,在这种攻击中,符号表(上下文相关)数据被送入lexer/解析器,造成了一个真正的混乱。@dader51:触发它的语法规则:“stmt=exp;”(对于xy,变量x乘以变量y)和“stmt=declaration;”(对于x作为类型,x作为指向x类型的指针,y作为声明为x*-类型的变量)。LR解析器问题:exp和声明的语法规则
G5 :
S -> a V
V -> - V
V -> + V
V -> a