(* * * NOTE: Space-delimited RHS elements DO now work. Hence, the restriction that * RHS elements must be separated by 'and' or ',' no longer exists. See * term-factor-wish-syntax.rsl. * * This file illustrates how to create an attribute-grammar-style definintion * in RSL. Syntactically, the notation is slightly different than most * standard CFG notations, however these syntactic differences are quite minor. * The differences are: * * (1) Elements of the RHS of a rule must be separated with one of the two * normal RSL operators 'and' or ',', rather than the more typical * blanks. * (2) The normal RSL attribute selection operator '.:' is used to select * the value of symbol attributes rather than the more typical '.'. * * Note that this grammar is patterned directly after the examples in CSC 451 * lectures notes week 9. See ~gfisher/classes/451/lectures/9.ps. * * Cf ./term-factor-almost-works.rsl and ./term-factor-doesnt-work.rsl. *) module TermFactorAttributeGrammar; (* * Attribute definitions. *) define obj attribute type:Type; define obj attribute valu:Value; define obj attribute text:string; (* * Attribute type definitions. *) obj Type = string; obj Value = number; obj Symtab = SymtabEntry*; obj SymtabEntry = n:Name and t:Type and v:Value; obj Name = string; (* * Auxiliary functions. *) function Lookup(Symtab, Name)->SymtabEntry; (* * Global attributes. *) var symtab:Symtab; (* * Grammar and semantic action definitions. *) obj E ::= e:E, '+', t:T actions: this.:type == (if e.:type = t.:type then e.:type else "ERROR"); this.:valu == e.:valu + t.:valu; end E; obj E ::= t:T actions: this.:type == t.:type; this.:valu == t.:valu; end E; obj T ::= t:T, '*', f:F actions: this.:type == (if e.:type = t.:type then e.:type else "ERROR"); this.:valu == e.:valu * t.:valu; end T; obj T ::= f:F actions: this.:type == f.:type; this.:valu == f.:valu; end T; obj F ::= x:'x' actions: this.:type == Lookup(symtab, x.:text).t; this.:valu == Lookup(symtab, x.:text).v; end F; end TermFactorAttributeGrammar;