forked from SeleniumHQ/selenium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
189 lines (154 loc) · 2.89 KB
/
main.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
require 'rake-tasks/crazy_fun/build_grammar'
class OutputType
attr_accessor :name
attr_reader :args
def initialize
@args = {}
end
def push(value)
if value.is_a? NameType
@name = value.to_native
elsif value.is_a? ArgType
@args[value.key] = value.value
end
end
def [](key)
@args[key]
end
def length
@args.length
end
def to_s
str = "#{@name}(\n"
@args.each do |arg|
str << " :#{arg[0]} => "
if arg[1].is_a? Symbol
str << ":#{arg[1]}"
elsif arg[1].is_a? String
str << '"' + arg[1] + '"'
elsif arg[1].is_a? Array
str << "[ "
arg[1].each do |item|
if item.is_a? Symbol
str << ":#{item}"
elsif item.is_a? String
str << '"' + item + '"'
end
str << ", "
end
str << " ]"
end
str << ",\n"
end
str << ")"
str
end
end
class StringType
def initialize
@data = ""
end
def <<(data)
@data << data
end
def to_native
@data
end
end
class SymbolType < StringType
def to_native
@data.to_sym
end
end
class NameType < StringType
end
class ArrayType
def initialize
@ary = []
end
def push(value)
@ary.push value.to_native
end
def to_native
@ary
end
end
class MapEntry
attr_accessor :key
attr_accessor :value
def push(value)
if @read_key
@value = value.to_native
else
@key = value.to_native
@read_key = true
end
end
def to_native
{ @key => @value }
end
end
class MapType
def initialize
@map = {}
end
def push(value)
@map = @map.merge value.to_native
end
def to_native
@map
end
end
class ArgType < MapEntry
end
class BuildFile
attr :type
attr_reader :types
attr_accessor :debug
def initialize
@lhs = []
@types = []
end
def leave
# Get the top of the stack, pop it, then push the old top into the new.
curr = @lhs[-1]
@lhs.pop
if (curr.is_a? OutputType)
@types.push curr
elsif !@lhs[-1].nil?
@lhs[-1].push curr
end
puts "Leaving #{curr}" if @debug
end
def parse_file(file_name)
@file_name = file_name
data = IO.read(file_name)
parse(data)
end
def show_bad_line
line = 1
column = 1
current_line = ""
for n in 0 ... @p
char = @data[n].chr
if char == "\n"
line += 1
column = 1
current_line = ""
else
column += 1
current_line << char
end
end
n += 1
while @data[n] && @data[n].chr != "\n"
current_line << @data[n].chr
n += 1
end
error_msg = "Parse error (#{line}, #{column}) "
error_msg << "in file '#{@file_name}'" unless @file_name.nil?
error_msg << "\n\n"
error_msg << current_line
error_msg
end
end