繁体   English   中英

如何消除以下语法中的歧义?

[英]How to Remove the ambiguity from the following grammar?

消除以下语法中的歧义

S −−> 如果 E 则 S | 如果 E 则 S 否则 S | 其他

可以消除悬空-其他歧义。 《编译器:原理、技术和工具》第 2 版,第 211-212 页中有这样的语法。 不过书里语法,只是没有解释(或者我没找到)。

在 ABNF 元语法中,语法是:

statement = matched / open
matched   = "if" expr "then" matched "else" matched 
          / other
open      = "if" expr "then" statement
          / "if" expr "then" matched "else" open

expr      = ...
other     = ...

它是如何工作的?

这里的想法是通过使用非确定性来避免歧义(无论如何已经提出,因为每个歧义语法也是非确定性的;最后我写了关于差异,我发现(太)经常被误解) . 这意味着在成功解析之后,任何输入都只有一个语法树(意味着您要求的非歧义)。 但是您将需要一个解析器,它可以使用比确定性 LL(1) 解析器复杂的机制。

规则matched确保子树中每个直接嵌套的 if 语句都有else 换句话说, then将有一个匹配的else

规则open确保每个子if语句没有else本身,或者如果确实如此,那么其别的语句是open反过来。 与其他词,排除open保证会减少else使用的关键字then关键字使用。 而与其他词,数量else子树内将小于的数量then (或者if ■如果你喜欢)。 这与确保两者数量相等matched规则形成对比。 这意味着在解析器中实现的matchedopen永远不会接受相同的输入,从第一次使用规则statement

此外,由于matched "else" open在规则openelse将“附加”到最近的if 这在解析器识别第一个使用的statement之前解决了悬空-其他歧义。

例子

为了说明将要发生的步骤,我升级了语法以允许更多“自然”输入。 这意味着更多的标点符号和空格。 首先是词法分析器:

keyword = %s"if" / %s"then" / %s"else"

它尽可能将输入字符分组,而未分组的字符则自行成为标记。 对于输入:

if(x)then if(x)then y else y

你有这些字节: 输入字节

对于这些字节,您将拥有以下令牌: 令牌

然后你有解析器语法,允许解析器接受这些标记(区分大小写)并显式放置空格。 还是可以看原版的,整体流程是一样的。 解析器语法:

statement = matched / open
matched   = {keyword, %s"if"} *ws "(" *ws expr *ws ")" *ws {keyword, %s"then"} 1*ws matched {keyword, %s"else"} 1*ws matched 
          / other *ws
open      = {keyword, %s"if"} *ws "(" *ws expr *ws ")" *ws {keyword, %s"then"} 1*ws statement
          / {keyword, %s"if"} *ws "(" *ws expr *ws ")" *ws {keyword, %s"then"} 1*ws matched {keyword, %s"else"} 1*ws open

expr      = %s"x"
other     = %s"y" 
ws        = %s" "

开始解析后,深入探究语法规则的解析机,会这样执行:

  • 它将进入开始规则statement
  • 然后进入具有对规则matched的引用的第一个串联。
  • 它将接受具有if(x)then字符的第一个标记
  • 然后它将再次使用matched规则
  • 它将接受所有其他标记,直到输入结束if(x)then y else y
  • then 将移出matched规则并期望其匹配else ,但没有这样的,因为输入已经结束 这意味着解析器必须返回以寻找另一种方式。 此时,您将拥有这个(部分构建的)语法树: 中间树
  • 它将返回到解析的最开始,并尝试在规则statement进行第二个连接,即一个引用规则open
  • 它将按照它的步骤工作,并最终使用这棵树成功地到达输入的末尾: 最终语法树
  • 那么解析机可能会继续探索更多,但不会找到任何其他语法树。

相关理论

决定论、非决定论、歧义和非歧义常常被误解。 我想每个人都举一个例子,因为我认为写的对每个人来说都不是很清楚。

从解析器的角度来看,确定性与给定状态下可能的操作数量有关。 当对于解析器中的所有可能状态至多一个动作是可能的时,解析器是确定性的。 我在很多地方都看到过这样的说法:“语法主要是确定性的,只有少数地方是非确定性的”。 这是误导,因为文法的确定性是基于整个文法——更准确地说是最坏的确定性情况。 例如,下一个语法是确定性的,当被解析器使用时,解析器也将是确定性的:

rule = "a" / "b"

非确定性意味着有解析器,其中一个以上动作是可能的,对于至少一个输入序列中的至少一个可能的状态。 例如,以下语法是不确定的:

rule = "a" / "a" 

显然,您可以将其重写为仅rule = "a"但这不是相同的语法。 两种语法都生成相同的语言。 语法正在生成一种语言的有效字符串。 这种语言包括其有效的字符串。 解析器正在接受有效的语言字符串并拒绝无效的语言字符串。

歧义是指输入可以在一个以上方式来识别。 这反过来意味着对于至少一个有效输入可能不止一种语法树。 例如,前面的语法( rule = "a" / "a" )是不明确的,因为两个连接都有a .

非歧义意味着任何有效输入都将以完全一种方式被识别。 这又意味着,只有一个语法树存在于每个有效的输入。 显然,对于无效输入,没有语法树。

您可能有一个非确定性非歧义的语法,如下所示:

rule = "a" "b" / "a" "c"

您在输入字符a的规则开头有一个不确定的选择,但在下一个输入字符中,哪个连接是正确的将变得清晰。 这是不可能的,在输入被完全处理,有一个以上语法树:这意味着语法是不明确的。

显然,每一个对应确定的语法也无歧义的,因为没有状态,其中第二个动作是可能的,可能会导致第二个树。

此外,每一个暧昧的语法不确定性,因为能够有一个以上的语法树,某处的状态,即有超过一个动作可能的,至少一个输入序列。

在这本书的语法的“绝招”是,非决定论是到存在(它实际上是“就业”),但它不会让到外面传播statement规则,有效防止语法变得暧昧。

现在,当解析器一次处理一个字符时,所有这些都是有效的。 但我不会离这里很远。 也有不同类型的歧义。 有些你可以数,有些你不能 但我也不会去那里。

免责声明:我使用了截图和我开发的工具的语法语法:Tunnel Grammar Studio。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM