我正在嘗試構建一個小型的野牛語法,但是在定義的一部分時遇到問題。函數可以用右邊的任何合法表達式(語法中的expression_list)作爲參數來調用。當規則覆蓋另一個子集時,消除語法歧義
問題的出現是因爲左側,功能可以通過分配給他們(標識符後跟標識符列表 - assignment_expression和identifier_list在語法)定義
我的問題是如何能夠消除因爲左側的合法聲明是右側合法聲明的子集,所以我的語法中含糊不清。
語法被寫入野牛(訴2.4.1)
從命令的輸出是:
2 shift/reduce, 2 reduce/reduce
warning: rule useless in parser due to conflicts: assignment_expression: IDENTIFIER LPAREN RPAREN
下面是完整的語法:
expression:
assignment_expression
| expression DECORATOR IDENTIFIER
value:
IDENTIFIER
| HEX
| BIN
| OCT
| SCI
| FLOAT
| INT
;
constant_expression:
value
| LPAREN constant_expression RPAREN
| constant_expression OR constant_expression
| constant_expression XOR constant_expression
| constant_expression AND constant_expression
| constant_expression LSHIFT constant_expression
| constant_expression RSHIFT constant_expression
| constant_expression PLUS constant_expression
| constant_expression MINUS constant_expression
| constant_expression MUL constant_expression
| constant_expression DIV constant_expression
| constant_expression MOD constant_expression
| constant_expression POW constant_expression
| constant_expression FACTORIAL
| NOT constant_expression
| IDENTIFIER LPAREN RPAREN
| IDENTIFIER LPAREN constant_expression RPAREN
| IDENTIFIER LPAREN expression_list RPAREN
;
expression_list:
constant_expression COMMA constant_expression
| expression_list COMMA constant_expression
;
assignment_expression:
constant_expression
| IDENTIFIER EQUAL assignment_expression
| IDENTIFIER LPAREN RPAREN
| IDENTIFIER LPAREN IDENTIFIER RPAREN
| IDENTIFIER LPAREN identifier_list RPAREN
;
identifier_list:
IDENTIFIER COMMA IDENTIFIER
| identifier_list COMMA IDENTIFIER
;
以下是野牛輸出詳細模式(-v)的相關部分:
State 34 conflicts: 2 shift/reduce
State 35 conflicts: 2 reduce/reduce
state 34
3 value: IDENTIFIER .
25 constant_expression: IDENTIFIER . LPAREN RPAREN
26 | IDENTIFIER . LPAREN constant_expression RPAREN
27 | IDENTIFIER . LPAREN expression_list RPAREN
33 assignment_expression: IDENTIFIER LPAREN IDENTIFIER . RPAREN
35 identifier_list: IDENTIFIER . COMMA IDENTIFIER
COMMA shift, and go to state 53
LPAREN shift, and go to state 39
RPAREN shift, and go to state 54
COMMA [reduce using rule 3 (value)]
RPAREN [reduce using rule 3 (value)]
$default reduce using rule 3 (value)
state 35
25 constant_expression: IDENTIFIER LPAREN RPAREN .
32 assignment_expression: IDENTIFIER LPAREN RPAREN .
$end reduce using rule 25 (constant_expression)
$end [reduce using rule 32 (assignment_expression)]
DECORATOR reduce using rule 25 (constant_expression)
DECORATOR [reduce using rule 32 (assignment_expression)]
$default reduce using rule 25 (constant_expression)
根據要求在這裏是一個很小的語法有問題:
assignment_expression:
constant_expression
| IDENTIFIER LPAREN identifier_list RPAREN
;
value:
IDENTIFIER
| INT
;
constant_expression:
value
| IDENTIFIER LPAREN expression_list RPAREN
;
expression_list:
constant_expression COMMA constant_expression
| expression_list COMMA constant_expression
;
identifier_list:
IDENTIFIER COMMA IDENTIFIER
| identifier_list COMMA IDENTIFIER
;
這並不困難。你只需要一個派生子集和另一個超集的非終端。然後相應地使用它們。 – Gene
由於它們可以包含相同的東西,因此無法區分paren對的兩種用法。 – stark
@gene恐怕我不完全明白... – rscarson