-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChecker.rb
157 lines (141 loc) · 3.19 KB
/
Checker.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
146
147
148
149
150
151
152
153
154
155
156
157
require_relative 'lexer'
require_relative 'Token'
class Checker
def program?(lex)
return stmts?(lex)
end
def stmts?(lex)
if !lex.has_next || lex.get_token_label==:EOF
return true;
end
arr = Array.new
#first, grab all tokens up to the first semicolon
while lex.has_next && lex.get_token_label!=:EOF
arr << lex.get_next
end
#then, check if arr is a stmt after discarding the semicolon
lex.get_next
return stmt?(arr) && stmts?(lex)
end
def stmt?(arr)
return vexp?(arr) || iexp?(arr) || wexp?(arr)
end
def vexp?(arr)
if(arr[0][0].label!=:VAR)
return false
elsif arr[1][0].label!=:ASSIGN
return false
else return addop?(arr[2..-1])
end
end
def iexp?(arr)
if(arr[0][0].text!='if')
return false
end
#get the tokens between if and then
i=1
while(i<arr.size&&arr[i][0].text!='then')
i+=1
end
if !lexp?(arr[1..i])
return false
end
j=i+1 #skip the then
while(j<arr.size&&arr[j][0].text!='else')
j+=1
end
if !stmts?(new Lexer(arr[i+1..j]))
return false
end
k=i+1 #skip the else
while(k<arr.size&&arr[k][0].text!='end')
k+=1
end
return stmts?(arr[j+1..k])
end
def wexp?(arr)
if(arr[0][0].text!='while')
return false
end
#get the tokens between while and do
i=1
while(i<arr.size&&arr[i][0].text!='do')
i+=1
end
if !lexpr?(arr[1..i-1])
return false
end
j=i+1 #skip the do
while(j<arr.size&&arr[j][0].text!='end')
j+=1
end
return stmts?(arr[i+1..j])
end
def addop?(arr)
i=0
while(i<arr.size)
break if (arr[i][0].text=="+"||arr[i][0].text=="-")
i+=1
end
if !mulop?(arr[0..i-1])
return false
elsif arr.size==i #reached the end of the mulop without finding more to check
return true
else
return addop?(arr[i+1..-1])
end
end
def mulop?(arr)
i=0
while(i<arr.size)
break if (arr[i][0].text=="*"||arr[i][0].text=="/")
i+=1
end
if !factor?(arr[0..i-1])
return false
elsif arr.size==i #reached the end of the mulop without finding more to check
return true
else
return mulop?(arr[i+1..-1])
end
end
def factor?(arr)
if arr[0][0].label==:NUMBERS || arr[0][0].label==:VAR
return true
else
return arr[0][0].label=='('&&arr[-1][0].label==')'&& addop?(arr[1..-2])
end
end
def lexpr?(arr)
i=0
while(i<arr.size)
break if (arr[i][0].text=="and")
i+=1
end
if !lterm?(arr[0..i-1])
return false
elsif arr.size==i #reached the end of the lexpr without finding more to check
return true
else
return lexpr?arr[i+1..-1]
end
end
def lterm?(arr)
if arr[0][0].text=="not"&&lfactor?(arr[1..-1])
return true
else
return lfactor?(arr)
end
end
def lfactor?(arr)
return (arr.size==1&&(arr[0][0].text=="true"||arr[0][0].text=="false"))||relop?(arr)
end
def relop?(arr)
i=0
while(i<arr.size)
break if (arr[i][0].text=="<="|| arr[i][0][0].text=="<"||arr[i][0].text=="=")
i+=1
end
return addop?(arr[0..i-1])&&addop?(arr[i+1..-1])
end
end