-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.rb
133 lines (122 loc) · 4.16 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
require "./token"
require "./lexer"
require "./func"
require "./variable"
class Parser
AdditiveOperator = [Token::Plus, Token::Minus]
MultiplitiveOperator = [Token::Multiply, Token::Devide]
ModuloOperator = [Token::Modulo, Token::Power]
BooleanOperator = [Token::Equal, Token::Greater, Token::Less]
def initialize
@var_mng = VariableManager.new
@func_mng = FunctionManager.new
end
def parse(input)
@lexer = Lexer.new(input)
first_token = @lexer.next_token()
if first_token.kind == Token::Variable
var_name = first_token.name
if @lexer.next_token().kind == Token::Assign
return @var_mng.set_name(var_name, operator_add())
end
elsif first_token.kind == Token::If
if operator_boolean()
raise "Parse Error" if @lexer.next_token().kind != Token::Then
ret = operator_add()
raise "Parse Error" if @lexer.next_token().kind != Token::Else
return ret
else
raise "Parse Error" if @lexer.next_token().kind != Token::Then
skip_while_else()
return operator_add()
end
elsif first_token.kind == Token::Defun
expected_func = @lexer.next_token()
raise "parse Error" if expected_func.kind != Token::Function
func_name = expected_func.name
expected_var = @lexer.next_token()
raise "parse Error" if expected_var.kind != Token::Variable
var_name = expected_var.name
raise "parse Error" if @lexer.next_token().kind != Token::RightParen
@func_mng.add_name(expected_func.name, expected_var.name, @lexer.get_rest_all)
return
end
@lexer.reset()
operator_add()
end
def skip_while_else
token_kind = @lexer.next_token.kind
while token_kind != Token::Else && token_kind != Token::EndLine
token_kind = @lexer.next_token.kind
end
raise "Parse Error" if token_kind == Token::EndLine
end
def operator_boolean()
num1 = operator_add()
operator = @lexer.next_token().kind
num2 = operator_add()
if operator == Token::Equal
return num1 == num2
elsif operator == Token::Greater
return num1 > num2
elsif operator == Token::Less
return num1 < num2
else
raise "Parse error"
end
end
def operator_add
ret = operator_mul()
while AdditiveOperator.include?(operator = @lexer.next_token().kind)
if operator == Token::Plus
ret += operator_mul()
else
ret -= operator_mul()
end
end
@lexer.revert
return ret
end
def operator_mul
ret = operator_pow()
while MultiplitiveOperator.include?(operator = @lexer.next_token().kind)
if operator == Token::Multiply
ret *= operator_pow()
else
ret /= operator_pow()
end
end
@lexer.revert
return ret
end
def operator_pow
ret = number()
while ModuloOperator.include?(operator = @lexer.next_token().kind)
if operator == Token::Modulo
ret = ret % number()
else
ret = ret ** number()
end
end
@lexer.revert
return ret
end
def number
ret = @lexer.next_token()
if ret.kind == Token::Number
return ret.value
elsif ret.kind == Token::LeftParen
ret = operator_add()
raise "Parse Error" if @lexer.next_token().kind != Token::RightParen
return ret
elsif ret.kind == Token::Variable
return @var_mng.get_name(ret.name)
elsif ret.kind == Token::Function
ret = @func_mng.get_name(ret.name, operator_add())
raise "Parse Error" if @lexer.next_token().kind != Token::RightParen
return ret
else
raise "Parse b Error"
end
end
end