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