Home

uuagsmall.png

Projects

Resources

Attribute Grammar System Features

HUT

New Features (Nov 3, 2003)

The AG-systeem has a number of new features.

  • use of attribute names in patterns on left-hand side of a rule
  • nonterminal sets
  • DERIVING for classes
  • WRAPPER to generate wrappers for semantic functions

Left-hand side patterns:

Attribute names can now be used in left hand side patterns:

SEM X [ | counter :Int | pp:PP_DOC ]
  | Y (lhs.pp, left.counter) = (text "v" >|< @lhs.counter, @lhs.counter+1)

as an abbreviation for = (lhs.pp,lhs.counter)= one can write = lhs.(pp,counter)=

Nonterminal sets:

As the name suggests a nonterminal set is a set of nonterminals. You can use them in ATTR statements and in the new DERIVING statement. A nonterminal set can be given a name using a SET statement:

SET Expression = Expr Term Factor

Whenever you use the set Expression=it is expanded to =Expr Term Factor

You can for example write: ATTR Expression [ | | pp : {PP_DOC} ] instead of ATTR Expr Term Factor [ | | pp : {PP_DOC} ]

Nonterminal sets can be constructed using the following expression syntax:

set ::= conid               -- single nonterminal or named set (5)
      | set set             -- union                           (3)
      | set "/\" set        -- intersection                    (1)
      | set "-"  set        -- difference                      (2)
      | conid "->" conid    -- path                            (4)
      | "(" set ")"         -- grouping                        (5)
      | "*"                 -- all defined nonterminals        (5)
The numbers indicate the operator precedence. A conid is an uppercase identifier. The path operator (from -> to) computes the set of nonterminals that appear on direct paths between "from" and "to". The "to"-nonterminal is included in this set.

The syntax of the new "SET" statement is defined as follows:

statement ::= "SET" conid  "=" set

A nonterminal set can used in an ATTR statement:

statement ::= ATTR set "[" ... "]"
For example:
ATTR Root -> Expr [ env:Environment | | ]
declares an inherited attribute "env" for Expr and all nonterminals between Root and Expr. So the environment is passed from the Root to all expressions in the tree.

Deriving statement

When the AG system encounters a DERIVING statement for a datatype it will emit a "deriving" construct for the generated datatype. The syntax of the DERIVING construct:

statement ::= "DERIVING" set ":" conid ("," conid)*

For example:
DERIVING Types : Ord, Eq
generates deriving (Ord,Eq) at the end of the data definition for Types, and
DERIVING *     : Show
generates deriving (Show) for all data types. When more than one DERIVING statement is given for a single datatype, the union of the sets of classes will be taken. So when both DERIVING constructs above are provided then Ord, Eq, and Show are derived for the datatype Types, and Show for all other data types.

Wrapper statement

The AttributeGrammarSystem has a flag --wrappers to generate wrappers for the semantics of all nonterminals. A disadvantage of this flag is that is has to be provided as a command line argument, and cannot be expressed in the sources. Furthermore the wrapper functions are generated for all nonterminals instead of just the set of root nonterminals. A new statement WRAPPER has been added to address these problems:

statement ::= "WRAPPER" set
Here set stands for the set of nonterminals for which a wrapper function must be generated.

For example:
WRAPPER Root
generates a wrapper for Root, and
WRAPPER Expression Statement
generates wrappers for Expression, and Statement.

Providing the flag --wrappers is equivalent to writing:
WRAPPER *
in your source file.

TYPE synonyms for Maybe and tuple types (March 15, 2005)

The TYPE synonym construct is extended and now in addition to list-type also allows Maybe and tuple types.

Some examples:

TYPE X = MAYBE Int
SEM  X
  | Just lhs.pretty = "Just " ++ show @just
  | Nothing  lhs.pretty = "Nothing"
Note that MAYBE is a keyword and spelled using captials. Its constructors are Just and Nothing. The component in a Just node is named just .

In a tuple type, you can provide names for the components:

TYPE Date      = (day:Int,month:Int,year:Int)

When you omit a name, the name xN will be used, where N is the position of the component. Hence: (Int,Int,Int) is equivalent to (x1:Int,x2:Int,x3:Int)

TYPE Point     = (Int,Int)

As usual TYPE synonyms can be used in other TYPE synonyms, or DATA definitions:

TYPE Polygon   = [Point]
DATA Tree      | Node Point Tree Tree
               | Nil

Attributes can be defined for tuples in the normal way. Note that the constructor of a tuple-type is called Tuple.

ATTR Polygon Date Point [ || pretty : String]

SEM Date
  | Tuple lhs.pretty = show @day ++ "/" ++ show @month ++ "/" ++ show @year

SEM Point
  | Tuple lhs.pretty = "(" ++ show @x1 ++ "," ++ show @x2 ++ ")"

SEM Polygon
  | Cons lhs.pretty = @hd.pretty ++ " " ++ @tl.pretty
  | Nil  lhs.pretty = ""

-- DoaitseSwierstra - 10 May 2007