我想做这样的事情:
// match used as a statement, semicolon is optional
match (1) {}
// match used as an expression, semicolon is required
1 + match (2) {};
statement
: expression_without_block T_SEMICOLON
| expression_with_block
;
expression
: expression_without_block
| expression_with_block
;
expression_without_block
: scalar
| expression_without_block T_PLUS expression
| T_PLUS expression
;
expression_with_block
: T_MATCH T_LEFT expression T_RIGHT T_CURLY_LEFT T_CURLY_RIGHT
;
想法是expression_with_block
不能在语句的开头使用,这使得以下内容很明确:
match (1) {}
+2;
// Can't mean
(match (1) {} + 2);
// because of the line "expression_without_block T_PLUS expression"
语法会引起移位/减少冲突,但我不知道为什么。输出显示以下内容(但我不确定该怎么做):
State 11 conflicts: 1 shift/reduce
...
State 11
5 expression: expression_without_block .
8 expression_without_block: expression_without_block . T_PLUS expression
T_PLUS shift, and go to state 14
T_PLUS [reduce using rule 5 (expression)]
$default reduce using rule 5 (expression)
The full output file can be found here。
我什至也不确定这是正确的方法,因为那样的话就行不通了:
// `match` can't be at the lhs of an expression, even in sub-expressions
func_call(match (10) {} + 20);
有没有一种方法可以实现我在野牛中所描述的内容?我不是野牛专家,所以我非常感谢您的帮助。谢谢!
这是左递归规则所发生的一种非常经典的冲突,但是由于平移/减少冲突的默认解决方案是进行平移,所以这里一切都会好起来的。
这里是您应该如何阅读野牛踪迹的方法:
T_PLUS shift, and go to state 14 -- when next token is T_PLUS shift action is selected
T_PLUS [reduce using rule 5 (expression)] -- the action between [] was disabled by Bison default conflict resolution
要覆盖Bison的默认冲突解决方案(在此无需这样做),我们可以使用运算符优先级(请参阅https://www.gnu.org/software/bison/manual/bison.html#Precedence-Decl)或使用非运算符优先级(请参阅https://www.gnu.org/software/bison/manual/bison.html#Non-Operators)