Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
156 views

TutorialFlexBison PDF

Flex and Bison are tools for lexical analysis and parsing. Flex takes regular expressions as input and generates a scanner. Bison takes a context-free grammar as input and generates a parser. The document provides examples of Flex and Bison input files for a calculator and discusses integrating the generated scanner and parser. It also provides tips for debugging Bison parsers.

Uploaded by

Anoop Chauhan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
156 views

TutorialFlexBison PDF

Flex and Bison are tools for lexical analysis and parsing. Flex takes regular expressions as input and generates a scanner. Bison takes a context-free grammar as input and generates a parser. The document provides examples of Flex and Bison input files for a calculator and discusses integrating the generated scanner and parser. It also provides tips for debugging Bison parsers.

Uploaded by

Anoop Chauhan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2

Flex and Bison Tutorial Note: for more complex flex input file, you might get an error

flex input file, you might get an error message like


Ming-Hwa Wang, Ph.D "parse tree too big, try %a num (or %e num)"
COEN 259 Compilers Then you need to define %e <num>. You should put it between macro and
Department of Computer Engineering %start symbol. The other options are %a, %o, %n, %p, etc.
Santa Clara University
Bison
Flex Bison is a LALR(1) parser generator tool for syntax analysis, which is based
Flex is a scanner generator tool for lexical analysis, which is based on finite on pushdown automata (PDA). The input is a set of context-free grammar
state machine (FSM). The input is a set of regular expressions, and the (CFG) rules, and the output is the code to implement the parser according to
output is the code to implement the scanner according to the input rules. the input rules.

To implement a scanner for calculator, we can write the file “cal1.l” as To implement a parser for calculator, we can write the file “cal.y” as below:
below:
%{
/* this is only for scanner, not link with parser yet */ #include <stdio.h>
%{ #include <ctype.h>
int lineNum = 0; int lineNum = 1;
%} void yyerror(char *ps, ...) { /* need this to avoid
link problem */
%% printf("%s\n", ps);
}
"(" { printf("(\n"); } %}
")" { printf(")\n"); }
"+" { printf("+\n"); } %union {
"*" { printf("*\n"); } int d;
\n { lineNum++; } }
[ \t]+ { } // need to choose token type from union above
[0-9]+ { printf("%s\n", yytext); } %token <d> NUMBER
%token '(' ')'
%% %left '+'
%left '*'
int yywrap() { %type <d> exp factor term
return 1;
} %start cal

int main () { %%
yylex();
return 0; cal
} : exp
{ printf("The result is %d\n", $1); }
Here is the Makefile used to build the scanner: ;

p1: lex.yy.o exp


gcc -g -o p1 lex.yy.o : exp '+' factor
{ $$ = $1 + $3; }
lex.yy.o: cal1.l | factor
flex cal1.l; gcc -g -c lex.yy.c { $$ = $1; }
;
clean:
rm -f p1 *.o lex.yy.c factor
: factor '*' term #ifdef DEBUG
{ $$ = $1 * $3; } printf("token '+' at line %d\n", lineNum);
| term #endif
{ $$ = $1; } return '+';
; }
"*" {
term #ifdef DEBUG
: NUMBER printf("token '*' at line %d\n", lineNum);
{ $$ = $1; } #endif
| '(' exp ')' return '*';
{ $$ = $2; } }
; [0-9]+ {
#ifdef DEBUG
%% printf("token %s at line %d\n", yytext, lineNum);
#endif
int main() { yylval.d = atoi(yytext);
yyparse(); return NUMBER;
return 0; }
}
%%
To integrate both the scanner and parser, we need to modify the scanner
input file “cal1.l” and save it as “cal.l” as below: int yywrap() { /* need this to avoid link problem */
return 1;
%{ }
#include <stdlib.h> /* for atoi call */
#define DEBUG /* for debuging: print tokens and Here is the Makefile used to build the scanner and parser:
their line numbers */
#define NUMBER 258 /* copy this from cal.tab.c */ p2: lex.yy.o cal.tab.o
typedef union { /* copy this from cal.tab.c */ gcc -o p2 lex.yy.o cal.tab.o
int d;
} YYSTYPE; lex.yy.o: cal.l
YYSTYPE yylval; /* for passing value to parser */ flex cal.l; gcc -c lex.yy.c
extern int lineNum; /* line number from cal.tab.c */
%} cal.tab.o: cal.y
bison -d cal.y; gcc -c cal.tab.c
%%
clean:
[ \t]+ {} rm -f p2 cal.output *.o cal.tab.c lex.yy.c
[\n] { lineNum++; }
"(" { There are some tips to debug Bison.
#ifdef DEBUG 1. Run Bison with –v option, then a file cal.output is generated. It contains
printf("token '(' at line %d\n", lineNum); all the conflicts and/or never reduced rules, and all the states generated
#endif by Bison.
return '(';
2. To get debug information from Bison: first, add -DYYDEBUG when
}
compiling cal.tab.c; second, set the environment variable YYDEBUG=1.
")" {
#ifdef DEBUG Then it will print a bunch of debug information, e.g. how to shift or
printf("token ')' at line %d\n", lineNum); reduce.
#endif
return ')';
}
"+" {

You might also like