First cut at reviving the External Core tools
[ghc-hetmet.git] / utils / ext-core / Parser.y
1 {
2 module Parser ( parse ) where
3
4 import Core
5 import ParseGlue
6 import Lex
7
8 }
9
10 %name parse
11 %tokentype { Token }
12
13 %token
14  '%module'      { TKmodule }
15  '%data'        { TKdata }
16  '%newtype'     { TKnewtype }
17  '%forall'      { TKforall }
18  '%rec'         { TKrec }
19  '%let'         { TKlet }
20  '%in'          { TKin }
21  '%case'        { TKcase }
22  '%of'          { TKof }
23  '%cast'        { TKcast }
24  '%note'        { TKnote }
25  '%external'    { TKexternal }
26  '%_'           { TKwild }
27  '('            { TKoparen }
28  ')'            { TKcparen }
29  '{'            { TKobrace }
30  '}'            { TKcbrace }
31  '#'            { TKhash}
32  '='            { TKeq }
33  '::'           { TKcoloncolon }
34  '*'            { TKstar }
35  '->'           { TKrarrow }
36  '\\'           { TKlambda}
37  '@'            { TKat }
38  '.'            { TKdot }
39  ':'            { TKcolon }
40  '?'            { TKquestion}
41  ';'            { TKsemicolon }
42  NAME           { TKname $$ }
43  CNAME          { TKcname $$ }
44  INTEGER        { TKinteger $$ }
45  RATIONAL       { TKrational $$ }
46  STRING         { TKstring $$ }
47  CHAR           { TKchar $$ }
48
49 %monad { P } { thenP } { returnP }
50 %lexer { lexer } { TKEOF }
51
52 %%
53
54 module  :: { Module }
55         : '%module' mname tdefs  vdefgs 
56                 { Module $2 $3 $4 }
57
58 tdefs   :: { [Tdef] }
59         : {- empty -}   {[]}
60         | tdef ';' tdefs        {$1:$3}
61
62 tdef    :: { Tdef }
63         : '%data' qcname tbinds '=' '{' cons1 '}'
64                 { Data $2 $3 $6 }
65         | '%newtype' qcname tbinds trep 
66                 { Newtype $2 $3 $4 }
67
68 trep    :: { Maybe Ty }
69         : {- empty -}   {Nothing}
70         | '=' ty        { Just $2 }
71
72 tbind   :: { Tbind }
73         :  name { ($1,Klifted) }
74         |  '(' name '::' akind ')'
75                 { ($2,$4) }
76
77 tbinds  :: { [Tbind] }
78         : {- empty -}   { [] }
79         | tbind tbinds  { $1:$2 }
80
81
82 vbind   :: { Vbind }
83         : '(' name '::' ty')'   { ($2,$4) }
84
85 vbinds  :: { [Vbind] }
86         : {-empty -}    { [] }
87         | vbind vbinds  { $1:$2 }
88
89 bind    :: { Bind }
90         : '@' tbind     { Tb $2 }
91         | vbind         { Vb $1 }
92
93 binds1  :: { [Bind] }
94         : bind          { [$1] }
95         | bind binds1   { $1:$2 }
96
97 attbinds :: { [Tbind] }
98         : {- empty -}   { [] }
99         | '@' tbind attbinds 
100                         { $2:$3 }
101
102 akind   :: { Kind }
103         : '*'           {Klifted}       
104         | '#'           {Kunlifted}
105         | '?'           {Kopen}
106         | '(' kind ')'  { $2 }
107
108 kind    :: { Kind }
109         : akind         { $1 }
110         | akind '->' kind 
111                 { Karrow $1 $3 }
112
113 cons1   :: { [Cdef] }
114         : con           { [$1] }
115         | con ';' cons1 { $1:$3 }
116
117 con     :: { Cdef }
118         : qcname attbinds atys 
119                 { Constr $1 $2 $3 }
120
121 atys    :: { [Ty] }
122         : {- empty -} { [] }
123         | aty atys      { $1:$2 }
124
125 aty     :: { Ty }
126         : name  { Tvar $1 }
127         | qcname { Tcon $1 }
128         | '(' ty ')' { $2 }
129
130
131 bty     :: { Ty }
132         : aty   { $1 }
133         | bty aty { Tapp $1 $2 }
134
135 ty      :: { Ty }
136         : bty   {$1}
137         | bty '->' ty 
138                 { tArrow $1 $3 }
139         | '%forall' tbinds '.' ty 
140                 { foldr Tforall $4 $2 }
141
142 vdefgs  :: { [Vdefg] }
143         : {- empty -}           { [] }
144         | vdefg ';' vdefgs      {$1:$3 }
145
146 vdefg   :: { Vdefg }
147         : '%rec' '{' vdefs1 '}'
148                        { Rec $3 }
149         |  vdef { Nonrec $1}
150
151 vdefs1  :: { [Vdef] }
152         : vdef          { [$1] }
153         | vdef ';' vdefs1 { $1:$3 }
154
155 vdef    :: { Vdef }
156         : qname '::' ty '=' exp 
157                 { Vdef ($1,$3,$5) }
158
159 aexp    :: { Exp }
160         : qname         { Var $1 }
161         | qcname        { Dcon $1 } 
162         | lit           { Lit $1 }
163         | '(' exp ')'   { $2 }
164
165 fexp    :: { Exp }
166         : fexp aexp     { App $1 $2 }
167         | fexp '@' aty  { Appt $1 $3 }
168         | aexp          { $1 }
169
170 exp     :: { Exp }
171         : fexp          { $1 }
172         | '\\' binds1 '->' exp
173                 { foldr Lam $4 $2 }
174         | '%let' vdefg '%in' exp 
175                 { Let $2 $4 }
176         | '%case' ty aexp '%of' vbind '{' alts1 '}'
177                 { Case $3 $5 $2 $7 }
178         | '%cast' exp aty 
179                 { Cast $2 $3 }
180         | '%note' STRING exp 
181                 { Note $2 $3 }
182         | '%external' STRING aty
183                 { External $2 $3 }
184
185 alts1   :: { [Alt] }
186         : alt           { [$1] }
187         | alt ';' alts1 { $1:$3 }
188
189 alt     :: { Alt }
190         : qcname attbinds vbinds '->' exp 
191                 { Acon $1 $2 $3 $5 } 
192         | lit '->' exp
193                 { Alit $1 $3 }
194         | '%_' '->' exp
195                 { Adefault $3 }
196
197 lit     :: { Lit }
198         : '(' INTEGER '::' aty ')'
199                 { Lint $2 $4 }
200         | '(' RATIONAL '::' aty ')'
201                 { Lrational $2 $4 }
202         | '(' CHAR '::' aty ')'
203                 { Lchar $2 $4 }
204         | '(' STRING '::' aty ')'
205                 { Lstring $2 $4 }
206
207 name    :: { Id }
208         : NAME  { $1 }
209
210 cname   :: { Id }
211         : CNAME { $1 }
212          
213 mname   :: { AnMname }
214         : pkgName ':' mnames '.' name
215              { ($1, $3, $5) }
216
217 pkgName :: { Id }
218         : NAME { $1 }
219
220 mnames :: { [Id] } 
221          : {- empty -} {[]}
222          | name '.' mnames {$1:$3}
223
224 -- it sucks to have to repeat the Maybe-checking twice,
225 -- but otherwise we get reduce/reduce conflicts
226
227 qname   :: { (Mname,Id) }
228         : name { (Nothing, $1) }
229         | mname '.' name 
230                 { (Just $1,$3) }
231
232 qcname  :: { (Mname,Id) }
233         : cname { (Nothing, $1) }
234         | mname '.' cname 
235                 { (Just $1,$3) }
236
237
238 {
239
240 happyError :: P a 
241 happyError s l = failP (show l ++ ": Parse error\n") (take 100 s) l
242
243 }