LR1 LaLr Course
LR1 LaLr Course
Y.N. Srikant
The core part of LR(1) items (the part after leaving out the
lookahead symbol) is the same for several LR(1) states
(the loohahead symbols will be different)
Merge the states with the same core, along with the
lookahead symbols, and rename them
The ACTION and GOTO parts of the parser table will be
modified
Merge the rows of the parser table corresponding to the
merged states, replacing the old names of states by the
corresponding new names for the merged states
For example, if states 2 and 4 are merged into a new state
24, and states 3 and 6 are merged into a new state 36, all
references to states 2,4,3, and 6 will be replaced by
24,24,36, and 36, respectively
LALR(1) parsers may perform a few more reductions (but
not shifts) than an LR(1) parser before detecting an error
Y.N. Srikant
programs – optional
YACC uses the lexical analyzer generated by LEX to match
the terminal symbols of the CFG
YACC generates a file named y.tab.c
E → E + E | E − E | E ∗ E | E/E | (E) | id
Ambiguity with left or right associativity of ‘-’ and ‘/’
This causes shift-reduce conflicts in YACC: (E-E-E) – shift
or reduce on -?
Disambiguating rule in YACC:
Default is shift action in S-R conflicts
Reduce by earlier rule in R-R conflicts
Associativity can be specified explicitely
Similarly, precedence of operators causes S-R conflicts.
Precedence can also be specified
Example
%right ’=’
%left ’+’ ’-’ --- same precedence for +, -
%left ’*’ ’/’ --- same precedence for *, /
%right ^ --- highest precedence
Y.N. Srikant YACC
Symbol Values
%{
#define NSYMS 20
struct symtab {
char *name; double value;
}symboltab[NSYMS];
struct symtab *symlook();
#include <string.h>
#include <ctype.h>
#include <stdio.h>
%}
%union {
double dval;
struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%token POSTPLUS
%token POSTMINUS
%left ’=’
%left ’+’ ’-’
%left ’*’ ’/’
%left POSTPLUS
%left POSTMINUS
%right UMINUS
%type <dval> expr
number [0-9]+\.?|[0-9]*\.[0-9]+
name [A-Za-z][A-Za-z0-9]*
%%
[ ] {/* skip blanks */}
{number} {sscanf(yytext,"%lf",&yylval.dval);
return NUMBER;}
{name} {struct symtab *sp =symlook(yytext);
yylval.symp = sp; return NAME;}
"++" {return POSTPLUS;}
"--" {return POSTMINUS;}
"$" {return 0;}
\n|. {return yytext[0];}
%%
void initsymtab()
{int i = 0;
for(i=0; i<NSYMS; i++) symboltab[i].name = NULL;
}
int yywrap(){return 1;}
yyerror( char* s) { printf("%s\n",s);}
main() {initsymtab(); yyparse(); }
#include "lex.yy.c"