510 likes | 527 Views
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.
E N D
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 → 'program' Name ':' S 'end' Name '.’ => 'program'; S → 'assign' Name ':=' Exp => 'assign' → 'output' Exp => 'output' → 'if' Exp 'then' S 'else' S 'fi' => 'if' → 'while' Exp 'do' S 'od' => 'while' → S list ';' => ';' ; Exp → Term '=' Term => '=' → Term; Term → Term '+' Factor => '+' → Term '-' Factor => '-' → Factor;
Tiny’s Syntax (cont’d) Factor → '-' Factor => '-' → 'not' Factor => 'not' → 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 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] of save n: stack[n] := stack[top--] load n: stack[++top] := stack[n] negate: stack[top] := -stack[top] not: stack[top] := not stack[top] add: t := stack[top--]; stack[top] := stack[top] + t subtract: t := stack[top--]; stack[top] := stack[top] - t equal: t := stack[top--]; stack[top] := stack[top] = t
Target Machine Instruction Set (cont’d) read: stack[++top] := getinteger(input) print: putinteger(stack[top--]) lit n: stack[++top] := n goto n: PC := n; goto Next iffalse n: if stack[top--] = 0 then PC:=n; goto Next fi iftrue n: if stack[top--] = 1 then PC:=n; goto Next fi stop: halt end; ++PC; goto Next;
Target Code for our Sample Tiny Program 1: lit 1 # i := 1 2: load 1 # i = 11 3: lit 11 4: equal 5: not 6: iffalse 14 # while 7: read 8: print 9: load 1 # i := i + 1 10: lit 1 11: add 12: save 1 13: goto 2 # od 14: stop # 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, arg1 , ..., argn). Writes a new line to "file". The line contains arg1 , ..., argn. Returns the new, modified file. • function Open. Creates a new file. • function Close. Closes a file.
Attributes • code: File of code generated. • next: Label of the next instruction on the code file. • error: File of semantic errors. • top: Current (predicted) size of run-time stack. • type: 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) = { code , error } I(program) = { } S(assign) = { code , next , error , top , type } I(assign) = { 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 () = gen (code (), "lit", "n") next () = next () + 1 top () = top () + 1 type () = "integer"
Tiny's Attribute Grammar (cont’d) E → '<identifier:x>' code () = gen (code (), "load", lookup("x")) next () = next () + 1 top () = top () + 1 type () = "integer" error () = if lookup("x") = 0 then gen (error (), "identifier un-initialized") else error ()
Tiny's Attribute Grammar (cont’d) E → read code () = gen (code (), "read") next () = next () + 1 top () = top () + 1 type () = "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 () = gen (code (2), "add") next () = next (2) + 1 top () = top (2) - 1 type () = "integer" error () = 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 () = gen (code (2), “subtract") next () = next (2) + 1 top () = top (2) - 1 type () = "integer" error () = 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 () = gen (code (2), “equal") next () = next (2) + 1 type () = “boolean" top () = top (2) - 1 error () = 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 () = gen (code (1), “print") next () = next (1) + 1 top () = top (1) - 1 type () = “statement" error () = 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 () = if lookup("x") = 0 then enter("x",top (2)); code (2) else gen (code (2), "save", lookup("x")) next () = if lookup("x") = 0 then next (2) else next (2) + 1
E → < assign '<identifier:x>' E >(cont’d) top () = 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"
Tiny's Attribute Grammar (cont’d) E -> < ; E* > Use Defaults !
Tiny's Attribute Grammar (cont’d) E → < if E E E > code (2) = gen (code (1),"iffalse", next (2) + 1) next (2) = next (1) + 1 top (2) = top (1) - 1 code (3) = gen (code (2), "goto", next (3)) next (3) = next (2) + 1 error (2) = 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") error () = 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 (2) = gen (code (1), "iffalse", next (2) + 1) next (2) = next (1) + 1 top (2) = top (1) - 1 code () = gen (code (2), "goto", next ()) next () = next (2) + 1 type () = "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 (2) = Open error (2) = Open next (2) = 1 top (2) = 0 code () = close (gen (code (2), "stop")) error () = close (if x = y then error (2) else gen (error (2), "program names don't match") )