我知道这部分语法错误但我不知道如何修复它我甚至使用%左右但它没有帮助。任何人都可以帮我找出这个语法有什么问题。 在此先感谢您的帮助。
%token VARIABLE NUM
%right '='
%left '+' '-'
%left '*' '/'
%left '^'
%start S_PROOP
EQUATION_SEQUENCE
: FORMULA '=' EQUATION
;
EQUATION
: FORMULA
| FORMULA '=' EQUATION
;
FORMULA
: SUM EXPRESSION
| PRODUCT EXPRESSION
| EXPRESSION '+' EXPRESSION
| EXPRESSION '*' EXPRESSION
| EXPRESSION '/' EXPRESSION
| EXPRESSION '^' EXPRESSION
| EXPRESSION '-' EXPRESSION
| EXPRESSION
;
EXPRESSION
: EXPRESSION EXPRESSION
| '(' EXPRESSION ')'
| NUM
| VARIABLE
;
答案 0 :(得分:0)
正常的风格是对于非终端使用小写,对终端使用大写;不加选择地使用大写字母会使你的语法难以阅读(至少对于我们这些习惯于常规yacc / bison风格的人来说)。所以我没有那么多地使用大写锁定键来写这个答案。
基本问题是制作
expression: expression expression
这显然是模棱两可的,因为它没有提供任何关联性的指示。在那,它与
没有什么不同expression: expression '+' expression
但可以使用优先声明来解决冲突:
%left '+'
不同之处在于第一个产品没有任何终端符号,这使得无法使用优先规则来消除歧义:在yacc / bison中,优先级始终是潜在减少和潜在变化之间的比较。潜在的减少是一些可以减少的产量;潜在的转变是终极符号,可能能够扩展一些生产。由于潜在的移位必须是终端符号,因此优先级声明中使用的是;默认情况下,潜在减少的优先级由右侧的最后一个终端符号定义,但可以使用%prec
标记指定不同的终端。在任何情况下,优先关系都涉及终端符号,如果语法允许并置两个终端,则没有相关的终端符号。
这很容易解决,因为您没有义务使用优先权来解决冲突。你可以避免冲突:
/* Left associative rule */
expr_sequence: expr | expr_sequence expr
/* Alternative: right associative rule */
expr_sequence: expr | expr expr_sequence
由于没有任何迹象表明您希望通过并置,我无法推荐上述其中一种或另一种,但通常我会倾向于第一种。
这与equation_sequence
的语法没有太大的不同,尽管equation_sequence
实际上使用了终端符号,因此可以使用优先声明进行处理。值得注意的是equation_sequence
,正如所写的,是正确联想的。对于赋值运算符而言,这通常被认为是正确的,(a = b = c + 3
,在像C这样的语言中,被解析为a = (b = c + 3)
而不是(a = b) = c + 3
,这使得任务成为少数几个权利之一 - 关联运算符。)但是如果你使用=
作为相等运算符,它可能实际上并不是你想要的。