我正在尝试创建一个编译器,我现在正在尝试创建解析器。 我收到有关这种状态的警告: 国家89
62 expr: '(' expr . ')'
66 | expr . '+' expr
67 | expr . '-' expr
68 | expr . '*' expr
69 | expr . '/' expr
70 | expr . '%' expr
74 | expr . '&' expr
75 | expr . '|' expr
77 cond: expr .
78 | '(' expr . ')'
82 | expr . '=' expr
83 | expr . "<>" expr
84 | expr . '<' expr
85 | expr . '>' expr
86 | expr . ">=" expr
87 | expr . "<=" expr
"<>" shift, and go to state 91
">=" shift, and go to state 92
"<=" shift, and go to state 93
'+' shift, and go to state 94
'-' shift, and go to state 95
'|' shift, and go to state 96
'*' shift, and go to state 97
'/' shift, and go to state 98
'%' shift, and go to state 99
'&' shift, and go to state 100
'=' shift, and go to state 101
'<' shift, and go to state 102
'>' shift, and go to state 103
')' shift, and go to state 119
$default reduce using rule 77 (cond)
State 119
62 expr: '(' expr ')' .
78 cond: '(' expr ')' .
"and" reduce using rule 62 (expr)
"and" [reduce using rule 78 (cond)]
"or" reduce using rule 62 (expr)
"or" [reduce using rule 78 (cond)]
':' reduce using rule 62 (expr)
':' [reduce using rule 78 (cond)]
')' reduce using rule 62 (expr)
')' [reduce using rule 78 (cond)]
$default reduce using rule 62 (expr)
这部分的语法是:
expr:
T_const |
T_char_const |
l_value |
'(' expr ')' |
func_call |
'+' expr |
'-' expr |
expr '+' expr |
expr '-' expr |
expr '*' expr |
expr '/' expr |
expr '%' expr |
T_true | T_false |
'!' expr |
expr '&' expr |
expr '|' expr
;
cond:
'(' cond ')' |
expr |
T_not cond |
cond T_and cond |
cond T_or cond |
expr '=' expr |
expr T_not_equal expr |
expr '<' expr |
expr '>' expr |
expr T_greater_equal expr |
expr T_less_equal expr
;
这里有什么问题,我怎么可能解决它?我已经解决了一些转移/减少问题,但通常我不明白这个问题是什么。 非常感谢你
答案 0 :(得分:1)
你的问题所引用的语法有:
cond: '(' cond ')'
但是输出文件中引用的那个有生产:
cond: '(' expr ')'
还有一些其他差异表明输出文件不是从引用的语法生成的。这使得回答你的问题的任务变得复杂,尽管从根本上说问题在两种情况下都是相同的。我正在使用输出文件作为答案的其余部分的参考。
既然你也有:
cond: expr
在cond
派生带括号的字符串的任何上下文中都存在歧义。 (状态119显示的冲突非常清楚。)例如,假设解析器遇到
not ( x )
x
只能缩减为expr
(通过l_value
),但有两种可能性:
not ( expr ) => not expr [ from expr: ( expr ) ]
=> not cond [ from cond: expr ]
not ( expr ) => not cond [ from cond: ( eχpr ) ]
这种歧义存在于允许cond
的所有上下文中。
将表达式语法分成布尔表达式和非布尔表达式是很棘手的,而且大部分都是不必要的。您最终允许任何表达式用作布尔值(cond: expr
),并且您很可能允许(或您的用户希望您允许)将布尔值分配给变量。所以最简单和最常见的解决方案就是只说一个值是一个值,一个表达式是一个表达式,没有特殊的套管布尔值。
如果你真的觉得需要在语法上区分这两者,你会在this recent question中找到一个例子。