1

I'm trying to create a parser for a simple language, but I can't get rid of some reduce/reduce conflicts because of the rules expr: l_value and r_value: '@' l_value. I tried to fix it determining a precedence for the symbol '@' but it didn't help. A minimal, reproducible example is that:

%{
#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;
}

`

In parser.output I get this:

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)
Kat
  • 11
  • 2
  • Why do you allow `expr` to derive `%empty`? That's not the issue here, but it's a bit weird and might lead to other problems. – rici Jul 06 '20 at 21:25
  • 2
    Anyway, you are not revealing all of your grammar, which makes it harder to help you. What precedence declaration did you attempt? What is the definition of `l_value`? We ask for an [mre] here; that's not "a small extract from your program". It's a complete but reduced program which exhibits the same problem. If you're not showing everything, it's not *reproducible*; if you're showing hundreds of lines of code, it's not *minimal*. Making a [mre] is more work, but then it's also a way for you to figure out the problem yourself. – rici Jul 06 '20 at 21:27

0 Answers0