ruby-ll 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ module LL
2
+ ##
3
+ # A warning/error generated during the compilation of a grammar.
4
+ #
5
+ class Message
6
+ attr_reader :type, :message, :source_line
7
+
8
+ ##
9
+ # The colours to use for the various message types.
10
+ #
11
+ # @return [Hash]
12
+ #
13
+ COLORS = {
14
+ :error => :red,
15
+ :warning => :yellow
16
+ }
17
+
18
+ ##
19
+ # @param [Symbol] type
20
+ # @param [String] message
21
+ # @param [LL::SourceLine] source_line
22
+ #
23
+ def initialize(type, message, source_line)
24
+ @type = type
25
+ @message = message
26
+ @source_line = source_line
27
+ end
28
+
29
+ ##
30
+ # Returns a String containing details of the message, complete with ANSI
31
+ # colour sequences.
32
+ #
33
+ # @return [String]
34
+ #
35
+ def to_s
36
+ location = ANSI.ansi("#{determine_path}:#{line}:#{column}", :white, :bold)
37
+
38
+ type_label = ANSI.ansi(type.to_s, COLORS[type], :bold)
39
+ msg_line = "#{location}:#{type_label}: #{message}"
40
+
41
+ return "#{msg_line}\n#{source_line.source}\n#{marker}"
42
+ end
43
+
44
+ ##
45
+ # @return [String]
46
+ #
47
+ def inspect
48
+ return "Message(type: #{type.inspect}, message: #{message.inspect}, " \
49
+ "file: #{determine_path.inspect}, line: #{line}, column: #{column})"
50
+ end
51
+
52
+ ##
53
+ # Returns the path to the source of the message. If the path resides in the
54
+ # current working directory (or a child directory) the path is relative,
55
+ # otherwise it's absolute.
56
+ #
57
+ # @return [String]
58
+ #
59
+ def determine_path
60
+ if source_line.file == SourceLine::DEFAULT_FILE
61
+ return source_line.file
62
+ end
63
+
64
+ full_path = File.expand_path(source_line.file)
65
+ pwd = Dir.pwd
66
+
67
+ if full_path.start_with?(pwd)
68
+ from = Pathname.new(full_path)
69
+ to = Pathname.new(pwd)
70
+
71
+ return from.relative_path_from(to).to_s
72
+ else
73
+ return full_path
74
+ end
75
+ end
76
+
77
+ ##
78
+ # @return [Fixnum]
79
+ #
80
+ def line
81
+ return source_line.line
82
+ end
83
+
84
+ ##
85
+ # @return [Fixnum]
86
+ #
87
+ def column
88
+ return source_line.column
89
+ end
90
+
91
+ private
92
+
93
+ ##
94
+ # @return [String]
95
+ #
96
+ def marker
97
+ padding = ' ' * (column - 1)
98
+
99
+ return padding + ANSI.ansi('^', :magenta, :bold)
100
+ end
101
+ end # Message
102
+ end # LL
@@ -0,0 +1,280 @@
1
+ # This file is automatically generated by ruby-ll. Manually changing this file
2
+ # is not recommended as any changes will be lost the next time this parser is
3
+ # re-generated.
4
+
5
+ module LL
6
+ class Parser < LL::Driver
7
+ CONFIG = LL::DriverConfig.new
8
+
9
+ CONFIG.terminals = [
10
+ :$EOF, # 0
11
+ :T_RUBY, # 1
12
+ :T_NAME, # 2
13
+ :T_TERMINALS, # 3
14
+ :T_INNER, # 4
15
+ :T_HEADER, # 5
16
+ :T_IDENT, # 6
17
+ :T_EQUALS, # 7
18
+ :T_COLON, # 8
19
+ :T_PIPE, # 9
20
+ :T_EPSILON, # 10
21
+ :T_SEMICOLON, # 11
22
+ ].freeze
23
+
24
+ CONFIG.rules = [
25
+ [3, 0, 0, 1], # 0
26
+ [3, 1, 2, 0], # 1
27
+ [3, 2, 0, 1, 0, 2], # 2
28
+ [3, 3, 2, 0], # 3
29
+ [3, 4, 0, 18], # 4
30
+ [3, 5, 0, 3], # 5
31
+ [3, 6, 0, 5], # 6
32
+ [3, 7, 0, 6], # 7
33
+ [3, 8, 0, 7], # 8
34
+ [3, 9, 1, 11, 0, 4, 0, 10, 1, 2], # 9
35
+ [3, 10, 0, 4, 0, 10, 1, 8, 1, 8], # 10
36
+ [3, 11, 2, 0], # 11
37
+ [3, 12, 1, 11, 0, 8, 1, 3], # 12
38
+ [3, 13, 0, 15, 1, 4], # 13
39
+ [3, 14, 0, 15, 1, 5], # 14
40
+ [3, 15, 0, 9, 0, 10], # 15
41
+ [3, 16, 0, 8], # 16
42
+ [3, 17, 2, 0], # 17
43
+ [3, 18, 1, 6], # 18
44
+ [3, 19, 0, 8], # 19
45
+ [3, 20, 0, 12], # 20
46
+ [3, 21, 1, 10], # 21
47
+ [3, 22, 0, 14, 0, 11], # 22
48
+ [3, 23, 0, 15], # 23
49
+ [3, 24, 2, 0], # 24
50
+ [3, 25, 1, 1], # 25
51
+ [3, 26, 0, 17, 0, 13], # 26
52
+ [3, 27, 0, 16, 1, 9], # 27
53
+ [3, 28, 2, 0], # 28
54
+ [3, 29, 1, 11, 0, 16, 1, 7, 0, 10], # 29
55
+ ].freeze
56
+
57
+ CONFIG.table = [
58
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 0
59
+ [3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3], # 1
60
+ [-1, -1, 5, 6, 7, 8, 4, -1, -1, -1, -1, -1], # 2
61
+ [-1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 3
62
+ [11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11], # 4
63
+ [-1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1], # 5
64
+ [-1, -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, -1], # 6
65
+ [-1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1], # 7
66
+ [-1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1], # 8
67
+ [17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17], # 9
68
+ [-1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1], # 10
69
+ [-1, -1, -1, -1, -1, -1, 19, -1, -1, -1, 20, -1], # 11
70
+ [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, -1], # 12
71
+ [-1, -1, -1, -1, -1, -1, 22, -1, -1, -1, 22, -1], # 13
72
+ [24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24], # 14
73
+ [-1, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 15
74
+ [-1, -1, -1, -1, -1, -1, 26, -1, -1, -1, 26, -1], # 16
75
+ [28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 28, 28], # 17
76
+ [-1, -1, -1, -1, -1, -1, 29, -1, -1, -1, -1, -1], # 18
77
+ ].freeze
78
+
79
+ CONFIG.actions = [
80
+ [:_rule_0, 1], # 0
81
+ [:_rule_1, 0], # 1
82
+ [:_rule_2, 2], # 2
83
+ [:_rule_3, 0], # 3
84
+ [:_rule_4, 1], # 4
85
+ [:_rule_5, 1], # 5
86
+ [:_rule_6, 1], # 6
87
+ [:_rule_7, 1], # 7
88
+ [:_rule_8, 1], # 8
89
+ [:_rule_9, 4], # 9
90
+ [:_rule_10, 4], # 10
91
+ [:_rule_11, 0], # 11
92
+ [:_rule_12, 3], # 12
93
+ [:_rule_13, 2], # 13
94
+ [:_rule_14, 2], # 14
95
+ [:_rule_15, 2], # 15
96
+ [:_rule_16, 1], # 16
97
+ [:_rule_17, 0], # 17
98
+ [:_rule_18, 1], # 18
99
+ [:_rule_19, 1], # 19
100
+ [:_rule_20, 1], # 20
101
+ [:_rule_21, 1], # 21
102
+ [:_rule_22, 2], # 22
103
+ [:_rule_23, 1], # 23
104
+ [:_rule_24, 0], # 24
105
+ [:_rule_25, 1], # 25
106
+ [:_rule_26, 2], # 26
107
+ [:_rule_27, 2], # 27
108
+ [:_rule_28, 0], # 28
109
+ [:_rule_29, 4], # 29
110
+ ].freeze
111
+
112
+ ##
113
+ # @see [LL::Lexer#initialize]
114
+ #
115
+ def initialize(*args)
116
+ @lexer = Lexer.new(*args)
117
+ end
118
+
119
+ ##
120
+ # @yieldparam [Symbol] type
121
+ # @yieldparam [String] value
122
+ #
123
+ def each_token
124
+ @lexer.advance do |token|
125
+ yield [token.type, token]
126
+ end
127
+
128
+ yield [-1, -1]
129
+ end
130
+
131
+ ##
132
+ # @see [LL::AST::Node#initialize]
133
+ #
134
+ def s(*args)
135
+ return AST::Node.new(*args)
136
+ end
137
+
138
+ def _rule_0(val)
139
+ s(:grammar, val[0])
140
+ end
141
+
142
+ def _rule_1(val)
143
+ s(:grammar)
144
+ end
145
+
146
+ def _rule_2(val)
147
+ val[0] + val[1]
148
+ end
149
+
150
+ def _rule_3(val)
151
+ val
152
+ end
153
+
154
+ def _rule_4(val)
155
+ val
156
+ end
157
+
158
+ def _rule_5(val)
159
+ val
160
+ end
161
+
162
+ def _rule_6(val)
163
+ val
164
+ end
165
+
166
+ def _rule_7(val)
167
+ val
168
+ end
169
+
170
+ def _rule_8(val)
171
+ val
172
+ end
173
+
174
+ def _rule_9(val)
175
+
176
+ s(:name, [val[1], *val[2]], :source_line => val[0].source_line)
177
+
178
+ end
179
+
180
+ def _rule_10(val)
181
+ [val[2]] + val[3]
182
+ end
183
+
184
+ def _rule_11(val)
185
+ val
186
+ end
187
+
188
+ def _rule_12(val)
189
+
190
+ s(:terminals, val[1], :source_line => val[0].source_line)
191
+
192
+ end
193
+
194
+ def _rule_13(val)
195
+
196
+ s(:inner, [val[1]], :source_line => val[0].source_line)
197
+
198
+ end
199
+
200
+ def _rule_14(val)
201
+
202
+ s(:header, [val[1]], :source_line => val[0].source_line)
203
+
204
+ end
205
+
206
+ def _rule_15(val)
207
+ [val[0]] + val[1]
208
+ end
209
+
210
+ def _rule_16(val)
211
+ val[0]
212
+ end
213
+
214
+ def _rule_17(val)
215
+ val
216
+ end
217
+
218
+ def _rule_18(val)
219
+
220
+ s(:ident, [val[0].value], :source_line => val[0].source_line)
221
+
222
+ end
223
+
224
+ def _rule_19(val)
225
+
226
+ s(:steps, val[0], :source_line => val[0][0].source_line)
227
+
228
+ end
229
+
230
+ def _rule_20(val)
231
+
232
+ s(:steps, [val[0]], :source_line => val[0].source_line)
233
+
234
+ end
235
+
236
+ def _rule_21(val)
237
+ s(:epsilon, [], :source_line => val[0].source_line)
238
+ end
239
+
240
+ def _rule_22(val)
241
+
242
+ steps = [val[0]]
243
+
244
+ steps << val[1] if val[1]
245
+
246
+ s(:branch, steps, :source_line => val[0].source_line)
247
+
248
+ end
249
+
250
+ def _rule_23(val)
251
+ val[0]
252
+ end
253
+
254
+ def _rule_24(val)
255
+ nil
256
+ end
257
+
258
+ def _rule_25(val)
259
+ s(:ruby, [val[0].value], :source_line => val[0].source_line)
260
+ end
261
+
262
+ def _rule_26(val)
263
+ [val[0]] + val[1]
264
+ end
265
+
266
+ def _rule_27(val)
267
+ val[1]
268
+ end
269
+
270
+ def _rule_28(val)
271
+ val
272
+ end
273
+
274
+ def _rule_29(val)
275
+
276
+ s(:rule, [val[0], *val[2]], :source_line => val[0].source_line)
277
+
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,8 @@
1
+ module LL
2
+ ##
3
+ # Generic error class for parsing errors (syntax errors, etc).
4
+ #
5
+ class ParserError < StandardError
6
+
7
+ end # ParserError
8
+ end # LL
@@ -0,0 +1,53 @@
1
+ module LL
2
+ ##
3
+ # Class containing details of a single rule in a grammar.
4
+ #
5
+ class Rule
6
+ attr_reader :name, :branches, :source_line, :references
7
+
8
+ ##
9
+ # @param [String] name
10
+ # @param [LL::SourceLine] source_line
11
+ #
12
+ def initialize(name, source_line)
13
+ @name = name
14
+ @branches = []
15
+ @source_line = source_line
16
+ @references = 0
17
+ end
18
+
19
+ ##
20
+ # @see [LL::Branch#initialize]
21
+ #
22
+ def add_branch(steps, source_line, ruby_code = nil)
23
+ branches << Branch.new(steps, source_line, ruby_code)
24
+ end
25
+
26
+ def increment_references
27
+ @references += 1
28
+ end
29
+
30
+ ##
31
+ # Returns an Array containing the terminals that make up the FIRST() set of
32
+ # this rule.
33
+ #
34
+ # @return [Array<LL::Terminal>]
35
+ #
36
+ def first_set
37
+ terminals = []
38
+
39
+ branches.each do |branch|
40
+ terminals += branch.first_set
41
+ end
42
+
43
+ return terminals
44
+ end
45
+
46
+ ##
47
+ # @return [String]
48
+ #
49
+ def inspect
50
+ return "Rule(name: #{name.inspect}, branches: #{branches.inspect})"
51
+ end
52
+ end # Rule
53
+ end # LL
@@ -0,0 +1,11 @@
1
+ require_relative 'version'
2
+ require_relative 'driver'
3
+ require_relative 'driver_config'
4
+ require_relative 'parser_error'
5
+ require_relative '../libll'
6
+
7
+ #:nocov:
8
+ if RUBY_PLATFORM == 'java'
9
+ org.libll.Libll.load(JRuby.runtime)
10
+ end
11
+ #:nocov: