YACC

Yet Another Compiler Compiler

Yacc is a parser generator Input: A Grammar

Output: A parser for the grammar

Reminder: a parser finds derivations

The yacc code: expr : '(' expr ')' | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | . .expr | INT .expr | INT .Example grammar: expr -> ( expr ) | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | .

Exampe Input: 10 * 3 + 4 Yacc Derivation: expr => expr + expr => expr * expr + expr => 10*3 + 4 .

'/' %left UMINUS %% expr : '(' expr ')' | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | '-' expr %prec UMINUS | INT . '-' %left '*'. .Resolving Ambiguities %left '+'.

} | expr '*' expr {$$ = $1 * $3.} | '-' expr %prec UMINUS {$$ = -$2.} | expr '/' expr {$$ = $1 / $3. '-' %left '*'. .Actions %left '+'.} | expr '+' expr {$$ = $1 + $3.} | INT {$$ = $1.} . '/' %left UMINUS %% expr : '(' expr ')' {$$ = $2.} | expr '-' expr {$$ = $1 .$3.

A Complete Yacc program (EXPR1. } %left '+'. '-' %left '*'. '/' %left UMINUS %token <int_val> INT %type <int_val> expr %start program %% .y) %union{ int int_val.

%% #include "lex.} | '-' expr %prec UMINUS {$$ = -$2.yy.c" .program : expr {printf("Expr value = %d \n".} | expr '/' expr {$$ = $1 / $3.} .} | expr '+' expr {$$ = $1 + $3. expr : '(' expr ')' {$$ = $2.} | error {printf("YACC: syntax error near line %d \n". abort().$3.} . linenum).} | INT {$$ = $1. $1).} | expr '-' expr {$$ = $1 .} | expr '*' expr {$$ = $1 * $3.

Execution Example Input: Output: 10 + 20*(3 .4 + 25) Expr value = 490 .

%{ int linenum=1.l) [\t ] /* skip spaces */. %} %% \n {linenum++.} .} "*" {return '*'.} ")" {return ')'. int temp_int.} "-" {return '-'.} "(" {return '('. "+" {return '+'.} "/" {return '/'.} The Lex Code (expr1. \/\/[^\n]* /* ignore comments */.

&temp_int). abort().} . linenum). return INT. yylval. "%d".[0-9]+ {sscanf(yytext.} . {printf("LEX: unknown input string found in line %d \n".int_val = temp_int.

c -ly -ll -o myparser Executable: myparser .Compiling: yacc YaccFile lex LexFile cc y.tab.

'/' %left UMINUS %token <int_val> INT %type <int_val> expr %start program %% . } %left '+'.y) %union{ int int_val.Another Yacc Program (EXPR2. '-' %left '*'.

} . stmt : expr '. {printf("Expr value = %d \n". stmt_list : stmt_list stmt | stmt . $1).} . linenum). abort().' .program : stmt_list | error {printf("YACC: syntax error near line %d \n".

c" .} | '-' expr %prec UMINUS {$$ = -$2.} | INT {$$ = $1.} | expr '-' expr {$$ = $1 . %% #include "lex.} | expr '+' expr {$$ = $1 + $3.$3.} | expr '/' expr {$$ = $1 / $3.} .yy.expr : '(' expr ')' {$$ = $2.} | expr '*' expr {$$ = $1 * $3.

123 + -001. Output: Expr value = -175 Expr value = 1066 Expr value = 22 . 17*8/6. 34 * 35 .Execution Example Input: 10 + 20*(30 -67) / 4.

\/\/[^\n]* /* ignore comments */.Lex Code (expr2.l) %{ int linenum=1.} [\t ] /* skip spaces */. %} %% \n {linenum++. int temp_int. .

} {return '-'."+" "-" "*" "/" ")" "(" ". linenum).} {return '*'.} .} [0-9]+ {sscanf(yytext. return INT." {return '+'. &temp_int). {printf("LEX: unknown input string found in line %d \n".} {return '/'. yylval.} {return '. abort().'.} {return ')'.} {return '('.} . "%d".int_val = temp_int.

%union{ int int_val.y) %left '+'. } Another Yacc Program (EXPR3. '-' %left '*'. '/' %left UMINUS %token PRINT %token NEWLINE %token <str_val> STRING %token <int_val> INT %type <int_val> expr %start program %% . char *str_val.

} {printf("\n").' | PRINT expr '.} {printf("%d". stmt : expr '. stmt_list : stmt_list stmt | stmt . {printf("expression found\n"). abort().program : stmt_list | error {printf("YACC: syntax error near line %d \n".} {printf("%s". linenum).' | PRINT NEWLINE '.' .} . $2). $2).} .' | PRINT STRING '.

} | expr '/' expr {$$ = $1 / $3.} | expr '*' expr {$$ = $1 * $3.} | expr '+' expr {$$ = $1 + $3.c" . %% #include "lex.} | expr '-' expr {$$ = $1 .yy.} | INT {$$ = $1.expr : '(' expr ')' {$$ = $2.} | '-' expr %prec UMINUS {$$ = -$2.$3.} .

Execution Example Input: print "The value of expression 123 * 25 is ". print newline. print newline. 10 + 5 * 8. Output: The value of expression 123 * 25 is 3075 expression found end of program . print 123 * 25. print "end of program".

l) %{ int linenum=1. . int temp_int. char temp_str[200].} [\t ] /* skip spaces */. \/\/[^\n]* /* ignore comments */. %} %% \n {linenum++.Lex Code (expr3.

" {return '.} "-" {return '-'.} "print" {return PRINT.} "."+" {return '+'.'.} "newline" {return NEWLINE.} "/" {return '/'.} .} ")" {return ')'.} "*" {return '*'.} "(" {return '('.

return INT.str_val = temp_str. return STRING.} \"[^"\n]*\" {strncpy(temp_str.int_val = temp_int.} . {printf("LEX: unknown input string found in line %d \n". &temp_int). temp_str[strlen(yytext)-2] = (char) 0. "%d". &(yytext[1]). linenum). abort(). strlen(yytext)-2). yylval.} . yylval.[0-9]+ {sscanf(yytext.

Sign up to vote on this title
UsefulNot useful