【问题标题】:Ambiguity resolution when making a C++ parser制作 C++ 解析器时的歧义解析
【发布时间】:2016-02-24 09:36:56
【问题描述】:

我为 C++17 编写了一个 LALR(1) 解析器。我发现了156个歧义,其中一些我可以按照标准解决,但其他我不能。

例如: 当遇到 小于 时,在解析“operator+ ”时会发生 Shift-Reduce 冲突:

我们可以将其解析为:

(1)

template-id -> operator-function-id ·

或:

(2)

unqualified-id -> operator-function-id · 其中 (1) 需要转移,但 (2) 需要减少。

但是,标准有:

在名称查找 (3.4) 后发现名称是模板名称,或者 operator-function-id 或literaloperator-id 引用一组重载函数,其中任何成员都是函数模板,如果后面跟着一个 137 被视为结束分隔符,而不是大于运算符。

所以我们选择换班。

不幸的是,有很多模棱两可的地方我找不到解决办法。在这里我列出了其中的一些(其中一些可以清楚地做出选择,但我就是找不到证据):

  1. 标准中是否有某些部分表明当出现歧义时“移位”是默认选择?

声明符

(1)当一个noptr-declarator被解析,遇到一个left-paren时,我应该按照:

ptr-declarator -> noptr-declarator ·

或移动左括号以满足:

declarator -> noptr-declarator · 参数和限定符

parameters-and-qualifiers -> · left-paren parameter-declaration-clause right-paren......

(2)当解析一个declarator-id遇到左括号时,我应该按照:

noptr-declarator -> declarator-id · noptr-declarator -> noptr-declarator · \left-bracket ?constant-expression \right-bracket ?attribute-specifier-seq

或左移满足:

noptr-declarator -> declarator-id ·attribute-specifier-seq

(attribute-specifier-seq is [[.......]])

【问题讨论】:

  • 我上次查看是在 1990 年代,C++ 语法有 53 个移位归约冲突,如果我没记错的话,还有一些归约冲突。
  • C++ 标准没有任何地方说该语法是 LARL(1) 语法。它也没有描述你打算如何实现解析器。
  • 众所周知,语法不能用la LALR解析,那么您期望或想要什么?

标签: c++ parsing lalr


【解决方案1】:

跟进 TonyD 的评论:见 Why can't C++ be parsed with a LR(1) parser?

在某些地方,您本质上必须保留解析产生的歧义,并通过名称解析来解决它,等效地,您必须将名称解析纠结到解析过程中。无论哪种情况,您都必须解释标准以确定应如何解决歧义,是的,这是一项非常困难的任务。

然后你会发现编译器真正做了什么; GCC 和 MS 在语法和语义解释方面都有许多标准的扩展和变体(这些产生的程序在不同的编译器下会产生不同的结果)。最后,您可以在系统头文件中找到可憎的内容;这些是编译器人员为了方便他们的生活而添加的技巧,并且记录非常糟糕,如果有的话。

【讨论】:

    【解决方案2】:

    C++ 是Turing Complete to parse

    非常相关的帖子here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多