所以我有这个语法(下面),我需要构建一个解析表。我需要使它适合预测解析器。我知道第一个想法是使它明确,但对我来说它已经是明确的(因为我找不到一个字符串,我可以绘制2个不同的解析树)。其次,我需要将其考虑在内。我把我的猜测放在原始语法之下,我觉得我错过了一些人可以指出我是否遗漏了什么。
S -> m G | m K p
G -> n G | n
K -> q K r | m n
我的猜测:
S -> m A
A -> G | K p
G -> n G'
G' -> n G' | emptyString
K -> q K r | m n
答案 0 :(得分:0)
您所拥有的看起来正确!这是逐步了解如何到达那里的方法,以及每次转换的必要性。
首先,让我们看一下我们的S非终结符。这个非终结符有两个以m
开头的产品,这意味着我们在这些产品之间存在FIRST / FIRST冲突。左乘积S→mG和S→mKp给我们
S→mA
A→G
A→Kp
现在,这样做是否暴露了以前不存在的任何问题?幸运的是,没有。非终结符G只能产生以n
开头的字符串,非终结符K只能产生以q
或m
开头的字符串。这意味着我们在这里没有引入任何FIRST / FIRST冲突,因此不需要进一步讨论-至少现在还没有。
接下来,让我们看一下G非末端,它的乘积为G→nG和G→n。换句话说,这将产生一串包含一个或多个字母n
的字符串。就目前而言,这是FIRST / FIRST冲突。我们可以用多种方法来重写它。您提出的方案实际上是将其分为两部分-一件生成一个n
,另一个则生成零个或多个n
副本。在此,我将按照您的指导进行操作,它引入了一个新的非终结符,我将其称为H以将其与G区别开来:
G→nH
H→nH | ε
现在,我们不得不问-这个ε产生了FIRST / FOLLOW冲突吗?为了回答这个问题,我们将需要确定FOLLOW(H)是什么。我们看到H仅出现在产品H→nH(没有给我们任何新内容)和G→nH的末尾,这告诉我们FOLLOW(G)中的所有内容也将出现在FOLLOW(H)中。 FOLLOW(G)中有什么? G出现在生产A→G的末尾,这告诉我们FOLLOW(A)中的所有内容都将在FOLLOW(H)中。并且A仅出现在S→mA中,这意味着FOLLOW(A)中唯一的标记是输入结束标记$。 !因此FOLLOW(H)= {$}。这是个好消息,因为这与H→nH的产生没有冲突。
这留下了K的生产规则,幸运的是,它们没有任何问题。
将所有内容放在一起,我们得出的净转换语法是
S&rarr mA
A→G | Kp
G→nH
H→nH | ε
K→qKr | mn
这恰好是LL(1)。这是解析表:
m n q r $
+------+------+------+------+------+
S | mA | | | | |
+------+------+------+------+------+
A | Kp G Kp | | |
+------+------+------+------+------+
G | | nH | | | |
+------+------+------+------+------+
H | | nH | | | eps |
+------+------+------+------+------+
K | mn | | qKr | | |
+------+------+------+------+------+
看妈!没有冲突!