]> ruin.nu Git - proglang.git/blob - Parsyntax.y
minor change
[proglang.git] / Parsyntax.y
1 -- This Happy file was machine-generated by the BNF converter
2 {
3 module Parsyntax where
4 import Abssyntax
5 import Lexsyntax
6 import ErrM
7 }
8
9 %name pProgram Program
10
11 -- no lexer declaration
12 %monad { Err } { thenM } { returnM }
13 %tokentype { Token }
14
15 %token 
16  ';' { PT _ (TS ";") }
17  '{' { PT _ (TS "{") }
18  '}' { PT _ (TS "}") }
19  '=' { PT _ (TS "=") }
20  '(' { PT _ (TS "(") }
21  ')' { PT _ (TS ")") }
22  '++' { PT _ (TS "++") }
23  '--' { PT _ (TS "--") }
24  '-' { PT _ (TS "-") }
25  '!' { PT _ (TS "!") }
26  ',' { PT _ (TS ",") }
27  '<' { PT _ (TS "<") }
28  '<=' { PT _ (TS "<=") }
29  '>' { PT _ (TS ">") }
30  '>=' { PT _ (TS ">=") }
31  '==' { PT _ (TS "==") }
32  '!=' { PT _ (TS "!=") }
33  '+' { PT _ (TS "+") }
34  '*' { PT _ (TS "*") }
35  '/' { PT _ (TS "/") }
36  'bool' { PT _ (TS "bool") }
37  'else' { PT _ (TS "else") }
38  'false' { PT _ (TS "false") }
39  'if' { PT _ (TS "if") }
40  'int' { PT _ (TS "int") }
41  'print' { PT _ (TS "print") }
42  'readBool' { PT _ (TS "readBool") }
43  'readInt' { PT _ (TS "readInt") }
44  'return' { PT _ (TS "return") }
45  'true' { PT _ (TS "true") }
46  'while' { PT _ (TS "while") }
47
48 L_ident  { PT _ (TV $$) }
49 L_integ  { PT _ (TI $$) }
50 L_err    { _ }
51
52
53 %%
54
55 Ident   :: { Ident }   : L_ident  { Ident $1 }
56 Integer :: { Integer } : L_integ  { (read $1) :: Integer }
57
58 Bool :: { Bool }
59 Bool : 'true' { True } 
60   | 'false' { False }
61
62
63 Type :: { Type }
64 Type : 'int' { TInt } 
65   | 'bool' { TBool }
66
67
68 Program :: { Program }
69 Program : ListFuncStm { Program (reverse $1) } 
70
71
72 Stm :: { Stm }
73 Stm : Exp ';' { SExp $1 } 
74   | '{' ListStm '}' { SBlock (reverse $2) }
75   | Type Ident '=' Exp ';' { SDecl $1 $2 $4 }
76   | Type Ident ';' { SDeclD $1 $2 }
77   | 'while' '(' Exp ')' Stm { SWhile $3 $5 }
78   | 'if' '(' Exp ')' Stm 'else' Stm { SIf $3 $5 $7 }
79   | 'if' '(' Exp ')' Stm { if_ $3 $5 }
80   | 'print' Exp ';' { SPrint $2 }
81   | 'return' Exp ';' { SReturn $2 }
82
83
84 Exp :: { Exp }
85 Exp : Ident '=' Exp { EAss $1 $3 } 
86   | Exp1 Op0 Exp1 { compExp_ $1 $2 $3 }
87   | Exp1 { $1 }
88
89
90 Exp1 :: { Exp }
91 Exp1 : Exp1 Op1 Exp2 { op1_ $1 $2 $3 } 
92   | Exp2 { $1 }
93
94
95 Exp2 :: { Exp }
96 Exp2 : Exp2 Op2 Exp3 { op2_ $1 $2 $3 } 
97   | Exp3 { $1 }
98
99
100 Exp3 :: { Exp }
101 Exp3 : Ident '++' { postIncr_ $1 } 
102   | Ident '--' { postDecr_ $1 }
103   | Ident { EVar $1 }
104   | Integer { EInt $1 }
105   | Bool { EBool $1 }
106   | '-' Exp3 { ENeg $2 }
107   | '!' Exp3 { ENot $2 }
108   | 'readInt' { EReadI }
109   | 'readBool' { EReadB }
110   | Ident '(' ListExp ')' { EFunc $1 $3 }
111   | '(' Exp ')' { $2 }
112
113
114 ListStm :: { [Stm] }
115 ListStm : {- empty -} { [] } 
116   | ListStm Stm { flip (:) $1 $2 }
117
118
119 ListExp :: { [Exp] }
120 ListExp : {- empty -} { [] } 
121   | Exp { (:[]) $1 }
122   | Exp ',' ListExp { (:) $1 $3 }
123
124
125 Decl :: { Decl }
126 Decl : Type Ident { Decl $1 $2 } 
127
128
129 ListDecl :: { [Decl] }
130 ListDecl : {- empty -} { [] } 
131   | Decl { (:[]) $1 }
132   | Decl ',' ListDecl { (:) $1 $3 }
133
134
135 Func :: { Func }
136 Func : Type Ident '(' ListDecl ')' '{' ListStm '}' { Func $1 $2 $4 (reverse $7) } 
137
138
139 ListFunc :: { [Func] }
140 ListFunc : {- empty -} { [] } 
141   | ListFunc Func { flip (:) $1 $2 }
142
143
144 FuncStm :: { FuncStm }
145 FuncStm : Stm { S $1 } 
146   | Func { F $1 }
147
148
149 ListFuncStm :: { [FuncStm] }
150 ListFuncStm : {- empty -} { [] } 
151   | ListFuncStm FuncStm { flip (:) $1 $2 }
152
153
154 Op0 :: { Op }
155 Op0 : '<' { Lt } 
156   | '<=' { ELt }
157   | '>' { Gt }
158   | '>=' { EGt }
159   | '==' { Eq }
160   | '!=' { NEq }
161
162
163 Op1 :: { Op }
164 Op1 : '+' { Plus } 
165   | '-' { Minus }
166
167
168 Op2 :: { Op }
169 Op2 : '*' { Times } 
170   | '/' { Div }
171
172
173 Op :: { Op }
174 Op : Op1 { $1 } 
175   | Op2 { $1 }
176   | Op0 { $1 }
177
178
179
180 {
181
182 returnM :: a -> Err a
183 returnM = return
184
185 thenM :: Err a -> (a -> Err b) -> Err b
186 thenM = (>>=)
187
188 happyError :: [Token] -> Err a
189 happyError ts =
190   Bad $ "syntax error at " ++ tokenPos ts ++ if null ts then [] else (" before " ++ unwords (map prToken (take 4 ts)))
191
192 myLexer = tokens
193 if_ e_ s_ = SIf e_ s_ SNoop
194 compExp_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
195 op1_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
196 op2_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
197 postIncr_ i_ = EPost i_ Plus
198 postDecr_ i_ = EPost i_ Minus
199 }
200