Download presentation
Presentation is loading. Please wait.
1
CH4.1 CSE244 Bottom Up Translation (revisited) Aggelos Kiayias Computer Science & Engineering Department The University of Connecticut 371 Fairfield Road, Unit 1155 Storrs, CT 06269 aggelos@cse.uconn.edu http://www.cse.uconn.edu/~akiayias
2
CH4.2 CSE244 The Picture So Far We discussed already “top-down translation.” Works exceptionally well with L-attributed Definitions (with corresponding translation schemes) Nevertheless we must make sure that the underlying grammar is suitable for predictive parsing. Grammar has no left-recursion and it is left-factored. We also discussed “bottom up translation” For S- Directed Definitions. Simple Idea: Use additional stack space to store attribute values for Non-terminals. During Reduce Actions update attributes in stack accordingly.
3
CH4.3 CSE244 Inherited Attributes and Bottom Up Translation Some inherited attributes might not be available when we are reducing by a certain production. Consider the translation scheme: PRODUCTIONSEMANTIC RULE D T LL.in = T.type T int T.type = integer T real T.type = real L L 1, idL 1.in = L.in addtype(id.entry, L.in) L id addtype(id.entry, L.in) Attempt B-U parsing over real id 1, id 2, id 3
4
CH4.4 CSE244 Parsing Example. STACKInputAction $real a,b,c$SHIFT $[real, lexval=‘real’]a,b,c$REDUCE T real modify type $[T, type = ‘real’]a,b,c$SHIFT $[T, type = ‘real’] [id, lexval=‘a’],b,c$REDUCE L id requires L.in $[T, type = ‘real’] [L, …],b,c$SHIFT $[T, type = ‘real’] [L, …], [id, lexval=‘b’],c$REDUCE L L, id requires L.in $[T, type = ‘real’] [L, …],c$SHIFT $[T, type = ‘real’] [L, …], [id, lexval=‘c’] $REDUCE L L, id requires L.in Value of L.in is not necessary… We might look into the stack and recover its intended value…
5
CH4.5 CSE244 Bottom Up Translation with Inherited Attributes Try to predict the location in the stack that you can recover the value of the inherited attribute you need. PRODUCTIONSEMANTIC RULE D T L T int val[ntop] = integer T real val[ntop] = real L L 1, idaddtype(id.entry, val[top-3]) L id addtype(id.entry, val[top-1]) Dangerous Stuff !!!
6
CH4.6 CSE244 A Brief Look into Yacc Terminals and Non-terminals in Yacc they have a “semantic value” (one attribute). The attribute type is specified by YYSTYPE Different typing for attributes is achieved through %union The current terminal semantic values are passed by Lex in the variable yylval (specified by Lex). Semantic values for a certain production are specified by the symbols $$, $1, $2, $3, … For a certain production, LHS is $$ and $1, $2, $3, … denote the semantic values of each item in the RHS. Also one can use $0, $-1, $-2, … to peek into the Yacc stack (beyond the current production). Dangerous Stuff !!!
7
CH4.7 CSE244 A Brief Look into Yacc,II Frequently one needs more versatility in defining the semantic values of non-terminals. (i.e., various different attributes). We define a collection of data types using %union We determine the attribute type of each symbol by using the %type declaration.
8
CH4.8 CSE244 Defining Attributes in Lex/Yacc typedef struct { int value; } myattribute; %union{ int number_type; int ident_type; int ident_type; myattribute myattribute_type; } myattribute myattribute_type; } %token ID %token NUM %type expr %left '+' % expr : ID { printf("%d\n", $1); $$.value = $1; } | NUM { printf("%d\n", $1); $$.value = $1; } | NUM { printf("%d\n", $1); $$.value = $1; } | expr '+' expr { $$.value = $1.value + $3.value; printf("%d\n", $$.value); } | expr '+' expr { $$.value = $1.value + $3.value; printf("%d\n", $$.value); } ;% *************** LEX FILE ***************** id [A-Za-z][A-Za-z0-9]* num [0-9]+ ws [ \t]+ % {ws} /* do nothing */ {id} { yylval.ident_type = 44; return ID; } {numr} { yylval.number_type = atoi(yytext); return NUM; }. { return yytext[0]; } %
9
CH4.9 CSE244 The Stack of Yacc Yacc employs and maintains a stack that contains all semantic values/ attributes. When Yacc makes a shift action It enters into the stack the corresponding token identifier along with its semantic value as this is determined by YYSTYPE and/or %token declaration. The value is provided by yylval When Yacc makes a reduce action for a production A: X 1 X 2 { $$ = f ($1,$2) }; stack is interpreted as: …[ X 1,$1] [X 2,$2] I.e., yacc pops two stack elements and uses their semantic values to fill $1,$2 After the action: …[ A,$$]
10
CH4.10 CSE244 Attributes and Yacc Standard rules is that we cannot refer to any semantic-value or attribute to the “right.” E.g. the following will produce an error A: B C { $4 = f ($1,$2) } D; Usually we do the computation for $$ at the end of a production. Attributes of Yacc can be inherited in the following sense: A: B C { $2 = f ($1) }; But this is of limited use..
11
CH4.11 CSE244 Attributes and Yacc, II PRODUCTIONSEMANTIC RULE D T LL.in = T.type T int T.type = integer T real T.type = real L L 1, idL 1.in = L.in addtype(id.entry, L.in) L id addtype(id.entry, L.in) %type T %type L % D: T { $2 = $1 }L; This is no Good: L: ID_TOKEN {addtype($1,$0)}; Dangerous Stuff !!! Instead we opt to look into the stack:
12
CH4.12 CSE244... but there is a more “sane” way to go Use variables… When you code these productions: T int T.type = integer T real T.type = real T: REAL_TOKEN { current_type=$1 }; T: INT_TOKEN { current_type=$1 }; Then when time comes for the production: L id addtype(id.entry, L.in) Code it as: L: ID_TOKEN { addtype($1,current_type) }; It is easy to see that current_type will hold the most recent type occurrence. As a rule of thumb keep in mind the DFS traversal of the parse-tree.
13
CH4.13 CSE244 Always prefer the sane way. Unless you want to prove to your friends what a yacc-freak you are. + you want to show that you really understand grammars. + you want to make it really hard for other people to understand your YACC programs. IN THIS CASE prefer using $0,$-1,$-2,… The highest negative number used in a yacc code earns higher yacc-geekiness degree.
14
CH4.14 CSE244 Translation with Yacc (Looking Ahead) For a programming language: Target to an Intermediate Language. Not really assembly but very close to it. Restricted set of commands: Assignments with two operands. X=Y+Z Goto (jump statements) Conditional Goto’s using only two vars e.g. If X>Y Goto LABEL Push, Pop statements (stack)
15
CH4.15 CSE244 Translation with Yacc Define the main attribute of any construct to be a char buffer of a certain size + have any additional typedef struct {char* translation; int var;} myattribute; Then define semantics actions appropriately: e.g. expr : NUM { varcounter++; { varcounter++; append($$.translation, “a”, varcounter, “=“, $1); $$.var = varcounter; } | expr ‘ +‘ expr {varcounter++; | expr ‘ +‘ expr {varcounter++; append($$.translation, $1.translation); append($$.translation, $3.translation); append($$.translation, “a”, varcounter,“=“,“a”, $1.var, “+”, “a”, $3.var); $$.var = varcounter; } ;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.