1

我正在尝试为一种简单的语言创建解析器,但由于规则 expr: l_value 和 r_value: '@' l_value,我无法摆脱一些减少/减少冲突。我试图修复它来确定符号“@”的优先级,但它没有帮助。一个最小的、可重现的例子是:

%{
#include <cstdio>
#include "lexer.hpp"
%}
%define parse.error verbose  /*to help me debug the parser*
%token T_if "if"
%token T_then "then"
%token T_do "do"
%token T_begin "begin"
%token T_end "end"
%token T_and "and"
%token T_of "of"
%token T_array "array"
%token T_else "else"
%token T_integer "integer"
%token T_or "or"
%token T_true "true"
%token T_label "label"
%token T_procedure "procedure"
%token T_var "var"
%token T_boolean "boolean"
%token T_false "false"
%token T_mod "mod"
%token T_program "program"
%token T_while "while"
%token T_char "char"
%token T_forward "forward"
%token T_new "new"
%token T_real "real"
%token T_dispose "dispose"
%token T_function "function"
%token T_nil "nil"
%token T_result "result"
%token T_div "div"
%token T_goto "goto"
%token T_not "not"
%token T_return "return"
%token T_id 
%token T_realnum 
%token T_int 
%token T_character 
%token T_string 
%token T_assign       ":="
%token T_greaterequal ">="
%token T_lessequal    "<="
%token T_notequal     "<>"


%nonassoc '=' '<' '>' "<=" ">=" "<>" ":="
%left '+' '-' "or" 
%left '*' '/' "div" "mod" "and"
%left UMINUS
%right '^'
%left '@'
%left '[' '('

%expect 1

%%



expr:
l_value
|r_value
;

l_value:
T_id
|"result"
|T_string
|l_value '[' expr ']'
|expr '^'
|'(' l_value ')'
;

r_value:
T_int
|"true"
|"false"
|T_realnum
|T_character
|'(' r_value ')'
|"nil"
|call
| expr '<' expr 
| expr '>' expr
| expr "<=" expr
| expr ">=" expr
| expr '=' expr
| expr "<>" expr
| expr '+' expr
| expr '-' expr
| expr "or" expr
| expr '*' expr
| expr '/' expr
| expr "and" expr
| expr "div" expr
| expr "mod" expr
|"not" expr %prec UMINUS
|'+' expr   %prec UMINUS
|'-' expr   %prec UMINUS
|'@' l_value
;

call:
T_id '(' expr text6
;
text6: 
 ')' | ',' expr text6
;




%%
extern int lineno;
int main() {
#ifdef YYDEBUG
yydebug = 1;
#endif
int result = yyparse();
if (result == 0) printf("Success.\n");
return result;
}

`

在 parser.output 我得到这个:

1 expr: l_value .
6 l_value: l_value . '[' expr ']'
34 r_value: '@' l_value . 

'['  shift, and go to state 43


$end      reduce using rule 34 (r_value)
"and"     reduce using rule 1 (expr)
"and"     [reduce using rule 34 (r_value)]
"or"      reduce using rule 1 (expr)
"or"      [reduce using rule 34 (r_value)]
"mod"     reduce using rule 1 (expr)
"mod"     [reduce using rule 34 (r_value)]
"div"     reduce using rule 1 (expr)
"div"     [reduce using rule 34 (r_value)]
">="      reduce using rule 1 (expr)
">="      [reduce using rule 34 (r_value)]
"<="      reduce using rule 1 (expr)
"<="      [reduce using rule 34 (r_value)]
"<>"      reduce using rule 1 (expr)
"<>"      [reduce using rule 34 (r_value)]
'='       reduce using rule 1 (expr)
'='       [reduce using rule 34 (r_value)]
'<'       reduce using rule 1 (expr)
'<'       [reduce using rule 34 (r_value)]
'>'       reduce using rule 1 (expr)
'>'       [reduce using rule 34 (r_value)]
'+'       reduce using rule 1 (expr)
'+'       [reduce using rule 34 (r_value)]
'-'       reduce using rule 1 (expr)
'-'       [reduce using rule 34 (r_value)]
'*'       reduce using rule 1 (expr)
'*'       [reduce using rule 34 (r_value)]
'/'       reduce using rule 1 (expr)
'/'       [reduce using rule 34 (r_value)]
'^'       reduce using rule 1 (expr)
'^'       [reduce using rule 34 (r_value)]
']'       reduce using rule 34 (r_value)
')'       reduce using rule 34 (r_value)
','       reduce using rule 34 (r_value)
$default  reduce using rule 1 (expr)
4

0 回答 0