ATTRIBUTE GRAMMAR FOR PL/0 -------------------------- This attribute grammar contructs an environment and a syntax tree for a PL/0 program. The environment corresponds to a symbol table of records with fields for identifier name and type. Types are themselves a variant record-like structure with three discriminants: 1) const with a value field, 2) var, and 3) procedure with fields to represent the local environment and syntax tree of that procedure. There is no type checking in this attribute grammar, so the environ- ment is not actually referenced. Attributes ---------- (1) env - environment as a list of declared variables with their associated type (e.g. const (value), var, procedure (env, tree)) (2) tree - syntax tree representation of program and procedures (3) lexeme - the lexeme of a token (4) value - the value of a numeric constant Functions --------- (1) list - return a list containing its argument (2) append - accept a set of arguments and return a list of those arguments (3) tuple - accept a set of arguments and return a tuple of those arguments (4) tree - accept a set of arguments and return a tree with the first argument as the root and the remaining arguments as children Grammar ------- ::= . . tree <-- . tree ::= . env <-- append ( . env, . env, . env) . env <-- . env . tree <-- . tree ::= const ; . env <-- . env | e . env <-- nil 2 ::= = . env <-- list (tuple ( . lexeme, const ( . value))) | [1] , = . env <-- append ([1] . env, list (tuple ( . lexeme, const ( . value)))) ::= var ; . env <-- . env | e . env <-- nil ::= . env <-- list (tuple ( . lexeme, var)) | [1] , . env <-- append ([1] . env, list (tuple ( . lexeme, var))) ::= [1] procedure ; ; . env <-- append ([1] . env, list (tuple ( . lexeme, procedure ( . env, . tree)))) | e . env <-- nil ::= := . env <-- . env . tree <-- tree (":=", . lexeme, . tree) | call . tree <-- tree ("call", . lexeme) | begin end . env <-- . env . tree <-- . tree | if then [1] . env <-- . env [1] . env <-- . env . tree <-- tree ("if-then", . tree, [1] . tree) | while do [1] . env <-- . env [1] . env <-- . env . tree <-- tree ("while-do", . tree, [1] . tree) | e . tree <-- nil 3 ::= . env <-- . env . tree <-- . tree | [1] ; [1] . env <-- . env . env <-- . env . tree <-- tree (";", [1] . tree, . tree) ::= odd . env <-- . env . tree <-- tree ("odd", . tree) | [1] [2] [1] . env <-- . env [2] . env <-- . env . tree <-- tree ( . lexeme, [1] . tree, [2] . tree) ::= = | <> | < | > | <= | >= ::= . env <-- . env . tree <-- . tree | . env <-- . env . tree <-- tree ( . lexeme, . tree) | [1] [1] . env <-- . env . env <-- . env . tree <-- tree ( . lexeme, [1] . tree, . tree) ::= + | - ::= . env <-- . env . tree <-- . tree | [1] [1] . env <-- . env . env <-- . env . tree <-- tree ( . lexeme, [1] . tree, . tree) ::= * | / ::= . tree <-- tree ( . lexeme) | . tree <-- tree ( . lexeme) | ( ) . env <-- . env . tree <-- . tree