-
Notifications
You must be signed in to change notification settings - Fork 0
/
Grammar.y
117 lines (98 loc) · 2.45 KB
/
Grammar.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
{
module Parser (Exp(..), AppExp(..), Value(..), Var(..), parse, parseFromFile) where
import Scanner
}
%name parse
%tokentype {Scanner.Token}
%error { parseError }
%token
'(' {S_Lparen}
'\\' {S_Bslash}
'.' {S_Period}
')' {S_Rparen}
'+' {S_Plus}
'-' {S_Minus}
if {S_If}
then {S_Then}
else {S_Else}
dig {S_Int $$}
var {S_Var $$}
fix {S_Fix}
%%
Exp
: AppExp '+' Exp {Plus $1 $3}
| AppExp '-' Exp {Minus $1 $3}
| if AppExp then Exp else Exp {If $2 $4 $6}
| fix AppExp {Fix $2}
| AppExp {AppExp $1}
AppExp
: Val AppExp {AppV $1 $2}
| '(' Exp ')' AppExp {AppE $2 $4}
| '(' Exp ')' {Nest $2}
| Val {Value $1}
Val
: dig {Int $1}
| Var {Variable $1}
| Lam {$1}
Lam
: '(' '\\' Var '.' Exp ')' {Lam $3 $5}
Var
: var {Var $1}
{
parseError :: [Token] -> a
parseError _ = error "Parse Error"
data Exp =
Plus AppExp Exp
| Minus AppExp Exp
| If AppExp Exp Exp
| Fix AppExp
| AppExp AppExp
instance Show Exp where
show (Plus ae e) = let strAe = show ae
strE = show e
in strAe ++ " + " ++ strE
show (Minus ae e) = let strAe = show ae
strE = show e
in strAe ++ " - " ++ strE
show (If ae et ee) = let strAe = show ae
strEt = show et
strEe = show ee
in "if " ++ strAe ++ " then " ++ strEt ++ " else " ++ strEe
show (Fix ae) = let strAe = show ae
in "fix " ++ strAe
show (AppExp ae) = show ae
data AppExp =
AppV Value AppExp
| AppE Exp AppExp
| Nest Exp
| Value Value
instance Show AppExp where
show (AppV v ae) = let strV = show v
strAe = show ae
in strV ++ " " ++ strAe
show (AppE e ae) = let strE = show e
strAe = show ae
in strE ++ " " ++ strAe
show (Nest e) = let strE = show e
in "(" ++ strE ++ ")"
show (Value v) = show v
data Var =
Var Char
deriving Eq
instance Show Var where
show (Var c) = c:""
data Value =
Int Int
| Lam Var Exp
| Variable Var
instance Show Value where
show (Int i) = show i
show (Lam v e) = let strV = show v
strE = show e
in "(\\" ++ strV ++ ". " ++ strE ++ ")"
show (Variable v) = show v
parseFromFile fil =
do
toks <- Scanner.lexFromFile fil
return (parse toks)
}