[Haskell-beginners] Attribute Grammar and Type signature with
Happy
Stephen Tetley
stephen.tetley at gmail.com
Thu May 27 16:08:35 EDT 2010
Hello Julien
I've worked out type signatures below for both examples in the Happy
docs. I'm afraid, I've no idea what what the type signatures actually
mean, I worked them out simply by hacking.
I'd rather suggest the AG system within Happy is best avoided, as it
seems like a proof of concept that didn't get fleshed out. UUAG I
would highly recommend - its a well maintained and documented AG
system for Haskell, that has been used for real compilers (Helium,
UHC/EHC).
{
module ABCParser where
}
%tokentype { Char }
%token a { 'a' }
%token b { 'b' }
%token c { 'c' }
%token newline { '\n' }
%attributetype { Attrs a }
%attribute value { a }
%attribute len { Int }
%name parse abcstring
%%
abcstring :: { Attrs [()] -> ([()], Attrs [Char]) }
abcstring
: alist blist clist newline
{ $$ = $1 ++ $2 ++ $3
; $2.len = $1.len
; $3.len = $1.len
}
alist :: { Attrs [()] -> ([()], Attrs [Char]) }
alist
: a alist
{ $$ = $1 : $2
; $$.len = $2.len + 1
}
| { $$ = []; $$.len = 0 }
blist :: { Attrs [()] -> ([()], Attrs [Char]) }
blist
: b blist
{ $$ = $1 : $2
; $2.len = $$.len - 1
}
| { $$ = []
; where failUnless ($$.len == 0) "blist wrong length"
}
clist :: { Attrs [()] -> ([()], Attrs [Char]) }
clist
: c clist
{ $$ = $1 : $2
; $2.len = $$.len - 1
}
| { $$ = []
; where failUnless ($$.len == 0) "clist wrong length"
}
{
happyError = error "parse error"
failUnless b msg = if b then () else error msg
}
-------------------------------
{
module BitsParser (parse) where
}
%tokentype { Char }
%token minus { '-' }
%token plus { '+' }
%token one { '1' }
%token zero { '0' }
%token newline { '\n' }
%attributetype { Attrs }
%attribute value { Integer }
%attribute pos { Int }
%name parse start
%%
start :: { Attrs -> ([()],Attrs) }
start
: num newline { $$ = $1 }
num :: { Attrs -> ([()],Attrs) }
num
: bits { $$ = $1 ; $1.pos = 0 }
| plus bits { $$ = $2 ; $2.pos = 0 }
| minus bits { $$ = negate $2; $2.pos = 0 }
bits :: { Attrs -> ([()],Attrs) }
bits
: bit { $$ = $1
; $1.pos = $$.pos
}
| bits bit { $$ = $1 + $2
; $1.pos = $$.pos + 1
; $2.pos = $$.pos
}
bit :: { Attrs -> ([()],Attrs) }
bit
: zero { $$ = 0 }
| one { $$ = 2^($$.pos) }
{
happyError = error "parse error"
}
More information about the Beginners
mailing list