Download presentation
Presentation is loading. Please wait.
1
CPSC 325 - Compiler Tutorial 5 Parser & Bison
2
Bison Concept Bison reads tokens and pushes them onto a stack along with the semantic values. The process of pushing a token onto stack is called “shifting”. Example: ‘10 – 3 *’ with a 2 come. There are four tokens in stack. (shifted four tokens). Reduction is when the last n tokens match the components of a grammar rules, and they can be combined according to the rules. Example: 10 – 3 * 2 10 – 6 4
3
Look-Ahead Token Bison parser does NOT always reduce immediately as soon as the last n tokens and grouping match a rule. The parser sometimes “look ahead” at the next token in order to decide what to do.
4
Look-Ahead Tokens (cont) When a token is read, it become look-ahead token first, and which is not on the stack. Then the parser do one or more reductions of tokens and grouping on the stack. When no more reductions should take place, the look-ahead token is shifted onto the stack.
5
Example expr: term ‘–’ expr | term term: ‘(‘ expr ‘)’ | term ‘!’ | NUMBER Example: ‘3 – 5’ had been read and shift; what should be done? Depends on next token. 1. ‘)’: then reduce ‘3 – 5’ to ‘expr’; there is no rule for term ’)’ 2. ‘!’: then it must be shifted immediately, so that ‘5 !’ can be reduced to make a ‘term’. There is no rule for expr ‘!’
6
Conflicts If_stmt: IF expr THEN stmt | IF expr THEN stmt ELSE stmt Bison choose to “shift” the ELSE instead of “reduce” in this case. (Match the innermost if-statement) The grammar is ambiguous
7
Sample if-else in Bison %token IF THEN ELSE variable % stmt: expr | if_stmt If_stmt: IF expr THEN stmt | IF expr THEN stmt ELSE stmt expr: variable
8
Precedence expr: expr ‘+’ expr | expr ‘*’ expr | expr ‘<‘ expr | ‘(‘ expr ‘)’ | … We have input ‘3 + 2’ 1. ‘)’ – no problem, just reduce to expr 2. ‘*’ or ‘<‘ – Oh! Oh! problem….. What should we do?
9
Solution Break them apart as mention before. Bison declaration – ‘1 + (2 op 3)’ or (1 + 2) op 3 will lead to different result sometimes. – Example: ‘1 – 2 – 3’ should be (1 – 2) – 3 or 1 – (2 – 3)? We want the first one, which is left association. The second case is right association, which is desirable for assignment operators. %nonassoc is for error catching – In our case, we will have the following declaration %left ‘ ’ ‘=‘ NE LE GE %left ‘+’ ‘-’ %left ‘*’ ‘/’
10
Context-Dependent Precedence ‘–’ has very low precedence when it acts as an ‘subtract’. Nevertheless, when it acts as an unary ‘Negative’ operator. In Bison, each token can only been declare once in %left, %right and %nonassoc. Therefore, for context-dependent precedence, we need to use an additional mechanism: the %prec modifier for rules.
11
Sample code for Unary minus … %left ‘+’ ‘-’ %left ‘*’ ‘/’ %left UMINUS exp: … | exp ‘-’ exp … | ‘-’ exp %prec UMINUS …
12
yyparse() Implemented using a finite-state machine. Each time a look-ahead token is read, it will either take the action of “Shift the look-ahead token” or “Reduce using rule number n”.
13
Reduce Conflicts Consider the following grammars sequence: /*empty*/ { printf(“empty sequence\n”);} | maybeword | sequence word { printf(“added word %s\n, $2);} maybeword: /*empty*/ {printf(“empty maybeword\n”);} | word { printf(“single word %s\n, $1); }
14
Solution Bison resolves a reduce conflict by choosing to use the rule that appears first in the grammar, but it is very risky to rely on this. sequence: /*empty*/ { printf(“empty sequence\n”);} | sequence word { printf (“added word %s\n, $2); }
15
Left recursive sequence: /*empty*/ | sequence words | sequence redirects words: /*empty*/ | words word redirects: /*empty*/ | redirects redirect
16
Bison Structure %{ C declarations %} Yacc/Bison declarations % Grammar rules % Additional C code
17
Compile Bison file bash$ flex calc.l generate lex.yy.c bash$ bison -d calc.y generate calc.tab.c and calc.tab.h bash$ gcc –o calc *.c –ll –lm bash$ calc
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.