Hey Guys this is driving me crazy I'll list the error and the relevant code below. Thanks in advance for any help.
ERROR:
51: shift/reduce conflict (shift 69, reduce 28) on '{'
state 51
funcao : publico tIDENTIFIER '(' seq_vars ')' eqliteral . corpo (13)
corpo : . (28)
'{' shift 69
$end reduce 28
tVOID reduce 28
tPUBLIC reduce 28
tCONST reduce 28
tIF reduce 28
tDO reduce 28
tFOR reduce 28
tCONTINUE reduce 28
tBREAK reduce 28
tRETURN reduce 28
tINTEGER reduce 28
tNUMBER reduce 28
tSTRING reduce 28
corpo goto 70
bloco goto 71
And this is the relevant code
// Função
funcao: publico tIDENTIFIER '(' seq_vars ')' eqliteral corpo {};
// Corpo do bloco
corpo: bloco |;
// Bloco
bloco: '{' seq_decls seq_inst '}' {/*figure this out later*/};
I'll keep trying to solve it and post the answer if I do.
Since we can't possible replicate the circumstances, I'm only guessing...
It looks like Yacc doesn't know what to do when it reaches the position after the eqliteral nonterminal. You can see that's where the parser generator is because of the . in rule in the error message.
When Yacc reaches this position, and there is no '{' terminal, should it shift using the bloco rule (you see the . in that rule too) or should it reduce when seeing something else?
One possible solution (that I'm unable to verify) is to change the funcao rule:
funcao: publico tIDENTIFIER '(' seq_vars ')' eqliteral
| publico tIDENTIFIER '(' seq_vars ')' eqliteral '{' seq_decls seq_inst '}'
;
It may work, it may not.
Related
i've been trying to fix a shift/reduce conflict in my yacc specification and i can't seem to find where it is.
%union{
char* valueBase;
char* correspondencia;
}
%token pal palT palC
%type <valueBase> pal
%type <correspondencia> palT palC Smth
%%
Dicionario : Traducao
| Dicionario Traducao
;
Traducao : Palavra Correspondencia
;
Palavra : Base Delim
| Exp
;
Delim :
| ':'
;
Correspondencia :
| palC {printf("PT Tradução: %s\n",$1);}
;
Exp : Smth '-' Smth {aux = yylval.valueBase; printf("PT Tradução: %s %s %s\n", $1, aux, $3);}
;
Smth : palT {$$ = strdup($1);}
| {$$ = "";}
;
Base : pal {printf("EN Palavra base: %s\n",$1);}
;
Any help to find and fix this conflict would be extremely appreciated.
So looking at the y.output file from your grammar, you have a shift/reduce conflict in state 13:
State 13
10 Exp: Smth '-' . Smth
palT shift, and go to state 2
palT [reduce using rule 12 (Smth)]
$default reduce using rule 12 (Smth)
Smth go to state 16
Basically, what this is saying is that when parsing an Exp after having seen a Smth '-' and looking at a lookahead of palT, it doesn't know whether it should reduce an empty Smth to finish the Exp (leaving the palT as part of some later construct) OR shift the palT so it can then be reduced (recognized) as a Smth that completes this Exp.
The language you are recognizing is a sequence of one or more Traducao, each of which consists of a Palavra followed by an optional palC (Correspondencia that may be a palC or empty). That means that you might have a Palavra directly following another Palavra (the Correspondencia for the first one is empty). So the parser needs to find the boundary between one Palavra and the next just by looking at its current state and one token of lookahead, which is a problem.
In particular, when you have an input like PalT '-' PalT '-' PalT, that is two consecutive Palavra, but it is not clear whether the middle PalT belongs to the first one or the second. It is ambiguous, because it could be parsed successfully either way.
If you want the parser to just accept as much as possible into the first Palavra, then you can just accept the default resolution (of shift). If that is wrong and you would want the other interpretation, then you are going to need more lookahead to recognize this case, as it depends on whether or not there is a second '-' after the second palT or something else.
I have shift-reduce warnings like this:
Can someone explain me what am I missing here?
168: shift/reduce conflict (shift 316, reduce 157) on ','
state 168
static_var_list : static_var_list2 . (157)
static_var_list2 : static_var_list2 . ',' T_VARIABLE '=' static_scalar (158)
I'm writing a flex/yacc program that should read some tokens and easy grammar using cygwin.
I'm guessing something is wrong with my BNF grammar, but I can't seem to locate the problem. Below is some code
%start statement_list
%%
statement_list: statement
|statement_list statement
;
statement: condition|simple|loop|call_func|decl_array|decl_constant|decl_var;
call_func: IDENTIFIER'('ID_LIST')' {printf("callfunc\n");} ;
ID_LIST: IDENTIFIER
|ID_LIST','IDENTIFIER
;
simple: IDENTIFIER'['NUMBER']' ASSIGN expr
|PRINT STRING
|PRINTLN STRING
|RETURN expr
;
bool_expr: expr E_EQUAL expr
|expr NOT_EQUAL expr
|expr SMALLER expr
|expr E_SMALLER expr
|expr E_LARGER expr
|expr LARGER expr
|expr E_EQUAL bool
|expr NOT_EQUAL bool
;
expr: expr ADD expr {$$ = $1+$3;}
| expr MULT expr {$$ = $1-$3;}
| expr MINUS expr {$$ = $1*$3;}
| expr DIVIDE expr {if($3 == 0) yyerror("divide by zero");
else $$ = $1 / $3;}
|expr ASSIGN expr
| NUMBER
| IDENTIFIER
;
bool: TRUE
|FALSE
;
decl_constant: LET IDENTIFIER ASSIGN expr
|LET IDENTIFIER COLON "bool" ASSIGN bool
|LET IDENTIFIER COLON "Int" ASSIGN NUMBER
|LET IDENTIFIER COLON "String" ASSIGN STRING
;
decl_var: VAR IDENTIFIER
|VAR IDENTIFIER ASSIGN NUMBER
|VAR IDENTIFIER ASSIGN STRING
|VAR IDENTIFIER ASSIGN bool
|VAR IDENTIFIER COLON "Bool" ASSIGN bool
|VAR IDENTIFIER COLON "Int" ASSIGN NUMBER
|VAR IDENTIFIER COLON "String" ASSIGN STRING
;
decl_array: VAR IDENTIFIER COLON "Int" '[' NUMBER ']'
|VAR IDENTIFIER COLON "Bool" '[' NUMBER ']'
|VAR IDENTIFIER COLON "String" '[' NUMBER ']'
;
condition: IF '(' bool_expr ')' statement ELSE statement;
loop: WHILE '(' bool_expr ')' statement;
I've tried changing statement into
statement:';';
,reading a simple token to test if it works, but it seems like my code refuses to enter that part of the grammar.
Also when I compile it, it tells me there are 18 shift/reduce conflicts. Should I try to locate and solve all of them ?
EDIT: I have edited my code using Chris Dodd's answer, trying to solve each conflict by looking at the output file. The last few conflicts seem to be located in the below code.
expr: expr ADD expr {$$ = $1+$3;}
| expr MULT expr {$$ = $1-$3;}
| expr MINUS expr {$$ = $1*$3;}
| expr DIVIDE expr {if($3 == 0) yyerror("divide by zero");
else $$ = $1 / $3;}
|expr ASSIGN expr
| NUMBER
| IDENTIFIER
;
And here is part of the output file telling me what's wrong.
state 60
28 expr: expr . ADD expr
29 | expr . MULT expr
30 | expr . MINUS expr
31 | expr . DIVIDE expr
32 | expr . ASSIGN expr
32 | expr ASSIGN expr .
ASSIGN shift, and go to state 36
ADD shift, and go to state 37
MINUS shift, and go to state 38
MULT shift, and go to state 39
DIVIDE shift, and go to state 40
ASSIGN [reduce using rule 32 (expr)]
ADD [reduce using rule 32 (expr)]
MINUS [reduce using rule 32 (expr)]
MULT [reduce using rule 32 (expr)]
DIVIDE [reduce using rule 32 (expr)]
$default reduce using rule 32 (expr)
I don't understand, why would it choose rule 32 when it read ADD, MULT, DIVIDE or other tokens ? What's wrong with this part of my grammar?
Also, even though that above part of the grammar is wrong, shouldn't my compiler be able to read other grammar correctly ? For instance,
let a = 5
should be readable, yet the program returns syntax error ?
Your grammar looks reasonable, though it does have ambiguities in expressions, most of which could be solved by precedence. You should definitely look at ALL the conflicts reported and understand why they occur, and preferrably change the grammar to get rid of them.
As for your specific issue, if you change it to have statement: ';' ;, it should accept that. You don't show any of your lexing code, so the problem may be there. It may be helpful to compile you parser with -DYYDEBUG=1 to enable the debugging code generated by yacc/bison, and set the global variable yydebug to 1 before calling yyparse, which will dump a trace of everything the parser is doing to stderr.
I'm making this grammar so that i can recognize streets, post cods, etc, it only gives that error, but i can't solve it.
grammar LabeledExpr;
/** The start rule; begin parsing here. */
exp: Inicio parte1 parte2 parte4 NL exp
| Inicio parte6 parte2 parte7 NL exp
|fim;
fim: /*vazio*/;
parte1: Id_Env Str Rua;
parte2: Virg Num parte3|/*vazio*/;
parte3: Andar|/*vazio*/;
parte4:Cod_Postal Str parte5;
parte5: Str |/*vazio*/;
parte6: Cod_Postal Id_Env Rua;
parte7:Str Str parte5;
Space : (' '|'\t')+ { skip(); };
Inicio : '#ID#';
Id_Env: [1-9]Nu?Nu?Nu?|'0';
Rua : '\"'('Rua'|'Av.'|'Trav.')Letra'\"';
Str : '\"'Letra'\"';
Letra: [A-Za-z ]+;
XXXX : [1-9]YYY;
YYY : Nu Nu Nu;
Andar: Num | 'R/C' | 'cave';
Cod_Postal: XXXX('-'YYY)?;
Num: [1-9]Nu*;
Nu: [0-9];
Virg:',';
NL : [\r\n]+;
Ponto: . ;
The error is:
line 1:38 mismatched input '123' expecting Num
line 2:35 mismatched input '3' expecting Num
line 3:55 mismatched input '9876' expecting Num
line 4:39 mismatched input '2623' expecting Num
Does anyone understands it?
Id_Env matches 123 as it is before Num.
Ter
You should make some of your lexer rules parser rules instead. Like Ter already pointed out, you have some lexer rules that can match the same input. This is resolved as "first wins", i.e. the topmost wins.
I'd also make Lettra a fragment since otherwise it will match things like R/C' or 'cave'.
Also note that Ponto matches any single character. Although I'm not proficient in your mother language, it sounds to me like Ponto should only match the point, so you have to write '.' instead of ..
I was trying many many time to solve this conflict.
But I don't know why occur conflict here.
2 conflicts occur at compliation time.
yacc(bison) error goes:
State 314 conflicts: 1 shift/reduce
State 315 conflicts: 1 shift/reduce
state 314
7 c_complex_object_id: type_identifier .
8 | type_identifier . V_LOCAL_TERM_CODE_REF
V_LOCAL_TERM_CODE_REF shift, and go to state 77
V_LOCAL_TERM_CODE_REF [reduce using rule 7 (c_complex_object_id)]
$default reduce using rule 7 (c_complex_object_id)
state 315
127 c_integer_spec: integer_value .
184 ordinal: integer_value . SYM_INTERVAL_DELIM V_QUALIFIED_TERM_CODE_REF
201 integer_list_value: integer_value . ',' integer_value
203 | integer_value . ',' SYM_LIST_CONTINUE
SYM_INTERVAL_DELIM shift, and go to state 380
',' shift, and go to state 200
SYM_INTERVAL_DELIM [reduce using rule 127 (c_integer_spec)]
$default reduce using rule 127 (c_integer_spec)
state 77
8 c_complex_object_id: type_identifier V_LOCAL_TERM_CODE_REF .
$default reduce using rule 8 (c_complex_object_id)
state 380
184 ordinal: integer_value SYM_INTERVAL_DELIM . V_QUALIFIED_TERM_CODE_REF
V_QUALIFIED_TERM_CODE_REF shift, and go to state 422
state 200
201 integer_list_value: integer_value ',' . integer_value
203 | integer_value ',' . SYM_LIST_CONTINUE
V_INTEGER shift, and go to state 2
SYM_LIST_CONTINUE shift, and go to state 276
'+' shift, and go to state 170
'-' shift, and go to state 171
integer_value go to state 277
...
yacc source goes:
c_complex_object_id
: type_identifier
| type_identifier V_LOCAL_TERM_CODE_REF
;
type_identifier
: '(' V_TYPE_IDENTIFIER ')'
| '(' V_GENERIC_TYPE_IDENTIFIER ')'
| V_TYPE_IDENTIFIER
| V_GENERIC_TYPE_IDENTIFIER
;
c_integer_spec
: integer_value
| integer_list_value
| integer_interval_value
;
c_integer
: c_integer_spec
| c_integer_spec ';' integer_value
| c_integer_spec ';' error
;
ordinal
: integer_value SYM_INTERVAL_DELIM V_QUALIFIED_TERM_CODE_REF
;
integer_list_value
: integer_value ',' integer_value
| integer_value ',' SYM_LIST_CONTINUE
;
integer_value
: V_INTEGER
| '+' V_INTEGER
| '-' V_INTEGER
;
I have two problems above. What's wrong with it?
Let's consider the messages from the first shift/reduce conflict. You can read the period (".") as a pointer. What the message says, more or less in English, is
"When I'm in state 299, and I have recognized a type_identifier, I must decide whether to reduce by rule 7 (recognize c_complex_object_id : type_identifier) or to shift to state 63 (continue scanning for a V_LOCAL_TERM_CODE_REF)."
Usually a conflict like this comes about when the production not yet recognized (V_LOCAL_TERM_CODE_REF) is optional.
Your definition of the tokens V_LOCAL_TERM_CODE_REF, etc. looks OK as far as I can tell from your comment.
It's hard to diagnose this further without seeing the yacc diagnostic output for state 63. Could you edit your question to show the output for state 63? It might tell us something.
I found some lecture notes by Pete Jinks that might be useful background for you. You might also read some of the other questions listed in the right column of this page, under the "Related" heading.
Update
In one way, you are correct: a shift/reduce conflict can be ignored. bison/yacc will produce a parser that runs, that does something. But it is important to understand why you are ignoring a specific conflict. Then you will understand why the parser, when presented with an input program, parses it the way it does and produces the output that it does. It is not good to say, "oh, this is too complex, I can't figure it out."