[移位/减少带有可选分号的语法冲突

问题描述 投票:2回答:1

Sample repository

我想做这样的事情:

// 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);

有没有一种方法可以实现我在野牛中所描述的内容?我不是野牛专家,所以我非常感谢您的帮助。谢谢!

bison yacc
1个回答
2
投票

这是左递归规则所发生的一种非常经典的冲突,但是由于平移/减少冲突的默认解决方案是进行平移,所以这里一切都会好起来的。

这里是您应该如何阅读野牛踪迹的方法:

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

© www.soinside.com 2019 - 2024. All rights reserved.