我怎样才能证明这个语法不含糊?

时间:2015-09-25 04:24:02

标签: regex compiler-construction grammar

我知道我需要证明没有字符串可以使用最左边的操作来导致两个不同的解析树。但是我怎么能这样做呢?我知道没有一种简单的方法可以做到这一点,但由于这个练习是在编译器Dragon的书上,所以我很确定有一种方式可以显示(不需要是一个正式的证据,只是为什么)。 Gramar是:

  

S-> SS * | SS + |一个

这个语法代表的是简单算术的另一种方式(我不记得名字,如果这个技术有人都知道,请告诉我):正常和算术的形式为a + a,这只是另一种求和方式和倍增。所以aa +也意味着a + a,aaa * +是a * a + a等等

2 个答案:

答案 0 :(得分:2)

证明CFG明确无误的最简单方法是构造一个明确的解析器。如果语法是LR(k)或LL(k)并且您知道 k 的值,那么这很简单。

这个特殊的语法是LR(0),因此解析器的构造几乎是微不足道的;你应该能够在一张纸上做到这一点(在你试着找到答案之前,这是值得做的。

直觉很简单:每个制作都以不同的终端符号结束,这些终结符号在语法中没有出现。因此,当您阅读符号时,您可以准确地知道要使用哪种生产来减少;只有一个可以申请,没有左手可以转入。

如果你将语法反转为产生波兰语(或Łukasiewicz)表示法,那么你将得到一个简单的LL语法。再次解析算法是显而易见的,因为每个右侧都以唯一的终端开始,因此只能做出一个预测:

S → * S S | + S S | a

所以这也是毫不含糊的。但是中缀语法含糊不清:

S → S * S | S + S | a

提供歧义的最简单方法是找到一个有两个解析的句子;在这种情况下,一个这样的句子是:

a + a + a

答案 1 :(得分:-1)

我认为示例字符串aa实际上显示了您的需求。它不能被解析为:

S => SS* => aaS => SS+ => aa