-
Notifications
You must be signed in to change notification settings - Fork 82
/
tiny.y
69 lines (56 loc) · 1.37 KB
/
tiny.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
-- An example demonstrating how to connect a Happy parser to an Alex lexer.
{
import Tokens_posn
}
%name calc
%tokentype { Token }
%token let { Let _ }
in { In _ }
int { Int _ $$ }
var { Var _ $$ }
'=' { Sym _ '=' }
'+' { Sym _ '+' }
'-' { Sym _ '-' }
'*' { Sym _ '*' }
'/' { Sym _ '/' }
'(' { Sym _ '(' }
')' { Sym _ ')' }
%%
Exp :: { Exp }
Exp : let var '=' Exp in Exp { LetE $2 $4 $6 }
| Exp1 { $1 }
Exp1 : Exp1 '+' Term { PlusE $1 $3 }
| Exp1 '-' Term { MinusE $1 $3 }
| Term { $1 }
Term : Term '*' Factor { TimesE $1 $3 }
| Term '/' Factor { DivE $1 $3 }
| Factor { $1 }
Factor : '-' Atom { NegE $2 }
| Atom { $1 }
Atom : int { IntE $1 }
| var { VarE $1 }
| '(' Exp ')' { $2 }
{
data Exp =
LetE String Exp Exp |
PlusE Exp Exp |
MinusE Exp Exp |
TimesE Exp Exp |
DivE Exp Exp |
NegE Exp |
IntE Int |
VarE String
deriving Show
main:: IO ()
main = interact (show.runCalc)
runCalc :: String -> Exp
runCalc = calc . alexScanTokens
happyError :: [Token] -> a
happyError tks = error ("Parse error at " ++ lcn ++ "\n")
where
lcn = case tks of
[] -> "end of file"
tk:_ -> "line " ++ show l ++ ", column " ++ show c
where
AlexPn _ l c = token_posn tk
}