Bison-语法中的非终结符

Bison-语法中的非终结符,bison,Bison,我试图用Bison创建一个简单的语法,但是我得到一个警告,非终结符是无用的加法表达式 我的代码如下所示: %% multiplicative_expr: CONSTANT_INTEGER | multiplicative_expr MULTIPLICATION CONSTANT_INTEGER ; additive_expr: multiplicative_expr | additive_expr ADDITION multiplicative_expr 我见过很多类似的问题,我认为这是因为

我试图用Bison创建一个简单的语法,但是我得到一个警告,非终结符是无用的加法表达式

我的代码如下所示:

%%
multiplicative_expr:
CONSTANT_INTEGER
| multiplicative_expr MULTIPLICATION CONSTANT_INTEGER 
;
additive_expr:
multiplicative_expr
| additive_expr ADDITION multiplicative_expr

我见过很多类似的问题,我认为这是因为它没有在其他表达中使用,但是我创造了一个新的表达,包括这个,警告继续。

野牛的语法是由符号和规则组成的,它们以一种可以理解的方式连接在一起,即符号是这些符号的合成形式。同样地,在相反的意义上,你会说这些符号是这个符号的扩展形式

一个符号可以合成一些基本的东西,如不可分割的单位,称为“终端符号”,或者像其他符号一样复杂,而这些符号又是更多事物的合成,在这种情况下,后者和前者被称为“非终端符号”

所有这些关于合成和扩展的东西都可以被认为是通过不同的形式来表现同一事物的一种方式。每一次形式根据语法规则发生变化,就被称为重写,就像用不同的方式表达同一事物一样

根据这里的常识以及关于解析器、野牛等的文本所说,随机重写符号没有多大意义。一系列重写应该朝着既定的目标前进,成功或失败都可以,但始终能够检测到任何一种情况并停止,结果就在眼前。Bison的方法是,用户程序员突出显示一组语法符号中的一个,并将其视为完全忽略任何有效的符号字符串以及找不到重写方法的无效字符串。这称为开始符号

除此之外,在典型语法的布局中,并非所有符号都在规则的左右两侧显式地参与start simbol。从其余符号到起始符号的连接构造为,任何符号通过参与同一规则与另一符号连接,并且该构造在其中一个符号与起始符号连接的情况下进行一次或多次

按照上述步骤,没有与开始符号连接的语法符号是无用的。因为重写是由到达起始符号的追求驱动的,而断开连接的符号永远不会满足它,所以它永远不会被使用。当然,在解析器生成阶段,会发布关于无用符号的警告,因为这里的问题不在于符号字符串实例,而在于语法符号类型

对于终端符号,控制不强制执行,因为Bison允许终端在此处环绕以用于其他目的,例如,建立优先级,而不必用于说明符号组是如何生成的,而使用非终端,则始终无效,并且当选项或指令未以其他方式设置时,会发出警告

该报告没有错误严重性,因为它被接受,无论出于何种原因,您都可以希望它出现在那里,尽管Bison会忽略它。尽管如此,这个警告还是值得注意的,因为它可能意味着一个键入错误,导致语法没有反映,解析器也没有按照您的要求进行操作

在进行解决方案之前,请考虑以下几点:

您的语法定义了加法运算和乘法运算的分组,这听起来像数学运算+和*

你的语法很好地遵循了Bison关于递归性的建议,也就是说,当有证据表明esense与乘法乘常数乘整数或常数乘整数乘乘法乘整数相同时,你的语法很方便地就是前面的构造。野牛手册,§3.3.3递归规则

你的语法正确地避免了Bison的reduce/reduce和shift/reduce冲突,同时它也符合了*over+更高优先级的数学意义

考虑到上述情况属实,我将针对无用符号的具体问题提出一些技巧

野牛不需要任何特定的规则。除了第一条规则有权选择起始符号外,Bison不介意规则中提到的符号没有定义,但在语法中是后者。如果交换规则,使加法_exp首先出现,它将成为开始符号,并且由于它会扩展到另一个而不是相反的符号,因此警告将消失。或者在语法顶部的%%之前放置一个%start additive_exp,效果完全相同

另一种方法是考虑到你的语法有一个规则加法“exp:乘法”exp。在参考书目中,这种形式的规则通常被称为单结果,并引用它: “单一产品出现的常见情况是 语法用于描述运算符的优先级和关联性”。 [...] “事实证明,运算符优先级或结合性表示中出现的单个结果总是可以消除的” “LR解析”、“A.V.Aho”和“S.C.约翰逊”。 参考书目中所说的完全符合你的情况,因为你的语法与使用裸exp而不是加法和乘法exp的语法相比,没有更多的功能,这将给你留下一个开始符号,它是唯一的非终结符,设置了非终结符无用的可能性,更重要的是,保留语法的意思

Bison通过其指令%prec、%left和%right,特别是它们在指令部分中出现的顺序,帮助您进行简化。非正式地说,它是关于运算符优先级的,但更准确地说,实际上被改变的是Bison的解析器决定立即分组或延迟后者,因为遇到了一个符号,这两种可能性都被取代了。Bison的手册中有关于它们的详细信息,Yacc的手册也通常捆绑在Bison发行版中,因为两者非常相关,甚至可能更详细地说明语法规则的优先级。野牛手册,§3.7.3操作员优先权和Yacc手册,§6:优先权

在可能的情况下使用指令作为优先级,可以避免Bison在构建解析器时通常会进行的一些优化,从而帮助Bison节省一些时间。 同样,基于同一来源“LR解析”、“A.V.Aho”和“S.C.约翰逊”:
“不明确语法立即生成简化语法分析器,而不需要此优化算法”。

您确定最后一行之前的乘法表达式后面应该有冒号吗?我的猜测是,bison看到加法运算,后跟乘法运算,并假设加法运算为空。不过,我不熟悉bison的语法。当然,在创建问题时,这是一个错误的拼写错误。已编辑。您将在示例中收到警告,因为无法从开始符号乘法表达式访问符号加法表达式。你有没有一个例子,你认为它不应该给出警告?我认为常量整数加法常量整数应该在乘法表达式加法乘法表达式中变为常量整数,然后在加法表达式加法乘法表达式中变为常量整数,最后在加法表达式中变为常量整数。也许我没有正确理解野牛。你可以用你想要的方式来定义你的语言。选择自由带来责任。但所示片段的问题在于克里斯·多德的诊断。该语法中的起始符号是乘法的_expr,而该规则从不使用规则加法的_expr,因此在语法片段中这是无用的。您需要一个顶级规则表达式:乘法表达式、加法表达式……或其他什么。或者可能是一个扩展的乘法表达式:加法表达式,乘法表达式,乘法表达式,加法表达式,或者沿着这些一般的线。