我正在尝试为相对简单的语法生成解析器,但我无法让我的优先级正常工作。
我已经设法减少了 15 个移位/减少错误,但我不知道如何解决剩下的几个错误——它们可能与我的优先级问题有关。
我有一个这样定义的语法:
%nonassoc T_LEN T_OPENPAREN T_CLOSEPAREN T_NUM T_ID T_QUOTE T_TRUE T_FALSE
%left T_GT T_GTE T_LT T_LTE T_EQ
%left T_OR
%left T_AND
%left T_NOT
Start : Expression { astRoot = new MainNode( $1 ); }
;
Expression : Expression T_OR Expression { $$ = new OrNode( $1, $3 ); }
| Expression T_AND Expression { $$ = new AndNode( $1, $3 ); }
| Expression Expression { $$ = new AndNode( $1, $2 ); }
| T_NOT Expression { $$ = new NotNode( $2 ); }
| T_GT Expression { $$ = new GreaterNode( $2 ); }
| T_GTE Expression { $$ = new GreaterEqualNode( $2 ); }
| T_LT Expression { $$ = new LessNode( $2 ); }
| T_LTE Expression { $$ = new LessEqualNode( $2 ); }
| T_EQ Expression { $$ = new EqualNode( $2 ); }
| T_LEN T_OPENPAREN T_NUM T_CLOSEPAREN { $$ = new LenNode( new IntegerNode( $3 ) ); }
| T_OPENPAREN Expression T_CLOSEPAREN { $$ = $2; }
| T_TRUE { $$ = new BoolTrueNode; }
| T_FALSE { $$ = new BoolFalseNode; }
| T_ID { $$ = new IdentifierNode( $1 ); }
| T_NUM { $$ = new IntegerNode( $1 ); }
| T_QUOTE { $$ = new QuoteNode( new IdentifierNode( $1 ) ); }
;
尝试解析以下内容时,我没有得到我想要的值:
100 T_AND 200 T_AND 300 T_AND 400 T_OR 1000
output => And( "100", And( "200", And( "300", Or( "400", "1000" ) ) ) );
expect => Or( And( "100", And( "200", And( "300", "400" ) ) ), "1000" );
最后,我的解析器输出的相关部分是:
State 27 conflicts: 15 shift/reduce
0 $accept: Start $end
1 Start: Expression
2 Expression: Expression T_OR Expression
3 | Expression T_AND Expression
4 | Expression Expression
5 | T_NOT Expression
6 | T_GT Expression
7 | T_GTE Expression
8 | T_LT Expression
9 | T_LTE Expression
10 | T_EQ Expression
11 | T_LEN T_OPENPAREN T_NUM T_CLOSEPAREN
12 | T_OPENPAREN Expression T_CLOSEPAREN
13 | T_TRUE
14 | T_FALSE
15 | T_ID
16 | T_NUM
17 | T_QUOTE
State 27
2 Expression: Expression . T_OR Expression
3 | Expression . T_AND Expression
4 | Expression . Expression
4 | Expression Expression .
T_LEN shift, and go to state 1
T_OPENPAREN shift, and go to state 2
T_NUM shift, and go to state 3
T_ID shift, and go to state 4
T_QUOTE shift, and go to state 5
T_TRUE shift, and go to state 6
T_FALSE shift, and go to state 7
T_GT shift, and go to state 8
T_GTE shift, and go to state 9
T_LT shift, and go to state 10
T_LTE shift, and go to state 11
T_EQ shift, and go to state 12
T_OR shift, and go to state 25
T_AND shift, and go to state 26
T_NOT shift, and go to state 13
T_LEN [reduce using rule 4 (Expression)]
T_OPENPAREN [reduce using rule 4 (Expression)]
T_NUM [reduce using rule 4 (Expression)]
T_ID [reduce using rule 4 (Expression)]
T_QUOTE [reduce using rule 4 (Expression)]
T_TRUE [reduce using rule 4 (Expression)]
T_FALSE [reduce using rule 4 (Expression)]
T_GT [reduce using rule 4 (Expression)]
T_GTE [reduce using rule 4 (Expression)]
T_LT [reduce using rule 4 (Expression)]
T_LTE [reduce using rule 4 (Expression)]
T_EQ [reduce using rule 4 (Expression)]
T_OR [reduce using rule 4 (Expression)]
T_AND [reduce using rule 4 (Expression)]
T_NOT [reduce using rule 4 (Expression)]
$default reduce using rule 4 (Expression)
Expression go to state 27
我能理解的最好的是,这个问题可能是由隐含的和(规则 3 和 4)引起的。如果这是问题的根源,我该如何解决?
谢谢!