(* * This file illustrates how to create an attribute-grammar-style definintion * in RSL. Syntactically, the notation is slightly different that most * standard CFG notations, however these syntactic differences are quite minor. * The differences are: * * (1) The RSL keyword "is" is used in place of the more standar '::=' * rule separator. * (2) Elements of the RHS of a rule must be separated with one of the two * normal RSL and operators "and" or ",", rather than the more typical * blanks. * * Comments below indicate what does not work here. Cf * ./term-factor-almost-works.rsl and ./term-factor-does-work.rsl. *) module TermFactorAttributeGrammar; (* * Attribute definitions. *) define obj attribute type:Type; define obj attribute valu:Value; (* * Attribute type definitions. *) obj Type = string; obj Value = number; (* * Grammar and semantic action definitions. *) (* * The attempt here was to eliminate the need for multiple obj defs by * allowing the actions to refer to the differently named components of the * comp expr. Unfortunately, as soon as we have an '|' in the comp expr, * the names of internal tuple components are not directly accessible. * I.e., in the comp expr for E just below, the precedence is * (e:E, '+', t:T) | (t':T) * which means that the component named "e" should not be directly * accessible in the action routine, since it's a member of the * (unfortunately anonymous) first tuple of the comp expr. Hence, e should * only officially be accesible via p1.e, which looks like a hokey pain. * * Soooo, let's just go with allowing obj redef to mean auto-unioning. It * seems that this wont be too big a pain to implement, per notes of 9nov96 * in rsl/doc/implementation-ideas.me, q.v. * * The other notational device is the Yacc-like embedded actions, which * appear to work fine if the use can stomach them. *) obj E = e:E, '+', t:T | t':T actions: this.:type == (if e.:type = t.:type then e.:type else "ERROR"); this.:valu == e.:valu + t.:valu; | this.:type == t'.:type; this.:valu == t.:valu; end E; obj T = t:T, '*', f:F; obj T' = f:F; obj F = 'x'; end TermFactorAttributeGrammar;