-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparser.rb
145 lines (120 loc) · 2.72 KB
/
parser.rb
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
require_relative "lexer"
class LambdaTerm
def initialize
end
def to_s
end
def children
end
end
class Variable < LambdaTerm
def initialize value
@value=value
end
def set new_value
@value=new_value
end
def to_s
return @value
end
def children
return []
end
end
class Abstraction < LambdaTerm
def initialize param,lambda_term
@param=param
@lambda_term=lambda_term
end
def to_s
return "( \\ #{@param} . #{@lambda_term} )"
end
def children
return [@param, @lambda_term]
end
def set_lambda_term lambda_term
@lambda_term=lambda_term
end
end
class Application < LambdaTerm
def initialize left_lambda_term,right_lambda_term
@left_lambda_term=left_lambda_term
@right_lambda_term=right_lambda_term
end
def to_s
return "[ #{@left_lambda_term} ] [ #{@right_lambda_term} ]"
end
def children
return [@left_lambda_term, @right_lambda_term]
end
def set_left_lambda_term lambda_term
@left_lambda_term=lambda_term
end
def set_right_lambda_term lambda_term
@right_lambda_term=lambda_term
end
end
class Parser
def initialize code
@code=code
@counter=0
end
def error expected, found
raise "ParserError: Expected #{expected}, found '#{found}' at position #{@counter+1} (1-indexed)"
end
def current_char
@code[@counter]
end
def advance_counter
@counter += 1
end
def get_counter
@counter
end
def expect expectation
if expectation.include? current_char
advance_counter
else
error expectation, current_char
end
end
def variable
term = current_char
expect Token::VARIABLE
return Variable.new term
end
def abstraction
expect Token::LEFT_PAREN
expect Token::LAMBDA
param = variable
expect Token::DOT
body = process
expect Token::RIGHT_PAREN
Abstraction.new param,body
end
def application
expect Token::LEFT_SQUARE
left_lambda_term = process
expect Token::RIGHT_SQUARE
expect Token::LEFT_SQUARE
right_lambda_term = process
expect Token::RIGHT_SQUARE
Application.new left_lambda_term, right_lambda_term
end
def process
c = current_char
case c
when Token::VARIABLE
variable
when Token::LEFT_PAREN
abstraction
when Token::LEFT_SQUARE
application
else
return error "a known symbol", c
end
end
def parse
process
end
end