留下一个语法因素

时间:2015-10-25 17:09:41

标签: parsing context-free-grammar ll ambiguous-grammar

所以我有这个语法(下面),我需要构建一个解析表。我需要使它适合预测解析器。我知道第一个想法是使它明确,但对我来说它已经是明确的(因为我找不到一个字符串,我可以绘制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

1 个答案:

答案 0 :(得分:0)

您所拥有的看起来正确!这是逐步了解如何到达那里的方法,以及每次转换的必要性。

首先,让我们看一下我们的S非终结符。这个非终结符有两个以m开头的产品,这意味着我们在这些产品之间存在FIRST / FIRST冲突。左乘积S→mG和S→mKp给我们

  

S→mA

     

A→G

     

A→Kp

现在,这样做是否暴露了以前不存在的任何问题?幸运的是,没有。非终结符G只能产生以n开头的字符串,非终结符K只能产生以qm开头的字符串。这意味着我们在这里没有引入任何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  |      |      |
  +------+------+------+------+------+

看妈!没有冲突!