An Attribute Grammar for Tiny Programming Language Principles
An Attribute Grammar for Tiny Programming Language Principles Lecture 18 Prepared by Manuel E. Bermúdez, Ph. D. Associate Professor University of Florida
An Attribute Grammar for Tiny • Tiny: a very small Pascal-like language with the following: • Every program is given a name. • Variables of type integer. • Expressions composed of: • variables • integers • intrinsic function "read" • boolean operator "not"
An Attribute Grammar for Tiny (cont’d) • equality operator "=" • binary operators "+" and "-" • unary "-", "not". • Assignment statements. • Variables must be assigned a value before they are used. • No declarations.
An Attribute Grammar for Tiny (cont’d) • Statements: • if-then-else • while • statement sequencing ("; ") • output statement.
Tiny’s Syntax Tiny S Exp Term → → → 'program' Name ': ' 'assign' Name ': =' 'output' Exp 'if' Exp 'then' S 'while' Exp 'do' S S list '; ' Term '=' Term; Term '+' Factor Term '-' Factor; S 'end' Name '. ’ Exp 'else' S 'fi' 'od' => => 'program'; 'assign' 'output' 'if' 'while' '; ' ; '=' => '+' => '-'
Tiny’s Syntax (cont’d) Factor → '-' Factor => '-' => 'not' → 'not' Factor → Name → 'read' => 'read' → '<integer>' → '(' Expression ')'; Name → '<identifier>';
Sample Tiny Program • Copies 10 integers from input to output: program copy: assign i : = 1; while not (i=11) do output read; assign i : = i + 1 od end copy.
AST Grammar for Tiny P → <'program' '<identifier>' E '<identifier>'> E → <'assign' '<identifier>' E> → <'output' E> → <'if' E E E> → <'while' E E> → <'; ' E+> → <'not' E> → <'=' E E> → <'+' E E> → <'-' E> → '<identifier>' → '<integer>' → 'read'
Note • AST grammar simplified. • No distinction between expressions and statements. • Our attribute grammar will specify the translation (compilation) of Tiny programs to assembly for an abstract machine.
Target Machine Instruction Set PC : = 1; Next: case Code[PC] save n: load n: negate: not: add: subtract: equal: of stack[n] : = stack[top--] stack[++top] : = stack[n] stack[top] : = -stack[top] : = not stack[top] t : = stack[top--]; stack[top] : = stack[top] + t t : = stack[top--]; stack[top] : = stack[top] - t t : = stack[top--]; stack[top] : = stack[top] = t
Target Machine Instruction Set (cont’d) read: print: lit n: goto n: iffalse n: iftrue n: stop: end; ++PC; goto Next; stack[++top] : = getinteger(input) putinteger(stack[top--]) stack[++top] : = n PC : = n; goto Next if stack[top--] = 0 then PC: =n; goto Next fi if stack[top--] = 1 then PC: =n; goto Next fi halt
Target Code for our Sample Tiny Program 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: lit 1 load 1 lit 11 equal not iffalse 14 read print load 1 lit 1 add save 1 goto 2 stop # i : = 1 # i = 11 # while # i : = i + 1 # od # end program copy: assign i : = 1; while not (i=11) do output read; assign i : = i + 1 od end copy.
Semantic Errors • Variables used before being initialized. • Non-boolean expression in "while", "not", or "if". • Non-integer expression in "=", "-", or "+". • Program names do not match.
Data Structures Required • Declaration table. • Function enter(name, l). • Binds "name" with stack location "l". • Returns "l". • Function lookup(name). • Returns the location of "name". • Returns 0 if "name" is not found.
Data Structures Required (cont’d) • Files. • Function gen(file, arg 1 , . . . , argn). Writes a new line to "file". The line contains arg 1 , . . . , argn. Returns the new, modified file. • function Open. Creates a new file. • function Closes a file.
Attributes • code: • next: File of code generated. Label of the next instruction • error: • top: on the code file. File of semantic errors. Current (predicted) size • type: of run-time stack. Type of subtree. Used for type-checking.
Attributes (cont’d) • ALL attributes are both synthesized and inherited. • Convention: • a is the synthesized attribute a. • a is the inherited attribute a.
Synthesized and Inherited Attributes S(program) I(program) S(assign) I(assign) = = { { code , error } } code , next , error , top , type } code , next , error , top } • All other nodes: • Same synthesized and inherited attributes as "assign".
Synthesized and Inherited Attributes • Most nodes have: • Four inherited attributes (all except type ). • All five synthesized attributes. • One exception: • "program" node: • no inherited attributes. • two synthesized attributes: code and error .
Tree Walking Assumptions • Top-down on the left, • Bottom-up on the right. • Defaults: • If axiom is missing, assume • no kids: a ( ) = a ( ) • n kids: • a (1) = a ( ) • a (i) = a (i-1), for 1 < i <= n • a ( ) = a (n)
Tiny's Attribute Grammar E → '<integer>: n' code "n") next top ( ) type ( ) = gen (code ( ), "lit", ( ) = next ( ) + 1 = top ( ) + 1 ( ) = "integer"
Tiny's Attribute Grammar (cont’d) E → '<identifier: x>' code ( ) = gen (code ( ), "load", lookup("x")) next top type error ( ) ( ) = next ( ) + 1 = top ( ) + 1 = "integer" = if lookup("x") = 0 then gen (error ( ), "identifier un-initialized") else error ( )
Tiny's Attribute Grammar (cont’d) E → read code "read") next top ( ) type ( ) = gen (code ( ), ( ) = next ( ) + 1 = top ( ) + 1 ( ) = "integer"
Tiny's Attribute Grammar (cont’d) E → < - E > code ( ) = gen (code (1), "negate") next ( ) = next (1) + 1 type ( ) = "integer" error ( ) = if type (1) = "integer" then error (1) else gen (error (1), “Illegal type for minus"))
Tiny's Attribute Grammar (cont’d) E → <not E > code ( ) = gen (code (1), “not") next ( ) = next (1) + 1 type ( ) = “boolean" error ( ) = if type (1) = “boolean" then error (1) else gen (error (1), "Illegal type for not")
Tiny's Attribute Grammar (cont’d) E → < + E E > code next top type error ( ) ( ) ( ) = = = gen (code (2), "add") next (2) + 1 top (2) - 1 "integer" if type (1)=type (2)= "integer" then error (2) else gen (error (2), "Illegal type for plus")
Tiny's Attribute Grammar (cont’d) E → < - E E > code next top type error ( ) ( ) ( ) = = = gen (code (2), “subtract") next (2) + 1 top (2) - 1 "integer" if type (1)=type (2)= "integer" then error (2) else gen (error (2), "Illegal type for minus")
Tiny's Attribute Grammar (cont’d) E → < = E E > code next type top error ( ) ( ) ( ) gen (code (2), “equal") next (2) + 1 “boolean" top (2) - 1 if type (1) = type (2) then error (2) else gen (error (2), "Type clash in equal comparison") = = =
Tiny's Attribute Grammar (cont’d) E → < output E > code next top type error ( ) ( ) ( ) gen (code (1), “print") next (1) + 1 top (1) - 1 “statement" if type (1) = "integer" then error (1) else gen (error (1), "Illegal type for output") = = =
Tiny's Attribute Grammar (cont’d) E → < assign '<identifier: x>' E > code ( ) = next if lookup("x") = 0 then enter("x", top (2)); code (2) else gen (code (2), "save", lookup("x")) ( ) = if lookup("x") = 0 then next (2) else next (2) + 1
E → < assign '<identifier: x>' E > (cont’d) ( ) = if lookup ("x") = 0 then top (2) else top (2) - 1 error ( ) = if type (2) = "integer" then error (2) else gen (error (2), "Assignment type clash") type ( ) = "statement" top
Tiny's Attribute Grammar (cont’d) E -> < ; E* > Use Defaults !
Tiny's Attribute Grammar (cont’d) E → < if E E E > code next top code next error (2) (2) (3) (2) gen (code (1), "iffalse", next (2) + 1) next (1) + 1 top (1) - 1 gen (code (2), "goto", next (3)) next (2) + 1 if type (1) = "boolean" then error (1) else gen (error (1), "Illegal expression for if") = = =
E → < if E E E > (cont’d) error (3) = if type (2) = "statement" then error (2) else gen (error (2), "Statement required for if") ( ) = if type (3) = "statement" then error (3) else gen (error (3), "Statement required for if")
Tiny's Attribute Grammar (cont’d) E → < while E E > code next top code next type (2) (2) ( ) ( ) = = = gen (code (1), "iffalse", next (2) + 1) next (1) + 1 top (1) - 1 gen (code (2), "goto", next ( )) next (2) + 1 "statement"
E → < while E E > (cont’d) error (2) = if type (1) = "boolean" then error (1) else gen (error (1), "Illegal expression in while") error ( ) = if type (2) = "statement" then error (2) else gen (error (2), "Statement required in while")
Tiny's Attribute Grammar (cont’d) Tiny → < program '<identifier: x>' E '<identifier: y>' > code error next top code error (2) (2) ( ) = = = Open 1 0 close (gen (code (2), "stop")) close (if x = y then error (2) else gen (error (2), "program names don't match") )
An Attribute Grammar for Tiny Programming Language Principles Lecture 18 Prepared by Manuel E. Bermúdez, Ph. D. Associate Professor University of Florida
- Slides: 51