%token <lbls> IF /* For backpatching labels*/
%token THEN ELSE FI
// ....
// ....
stmts :
stmt
| ifstmt
// ...
// ...
;
ifstmt : ifonly
| ifelsestmt
;
ifonly : IF exp {/* my code */ }
THEN commands
FI {/* my code */ }
;
ifelsestmt : IF exp {/* my code */ }
THEN commands {/* my code */ }
ELSE {/* my code */ }
commands
FI {/* my code */ }
;
This is my sample language
1 2 3 4 5 6 7
if n != 5 then
write "equal";
fi;
if abc == bcd then
else write "Str Not Equal";
fi;
If I run the above, It works perfectly for If Statement. But It gives me error at the line of else Statement. Is there any error in the rules ?
edit: i think the error is because in your grammar, you have it that after then there must be commands, so its seeing the else as a command and places it in one level deeper of scope. because of this, the else technically doesnt have a preceding if, which is causing the error. how to fix this: put in a command between then second if's then statement and the else statement
@TC: If you are trying to make an LL(1) parser (which is suppose may be a default), then you have a common prefix issue. I believe the technique used in this case is to left-factor out the common prefix (the if-statement).
I searched in some sites. It gives me the result that the problem is in Shift/reduce. So I had changed my code as Like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
%token <lbls> IF /* For backpatching labels*/
%token THEN
%nonassoc IFX
%nonassoc ELSE
%nonassoc FI
IF exp { /* my code */ }
THEN commands { /* my code */ }
%prec IFX
FI { /* my code */ }
| IF exp { /* my code */ }
THEN commands { /* my code */ }
ELSE { /* my code */ }
commands
FI { /* my code */ }
If if Give the Instruction '%prec IFX' before 'FI' statement, It gives me compile time Error as
"sample.yy", line 168: ill-formed rule
"sample.yy", line 168: rule given for FI, which is a token
rather If I give the same Instruction '%prec IFX' after 'FI' statement, I am not getting the compiler time error. But Else statement Doesn't working. I Have got Parse error, When I run my below code.
1 2 3 4 5
if n == 5 then write "equal"; fi;
if abc == bcd then write "Equal";
else write "Str Not Equal";
fi;