ruby-ll 1.1.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a058e52fdce3a69cfacb367d31f25d9322b09d3a
4
- data.tar.gz: 66c890ff03310a459735f8c14d2a452f4415e550
3
+ metadata.gz: c5d66bcacfb96b5c530ea468c1e6f9cc74a3d916
4
+ data.tar.gz: 4eba99c6eb0c02fd4945cc2767ec5487cd93b7d2
5
5
  SHA512:
6
- metadata.gz: b2635328c10c6b8a4c9570e997a2e9ecd0536fa767b03b62306f0eb9285c984e6b68b22bb1519164c1cef5c4a12cc3c2f3537f7aefc874464c2d4834b36edea2
7
- data.tar.gz: 8dfcc7a62283212ff857fd2ff2b33b68f78b2ee095021975900ddbd55f7abf7fc7795cd9a4081c2109a8e72b17cd21d9924c93b7a29daf9d5fcf77844cfca109
6
+ metadata.gz: 885e11cf3cfcb3f42644fbd4d0e79e34dbb5c9939e0916728517ba283a07b61b0f0dfaf6734285e112aa499aab4928a64b1fc14eecc2460139658e958542a6ee
7
+ data.tar.gz: 1f15f04b4abd4e573e12334e1db627ca899e24d91be250c048294e5503212a7eca375133723108732f07df7f7c8243f8beb665400cbe5a18669995fa1faf0841
data/README.md CHANGED
@@ -278,8 +278,30 @@ return specific elements from it:
278
278
  numbers = A B { val[0] };
279
279
 
280
280
  Values returned by code blocks are passed to whatever other rule called it. This
281
- allows code blocks to be used for building ASTs and the likes. If no explicit
282
- code block is defined `val` is returned as is.
281
+ allows code blocks to be used for building ASTs and the likes.
282
+
283
+ If no explicit code block is defined then ruby-ll will generate one for you. If
284
+ a branch consists out of only a single step (e.g. `A = B;`) then only the first
285
+ value is returned, otherwise all values are returned.
286
+
287
+ This means that in the following example the output will be whatever value "C"
288
+ contains:
289
+
290
+ A = B { p val[0] };
291
+ B = C;
292
+
293
+ However, here the output would be `[C, D]` as the `B` rule's branch contains
294
+ multiple steps:
295
+
296
+ A = B { p val[0] };
297
+ B = C D;
298
+
299
+ To summarize (`# =>` denotes the return value):
300
+
301
+ A = B; # => B
302
+ A = B C; # => [B, C]
303
+
304
+ You can override this behaviour simply by defining your own code block.
283
305
 
284
306
  ruby-ll parsers recurse into rules before unwinding, this means that the
285
307
  inner-most rule is processed first.
@@ -301,6 +323,50 @@ name as a terminal, as such the following is invalid:
301
323
 
302
324
  It's also an error to re-define an existing rule.
303
325
 
326
+ ### Operators
327
+
328
+ Grammars can use two operators to define a sequence of terminals/non-terminals:
329
+ the star (`*`) and plus (`+`) operators.
330
+
331
+ The star operator indicates that something should occur 0 or more times. Here
332
+ the "B" identifier could occur 0 times, once, twice or many more times:
333
+
334
+ A = B*;
335
+
336
+ The plus operator indicates that something should occur at least once followed
337
+ by any number of more occurrences. For example, this grammar states that "B"
338
+ should occur at least once but can also occur, say, 10 times:
339
+
340
+ A = B+;
341
+
342
+ Operators can be applied either to a single terminal/rule or a series of
343
+ terminals/rules grouped together using parenthesis. For example, both are
344
+ perfectly valid:
345
+
346
+ A = B+;
347
+ A = (B C)+;
348
+
349
+ When calling an operator on a single terminal/rule the corresponding entry in
350
+ the `val` array is simply set to the terminal/rule value. For example:
351
+
352
+ A = B+ { p val[0] };
353
+
354
+ For input `B B B` this would output `[B, B, B]`.
355
+
356
+ However, when grouping multiple terminals/rules using parenthesis every
357
+ occurrence is wrapped in an Array. For example:
358
+
359
+ A = (B C)+ { p val[0] };
360
+
361
+ For input `B C B C` this would output `[[B, C], [B, C]]`. To work around this
362
+ you can simply move the group of identifiers to its own rule and only return
363
+ whatever you need:
364
+
365
+ A = A1+ { p val[0] };
366
+ A1 = B C { val[0] }; # only return "B"
367
+
368
+ For input `B C B C` this would output `[B, B]`.
369
+
304
370
  ## Conflicts
305
371
 
306
372
  LL(1) grammars can have two kinds of conflicts in a rule:
@@ -0,0 +1,32 @@
1
+ # Driver Architecture
2
+
3
+ The actual parsing of input is handled by a so called "driver" represented as
4
+ the class `LL::Driver`. This class is written in either C or Java depending on
5
+ the Ruby platform that's being used. The rationale for this is simple:
6
+ performance. While Ruby is a great language it's sadly not fast enough to handle
7
+ parsing of large inputs in a way that doesn't either require lots of memory,
8
+ time or both.
9
+
10
+ Both the C and Java drivers try to use native data structures as much as
11
+ possible instead of using Ruby structures. For example, their internal parsing
12
+ stacks are native stacks. In case of Java this is an ArrayDeque, in case of C
13
+ this is a vector created using the [kvec][kvec] library as C doesn't have a
14
+ native vector structure.
15
+
16
+ The driver operates by iterating over every token supplied by the `each_token`
17
+ method (this method must be defined by a parser itself). For every input token a
18
+ callback function in C/Java is executed that determines what to parse and how to
19
+ parse it.
20
+
21
+ The parsing process largely operates on integers, only using Ruby objects where
22
+ absolutely required. For example, all steps of a rule's branch are represented
23
+ as integers. Lookup tables are also simply arrays of integers with terminals
24
+ being mapped directly to the indexes of these arrays. See ruby-ll's own parser
25
+ for examples. Note that the integers for the `rules` Array are in reverse order,
26
+ so everything that comes first is processed last.
27
+
28
+ For more information on the internals its best to refer to the C driver code
29
+ located in `ext/c/driver.c`. The Java code is largely based on this code safe
30
+ for some code comments here and there.
31
+
32
+ [kvec]: https://github.com/attractivechaos/klib/blob/master/kvec.h
data/ext/c/driver.c CHANGED
@@ -5,6 +5,10 @@
5
5
  #define T_TERMINAL 1
6
6
  #define T_EPSILON 2
7
7
  #define T_ACTION 3
8
+ #define T_STAR 4
9
+ #define T_PLUS 5
10
+ #define T_ADD_VALUE_STACK 6
11
+ #define T_APPEND_VALUE_STACK 7
8
12
 
9
13
  ID id_config_const;
10
14
  ID id_each_token;
@@ -66,6 +70,8 @@ VALUE ll_driver_each_token(VALUE token, VALUE self)
66
70
  VALUE method;
67
71
  VALUE action_args;
68
72
  VALUE action_retval;
73
+ VALUE operator_buffer;
74
+ VALUE last_value;
69
75
  long num_args;
70
76
  long args_i;
71
77
 
@@ -113,8 +119,8 @@ VALUE ll_driver_each_token(VALUE token, VALUE self)
113
119
  }
114
120
  }
115
121
 
116
- /* Rule */
117
- if ( stack_type == T_RULE )
122
+ /* A rule or the "+" operator */
123
+ if ( stack_type == T_RULE || stack_type == T_PLUS )
118
124
  {
119
125
  production_i = state->config->table[stack_value][token_id];
120
126
 
@@ -132,6 +138,19 @@ VALUE ll_driver_each_token(VALUE token, VALUE self)
132
138
  }
133
139
  else
134
140
  {
141
+ /*
142
+ Append a "*" operator for all following occurrences as they are
143
+ optional
144
+ */
145
+ if ( stack_type == T_PLUS )
146
+ {
147
+ kv_push(long, state->stack, T_STAR);
148
+ kv_push(long, state->stack, stack_value);
149
+
150
+ kv_push(long, state->stack, T_APPEND_VALUE_STACK);
151
+ kv_push(long, state->stack, 0);
152
+ }
153
+
135
154
  FOR(rule_i, state->config->rule_lengths[production_i])
136
155
  {
137
156
  kv_push(
@@ -142,6 +161,56 @@ VALUE ll_driver_each_token(VALUE token, VALUE self)
142
161
  }
143
162
  }
144
163
  }
164
+ /* "*" operator */
165
+ else if ( stack_type == T_STAR )
166
+ {
167
+ production_i = state->config->table[stack_value][token_id];
168
+
169
+ if ( production_i != T_EOF )
170
+ {
171
+ kv_push(long, state->stack, T_STAR);
172
+ kv_push(long, state->stack, stack_value);
173
+
174
+ kv_push(long, state->stack, T_APPEND_VALUE_STACK);
175
+ kv_push(long, state->stack, 0);
176
+
177
+ FOR(rule_i, state->config->rule_lengths[production_i])
178
+ {
179
+ kv_push(
180
+ long,
181
+ state->stack,
182
+ state->config->rules[production_i][rule_i]
183
+ );
184
+ }
185
+ }
186
+ }
187
+ /*
188
+ Adds a new array to the value stack that can be used to group operator
189
+ values together
190
+ */
191
+ else if ( stack_type == T_ADD_VALUE_STACK )
192
+ {
193
+ operator_buffer = rb_ary_new();
194
+
195
+ kv_push(VALUE, state->value_stack, operator_buffer);
196
+
197
+ RB_GC_GUARD(operator_buffer);
198
+ }
199
+ /*
200
+ Appends the last value on the value stack to the operator buffer that
201
+ preceeds it.
202
+ */
203
+ else if ( stack_type == T_APPEND_VALUE_STACK )
204
+ {
205
+ last_value = kv_pop(state->value_stack);
206
+
207
+ operator_buffer = kv_A(
208
+ state->value_stack,
209
+ kv_size(state->value_stack) - 1
210
+ );
211
+
212
+ rb_ary_push(operator_buffer, last_value);
213
+ }
145
214
  /* Terminal */
146
215
  else if ( stack_type == T_TERMINAL )
147
216
  {
@@ -166,7 +166,7 @@ VALUE ll_driver_config_set_actions(VALUE self, VALUE array)
166
166
 
167
167
  Data_Get_Struct(self, DriverConfig, config);
168
168
 
169
- config->action_names = ALLOC_N(ID, row_count);
169
+ config->action_names = ALLOC_N(VALUE, row_count);
170
170
  config->action_arg_amounts = ALLOC_N(long, row_count);
171
171
 
172
172
  FOR(rindex, row_count)
@@ -30,7 +30,7 @@ typedef struct
30
30
  long **table;
31
31
 
32
32
  /* Array containing action names as Symbols */
33
- ID *action_names;
33
+ VALUE *action_names;
34
34
 
35
35
  /* Array containing the arity for every action */
36
36
  long *action_arg_amounts;
@@ -27,11 +27,15 @@ import org.jruby.runtime.builtin.IRubyObject;
27
27
  @JRubyClass(name="LL::Driver", parent="Object")
28
28
  public class Driver extends RubyObject
29
29
  {
30
- private static long T_EOF = -1;
31
- private static long T_RULE = 0;
32
- private static long T_TERMINAL = 1;
33
- private static long T_EPSILON = 2;
34
- private static long T_ACTION = 3;
30
+ private static long T_EOF = -1;
31
+ private static long T_RULE = 0;
32
+ private static long T_TERMINAL = 1;
33
+ private static long T_EPSILON = 2;
34
+ private static long T_ACTION = 3;
35
+ private static long T_STAR = 4;
36
+ private static long T_PLUS = 5;
37
+ private static long T_ADD_VALUE_STACK = 6;
38
+ private static long T_APPEND_VALUE_STACK = 7;
35
39
 
36
40
  /**
37
41
  * The current Ruby runtime.
@@ -132,8 +136,8 @@ public class Driver extends RubyObject
132
136
  token_id = self.config.terminals.get(type);
133
137
  }
134
138
 
135
- // Rule
136
- if ( stack_type == self.T_RULE )
139
+ // A rule or the "+" operator
140
+ if ( stack_type == self.T_RULE || stack_type == self.T_PLUS )
137
141
  {
138
142
  Long production_i = self.config.table
139
143
  .get(stack_value.intValue())
@@ -152,6 +156,17 @@ public class Driver extends RubyObject
152
156
  }
153
157
  else
154
158
  {
159
+ // Append a "*" operator for all following
160
+ // occurrences as they are optional
161
+ if ( stack_type == self.T_PLUS )
162
+ {
163
+ stack.push(self.T_STAR);
164
+ stack.push(stack_value);
165
+
166
+ stack.push(self.T_APPEND_VALUE_STACK);
167
+ stack.push(Long.valueOf(0));
168
+ }
169
+
155
170
  ArrayList<Long> row = self.config.rules
156
171
  .get(production_i.intValue());
157
172
 
@@ -161,6 +176,47 @@ public class Driver extends RubyObject
161
176
  }
162
177
  }
163
178
  }
179
+ // "*" operator
180
+ else if ( stack_type == self.T_STAR )
181
+ {
182
+ Long production_i = self.config.table
183
+ .get(stack_value.intValue())
184
+ .get(token_id.intValue());
185
+
186
+ if ( production_i != self.T_EOF )
187
+ {
188
+ stack.push(self.T_STAR);
189
+ stack.push(stack_value);
190
+
191
+ stack.push(self.T_APPEND_VALUE_STACK);
192
+ stack.push(Long.valueOf(0));
193
+
194
+ ArrayList<Long> row = self.config.rules
195
+ .get(production_i.intValue());
196
+
197
+ for ( int index = 0; index < row.size(); index++ )
198
+ {
199
+ stack.push(row.get(index));
200
+ }
201
+ }
202
+ }
203
+ // Adds a new array to the value stack that can be used to
204
+ // group operator values together
205
+ else if ( stack_type == self.T_ADD_VALUE_STACK )
206
+ {
207
+ RubyArray operator_buffer = self.runtime.newArray();
208
+
209
+ value_stack.push(operator_buffer);
210
+ }
211
+ // Appends the last value on the value stack to the operator
212
+ // buffer that preceeds it.
213
+ else if ( stack_type == self.T_APPEND_VALUE_STACK )
214
+ {
215
+ IRubyObject last_value = value_stack.pop();
216
+ RubyArray operator_buffer = (RubyArray) value_stack.peek();
217
+
218
+ operator_buffer.append(last_value);
219
+ }
164
220
  // Terminal
165
221
  else if ( stack_type == self.T_TERMINAL )
166
222
  {
data/lib/ll.rb CHANGED
@@ -18,6 +18,7 @@ require_relative 'll/rule'
18
18
  require_relative 'll/branch'
19
19
  require_relative 'll/terminal'
20
20
  require_relative 'll/epsilon'
21
+ require_relative 'll/operator'
21
22
  require_relative 'll/message'
22
23
  require_relative 'll/ast/node'
23
24
  require_relative 'll/erb_context'
data/lib/ll/branch.rb CHANGED
@@ -25,7 +25,13 @@ module LL
25
25
  def first_set
26
26
  first = steps[0]
27
27
 
28
- return first.is_a?(Rule) ? first.first_set : [first]
28
+ if first.is_a?(Rule)
29
+ return first.first_set
30
+ elsif first
31
+ return [first]
32
+ else
33
+ return []
34
+ end
29
35
  end
30
36
 
31
37
  ##
@@ -8,11 +8,15 @@ module LL
8
8
  # @return [Hash]
9
9
  #
10
10
  TYPES = {
11
- :eof => -1,
12
- :rule => 0,
13
- :terminal => 1,
14
- :epsilon => 2,
15
- :action => 3
11
+ :eof => -1,
12
+ :rule => 0,
13
+ :terminal => 1,
14
+ :epsilon => 2,
15
+ :action => 3,
16
+ :star => 4,
17
+ :plus => 5,
18
+ :add_value_stack => 6,
19
+ :append_value_stack => 7
16
20
  }.freeze
17
21
 
18
22
  ##
@@ -105,7 +109,21 @@ module LL
105
109
 
106
110
  grammar.rules.each do |rule|
107
111
  rule.branches.each do |branch|
108
- bodies[:"_rule_#{index}"] = branch.ruby_code || DEFAULT_RUBY_CODE
112
+ if branch.ruby_code
113
+ code = branch.ruby_code
114
+
115
+ # If a branch only contains a single, non-epsilon step we can just
116
+ # return that value as-is. This makes parsing code a little bit
117
+ # easier.
118
+ elsif !branch.ruby_code and branch.steps.length == 1 \
119
+ and !branch.steps[0].is_a?(Epsilon)
120
+ code = 'val[0]'
121
+
122
+ else
123
+ code = DEFAULT_RUBY_CODE
124
+ end
125
+
126
+ bodies[:"_rule_#{index}"] = code
109
127
 
110
128
  index += 1
111
129
  end
@@ -133,17 +151,24 @@ module LL
133
151
  action_index += 1
134
152
 
135
153
  branch.steps.reverse_each do |step|
136
- if step.is_a?(LL::Terminal)
154
+ if step.is_a?(Terminal)
137
155
  row << TYPES[:terminal]
138
156
  row << term_indices[step] + 1
139
157
 
140
- elsif step.is_a?(LL::Rule)
158
+ elsif step.is_a?(Rule)
141
159
  row << TYPES[:rule]
142
160
  row << rule_indices[step]
143
161
 
144
- elsif step.is_a?(LL::Epsilon)
162
+ elsif step.is_a?(Epsilon)
145
163
  row << TYPES[:epsilon]
146
164
  row << 0
165
+
166
+ elsif step.is_a?(Operator)
167
+ row << TYPES[step.type]
168
+ row << rule_indices[step.receiver]
169
+
170
+ row << TYPES[:add_value_stack]
171
+ row << 0
147
172
  end
148
173
  end
149
174
 
data/lib/ll/driver.rb CHANGED
@@ -30,6 +30,10 @@ module LL
30
30
  message = "Unexpected #{token_type}, expected #{expected} instead"
31
31
  when :eof
32
32
  message = "Received #{token_type} but there's nothing left to parse"
33
+ when :star
34
+ message = %Q{Unexpected #{token_type} for a "*" operator}
35
+ when :plus
36
+ message = %Q{Unexpected #{token_type} for a "+" operator}
33
37
  end
34
38
 
35
39
  return message
@@ -179,7 +179,7 @@ module LL
179
179
  ##
180
180
  # Processes the assignment of terminals.
181
181
  #
182
- # @see #process
182
+ # @see [#process]
183
183
  #
184
184
  def on_terminals(node, compiled_grammar)
185
185
  node.children.each do |child|
@@ -199,7 +199,7 @@ module LL
199
199
  ##
200
200
  # Processes an %inner directive.
201
201
  #
202
- # @see #process
202
+ # @see [#process]
203
203
  #
204
204
  def on_inner(node, compiled_grammar)
205
205
  compiled_grammar.inner = process(node.children[0], compiled_grammar)
@@ -208,7 +208,7 @@ module LL
208
208
  ##
209
209
  # Processes a %header directive.
210
210
  #
211
- # @see #process
211
+ # @see [#process]
212
212
  #
213
213
  def on_header(node, compiled_grammar)
214
214
  compiled_grammar.header = process(node.children[0], compiled_grammar)
@@ -217,7 +217,7 @@ module LL
217
217
  ##
218
218
  # Processes a node containing Ruby source code.
219
219
  #
220
- # @see #process
220
+ # @see [#process]
221
221
  # @return [String]
222
222
  #
223
223
  def on_ruby(node, compiled_grammar)
@@ -227,7 +227,7 @@ module LL
227
227
  ##
228
228
  # Extracts the name from an identifier.
229
229
  #
230
- # @see #process
230
+ # @see [#process]
231
231
  # @return [String]
232
232
  #
233
233
  def on_ident(node, compiled_grammar)
@@ -237,7 +237,7 @@ module LL
237
237
  ##
238
238
  # Processes an epsilon.
239
239
  #
240
- # @see #process
240
+ # @see [#process]
241
241
  # @return [LL::Epsilon]
242
242
  #
243
243
  def on_epsilon(node, compiled_grammar)
@@ -247,7 +247,7 @@ module LL
247
247
  ##
248
248
  # Processes the assignment of a rule.
249
249
  #
250
- # @see #process
250
+ # @see [#process]
251
251
  #
252
252
  def on_rule(node, compiled_grammar)
253
253
  name = process(node.children[0], compiled_grammar)
@@ -280,7 +280,7 @@ module LL
280
280
  ##
281
281
  # Creates a basic prototype for a rule.
282
282
  #
283
- # @see #process
283
+ # @see [#process]
284
284
  #
285
285
  def on_rule_prototype(node, compiled_grammar)
286
286
  name = process(node.children[0], compiled_grammar)
@@ -295,7 +295,7 @@ module LL
295
295
  ##
296
296
  # Processes a single rule branch.
297
297
  #
298
- # @see #process
298
+ # @see [#process]
299
299
  # @return [LL::Branch]
300
300
  #
301
301
  def on_branch(node, compiled_grammar)
@@ -313,33 +313,53 @@ module LL
313
313
  ##
314
314
  # Processes the steps of a branch.
315
315
  #
316
- # @see #process
316
+ # @see [#process]
317
317
  # @return [Array]
318
318
  #
319
319
  def on_steps(node, compiled_grammar)
320
- steps = []
320
+ return lookup_identifiers(node, compiled_grammar)
321
+ end
321
322
 
322
- node.children.each do |step_node|
323
- retval = process(step_node, compiled_grammar)
323
+ ##
324
+ # Processes the "*" operator.
325
+ #
326
+ # @param [LL::AST::Node] node
327
+ # @param [LL::CompiledGrammar] compiled_grammar
328
+ # @return [LL::Operator]
329
+ #
330
+ def on_star(node, compiled_grammar)
331
+ steps = lookup_identifiers(node, compiled_grammar)
332
+ name = "_ll_star#{node.source_line.line}#{node.source_line.column}"
333
+ rule = Rule.new(name, node.source_line)
324
334
 
325
- # Literal rule/terminal names.
326
- if retval.is_a?(String)
327
- step = compiled_grammar.lookup_identifier(retval)
335
+ rule.add_branch(steps, node.source_line)
328
336
 
329
- undefined_identifier!(retval, step_node, compiled_grammar) unless step
330
- # Epsilon
331
- else
332
- step = retval
333
- end
337
+ rule.increment_references
334
338
 
335
- if step
336
- step.increment_references if step.respond_to?(:increment_references)
339
+ compiled_grammar.add_rule(rule)
337
340
 
338
- steps << step
339
- end
340
- end
341
+ return Operator.new(:star, rule, node.source_line)
342
+ end
343
+
344
+ ##
345
+ # Processes the "+" operator.
346
+ #
347
+ # @param [LL::AST::Node] node
348
+ # @param [LL::CompiledGrammar] compiled_grammar
349
+ # @return [LL::Operator]
350
+ #
351
+ def on_plus(node, compiled_grammar)
352
+ steps = lookup_identifiers(node, compiled_grammar)
353
+ name = "_ll_plus#{node.source_line.line}#{node.source_line.column}"
354
+ rule = Rule.new(name, node.source_line)
355
+
356
+ rule.add_branch(steps, node.source_line)
341
357
 
342
- return steps
358
+ rule.increment_references
359
+
360
+ compiled_grammar.add_rule(rule)
361
+
362
+ return Operator.new(:plus, rule, node.source_line)
343
363
  end
344
364
 
345
365
  private
@@ -355,5 +375,35 @@ module LL
355
375
  node.source_line
356
376
  )
357
377
  end
378
+
379
+ ##
380
+ # @see [#process]
381
+ # @return [Array]
382
+ #
383
+ def lookup_identifiers(node, compiled_grammar)
384
+ idents = []
385
+
386
+ node.children.each do |ident_node|
387
+ retval = process(ident_node, compiled_grammar)
388
+
389
+ # Literal rule/terminal names.
390
+ if retval.is_a?(String)
391
+ ident = compiled_grammar.lookup_identifier(retval)
392
+
393
+ undefined_identifier!(retval, ident_node, compiled_grammar) if !ident
394
+ # Epsilon
395
+ else
396
+ ident = retval
397
+ end
398
+
399
+ if ident
400
+ ident.increment_references if ident.respond_to?(:increment_references)
401
+
402
+ idents << ident
403
+ end
404
+ end
405
+
406
+ return idents
407
+ end
358
408
  end # Compiler
359
409
  end # LL
data/lib/ll/lexer.rb CHANGED
@@ -64,49 +64,49 @@ self._ll_lexer_indicies = [
64
64
  27, 1, 1, 1, 1, 1, 1, 1,
65
65
  1, 1, 1, 1, 1, 1, 1, 1,
66
66
  1, 1, 1, 1, 1, 1, 26, 1,
67
- 1, 28, 1, 29, 1, 1, 1, 1,
68
- 1, 1, 1, 1, 1, 1, 25, 25,
67
+ 1, 28, 1, 29, 1, 1, 30, 31,
68
+ 32, 33, 1, 1, 1, 1, 25, 25,
69
69
  25, 25, 25, 25, 25, 25, 25, 25,
70
- 30, 31, 1, 32, 1, 1, 1, 25,
70
+ 34, 35, 1, 36, 1, 1, 1, 25,
71
71
  25, 25, 25, 25, 25, 25, 25, 25,
72
72
  25, 25, 25, 25, 25, 25, 25, 25,
73
73
  25, 25, 25, 25, 25, 25, 25, 25,
74
- 25, 1, 1, 1, 1, 33, 1, 25,
74
+ 25, 1, 1, 1, 1, 37, 1, 25,
75
75
  25, 25, 25, 25, 25, 25, 25, 25,
76
76
  25, 25, 25, 25, 25, 25, 25, 25,
77
77
  25, 25, 25, 25, 25, 25, 25, 25,
78
- 25, 34, 35, 1, 1, 1, 25, 36,
79
- 36, 36, 36, 36, 36, 36, 36, 36,
80
- 36, 36, 36, 36, 36, 36, 36, 36,
81
- 36, 36, 36, 36, 36, 36, 36, 36,
82
- 36, 36, 36, 36, 36, 36, 36, 36,
83
- 36, 36, 36, 36, 36, 36, 36, 36,
84
- 36, 36, 36, 36, 36, 36, 36, 25,
78
+ 25, 38, 39, 1, 1, 1, 25, 40,
79
+ 40, 40, 40, 40, 40, 40, 40, 40,
80
+ 40, 40, 40, 40, 40, 40, 40, 40,
81
+ 40, 40, 40, 40, 40, 40, 40, 40,
82
+ 40, 40, 40, 40, 40, 40, 40, 40,
83
+ 40, 40, 40, 40, 40, 40, 40, 40,
84
+ 40, 40, 40, 40, 40, 40, 40, 25,
85
85
  25, 25, 25, 25, 25, 25, 25, 25,
86
- 25, 36, 36, 36, 36, 36, 36, 36,
86
+ 25, 40, 40, 40, 40, 40, 40, 40,
87
87
  25, 25, 25, 25, 25, 25, 25, 25,
88
88
  25, 25, 25, 25, 25, 25, 25, 25,
89
89
  25, 25, 25, 25, 25, 25, 25, 25,
90
- 25, 25, 36, 36, 36, 36, 25, 36,
90
+ 25, 25, 40, 40, 40, 40, 25, 40,
91
91
  25, 25, 25, 25, 25, 25, 25, 25,
92
92
  25, 25, 25, 25, 25, 25, 25, 25,
93
93
  25, 25, 25, 25, 25, 25, 25, 25,
94
- 25, 25, 36, 36, 36, 36, 36, 25,
95
- 37, 28, 39, 38, 38, 38, 38, 38,
96
- 38, 38, 38, 38, 38, 38, 38, 38,
97
- 38, 38, 38, 38, 38, 38, 38, 38,
98
- 38, 38, 38, 38, 38, 38, 38, 38,
99
- 38, 38, 38, 38, 38, 38, 38, 38,
100
- 38, 38, 38, 38, 38, 38, 38, 38,
101
- 38, 38, 38, 38, 38, 38, 38, 38,
102
- 38, 38, 38, 38, 38, 38, 38, 38,
103
- 38, 38, 38, 38, 38, 38, 38, 38,
104
- 38, 38, 38, 38, 38, 38, 38, 38,
105
- 38, 38, 38, 38, 38, 38, 38, 38,
106
- 38, 38, 38, 38, 38, 38, 38, 38,
107
- 38, 38, 38, 38, 38, 38, 38, 38,
108
- 38, 38, 38, 38, 38, 38, 38, 38,
109
- 38, 38, 38, 40, 38, 41, 38, 0
94
+ 25, 25, 40, 40, 40, 40, 40, 25,
95
+ 41, 28, 43, 42, 42, 42, 42, 42,
96
+ 42, 42, 42, 42, 42, 42, 42, 42,
97
+ 42, 42, 42, 42, 42, 42, 42, 42,
98
+ 42, 42, 42, 42, 42, 42, 42, 42,
99
+ 42, 42, 42, 42, 42, 42, 42, 42,
100
+ 42, 42, 42, 42, 42, 42, 42, 42,
101
+ 42, 42, 42, 42, 42, 42, 42, 42,
102
+ 42, 42, 42, 42, 42, 42, 42, 42,
103
+ 42, 42, 42, 42, 42, 42, 42, 42,
104
+ 42, 42, 42, 42, 42, 42, 42, 42,
105
+ 42, 42, 42, 42, 42, 42, 42, 42,
106
+ 42, 42, 42, 42, 42, 42, 42, 42,
107
+ 42, 42, 42, 42, 42, 42, 42, 42,
108
+ 42, 42, 42, 42, 42, 42, 42, 42,
109
+ 42, 42, 42, 44, 42, 45, 42, 0
110
110
  ]
111
111
 
112
112
  class << self
@@ -118,8 +118,8 @@ self._ll_lexer_trans_targs = [
118
118
  6, 22, 8, 9, 10, 22, 12, 13,
119
119
  22, 15, 16, 17, 18, 19, 20, 21,
120
120
  22, 23, 22, 22, 24, 1, 22, 22,
121
- 22, 23, 22, 22, 22, 22, 25, 25,
122
- 25, 25
121
+ 22, 22, 22, 22, 22, 23, 22, 22,
122
+ 22, 22, 25, 25, 25, 25
123
123
  ]
124
124
 
125
125
  class << self
@@ -132,7 +132,7 @@ self._ll_lexer_trans_actions = [
132
132
  3, 0, 0, 0, 0, 0, 0, 0,
133
133
  4, 7, 8, 9, 0, 0, 10, 11,
134
134
  12, 13, 14, 15, 16, 17, 18, 19,
135
- 20, 21
135
+ 20, 21, 22, 23, 24, 25
136
136
  ]
137
137
 
138
138
  class << self
@@ -164,8 +164,8 @@ end
164
164
  self._ll_lexer_eof_trans = [
165
165
  0, 0, 0, 0, 0, 0, 0, 0,
166
166
  0, 0, 0, 0, 0, 0, 0, 0,
167
- 0, 0, 0, 0, 0, 0, 0, 37,
168
- 38, 0
167
+ 0, 0, 0, 0, 0, 0, 0, 41,
168
+ 42, 0
169
169
  ]
170
170
 
171
171
  class << self
@@ -312,13 +312,13 @@ ts = p
312
312
  cs = _ll_lexer_trans_targs[_trans]
313
313
  if _ll_lexer_trans_actions[_trans] != 0
314
314
  case _ll_lexer_trans_actions[_trans]
315
- when 20 then
315
+ when 24 then
316
316
  # line 188 "lib/ll/lexer.rl"
317
317
  begin
318
318
  te = p+1
319
319
  begin brace_count += 1 end
320
320
  end
321
- when 21 then
321
+ when 25 then
322
322
  # line 190 "lib/ll/lexer.rl"
323
323
  begin
324
324
  te = p+1
@@ -338,7 +338,7 @@ te = p+1
338
338
  end
339
339
  end
340
340
  end
341
- when 18 then
341
+ when 22 then
342
342
  # line 206 "lib/ll/lexer.rl"
343
343
  begin
344
344
  te = p+1
@@ -367,33 +367,57 @@ te = p+1
367
367
  te = p+1
368
368
  begin emit(:T_HEADER, ts, te) end
369
369
  end
370
- when 12 then
370
+ when 16 then
371
371
  # line 220 "lib/ll/lexer.rl"
372
372
  begin
373
373
  te = p+1
374
374
  begin emit(:T_EQUALS, ts, te) end
375
375
  end
376
- when 10 then
376
+ when 14 then
377
377
  # line 221 "lib/ll/lexer.rl"
378
378
  begin
379
379
  te = p+1
380
380
  begin emit(:T_COLON, ts, te) end
381
381
  end
382
- when 11 then
382
+ when 15 then
383
383
  # line 222 "lib/ll/lexer.rl"
384
384
  begin
385
385
  te = p+1
386
386
  begin emit(:T_SEMICOLON, ts, te) end
387
387
  end
388
- when 15 then
388
+ when 19 then
389
389
  # line 223 "lib/ll/lexer.rl"
390
390
  begin
391
391
  te = p+1
392
392
  begin emit(:T_PIPE, ts, te) end
393
393
  end
394
- when 14 then
394
+ when 13 then
395
+ # line 225 "lib/ll/lexer.rl"
396
+ begin
397
+ te = p+1
398
+ begin emit(:T_PLUS, ts, te) end
399
+ end
400
+ when 12 then
395
401
  # line 226 "lib/ll/lexer.rl"
396
402
  begin
403
+ te = p+1
404
+ begin emit(:T_STAR, ts, te) end
405
+ end
406
+ when 10 then
407
+ # line 227 "lib/ll/lexer.rl"
408
+ begin
409
+ te = p+1
410
+ begin emit(:T_LPAREN, ts, te) end
411
+ end
412
+ when 11 then
413
+ # line 228 "lib/ll/lexer.rl"
414
+ begin
415
+ te = p+1
416
+ begin emit(:T_RPAREN, ts, te) end
417
+ end
418
+ when 18 then
419
+ # line 230 "lib/ll/lexer.rl"
420
+ begin
397
421
  te = p+1
398
422
  begin
399
423
  mark = ts + 1
@@ -405,26 +429,26 @@ te = p+1
405
429
  cs = 25;
406
430
  end
407
431
  end
408
- when 17 then
432
+ when 21 then
409
433
  # line 213 "lib/ll/lexer.rl"
410
434
  begin
411
435
  te = p
412
436
  p = p - 1; end
413
- when 16 then
437
+ when 20 then
414
438
  # line 1 "NONE"
415
439
  begin
416
440
  case act
417
441
  when 16 then
418
442
  begin begin p = ((te))-1; end
419
443
  emit(:T_EPSILON, ts, te) end
420
- when 18 then
444
+ when 22 then
421
445
  begin begin p = ((te))-1; end
422
446
 
423
447
  emit(:T_IDENT, ts, te)
424
448
  end
425
449
  end
426
450
  end
427
- when 19 then
451
+ when 23 then
428
452
  # line 148 "lib/ll/lexer.rl"
429
453
  begin
430
454
 
@@ -458,7 +482,7 @@ te = p+1
458
482
  begin
459
483
  te = p+1
460
484
  end
461
- when 13 then
485
+ when 17 then
462
486
  # line 1 "NONE"
463
487
  begin
464
488
  te = p+1
@@ -473,8 +497,8 @@ te = p+1
473
497
  end
474
498
  # line 168 "lib/ll/lexer.rl"
475
499
  begin
476
- act = 18; end
477
- # line 477 "lib/ll/lexer.rb"
500
+ act = 22; end
501
+ # line 501 "lib/ll/lexer.rb"
478
502
  end
479
503
  end
480
504
  end
@@ -484,7 +508,7 @@ act = 18; end
484
508
  # line 1 "NONE"
485
509
  begin
486
510
  ts = nil; end
487
- # line 487 "lib/ll/lexer.rb"
511
+ # line 511 "lib/ll/lexer.rb"
488
512
  end
489
513
 
490
514
  if cs == 0
@@ -576,7 +600,7 @@ end
576
600
  end
577
601
 
578
602
 
579
- # line 238 "lib/ll/lexer.rl"
603
+ # line 242 "lib/ll/lexer.rl"
580
604
 
581
605
  end # Lexer
582
606
  end # Oga
@@ -0,0 +1,26 @@
1
+ module LL
2
+ ##
3
+ # Class for operators such as + and *.
4
+ #
5
+ class Operator
6
+ attr_reader :type, :receiver, :source_line
7
+
8
+ ##
9
+ # @param [Symbol] type
10
+ # @param [LL::Rule] receiver
11
+ # @param [LL::SourceLine] source_line
12
+ #
13
+ def initialize(type, receiver, source_line)
14
+ @type = type
15
+ @receiver = receiver
16
+ @source_line = source_line
17
+ end
18
+
19
+ ##
20
+ # @return [String]
21
+ #
22
+ def inspect
23
+ return "Operator(type: #{type.inspect}, receiver: #{receiver.inspect})"
24
+ end
25
+ end # Operator
26
+ end # LL
data/lib/ll/parser.rb CHANGED
@@ -19,6 +19,10 @@ class Parser < LL::Driver
19
19
  :T_PIPE, # 9
20
20
  :T_EPSILON, # 10
21
21
  :T_SEMICOLON, # 11
22
+ :T_STAR, # 12
23
+ :T_PLUS, # 13
24
+ :T_LPAREN, # 14
25
+ :T_RPAREN, # 15
22
26
  ].freeze
23
27
 
24
28
  CONFIG.rules = [
@@ -26,7 +30,7 @@ class Parser < LL::Driver
26
30
  [3, 1, 2, 0], # 1
27
31
  [3, 2, 0, 1, 0, 2], # 2
28
32
  [3, 3, 2, 0], # 3
29
- [3, 4, 0, 18], # 4
33
+ [3, 4, 0, 23], # 4
30
34
  [3, 5, 0, 3], # 5
31
35
  [3, 6, 0, 5], # 6
32
36
  [3, 7, 0, 6], # 7
@@ -35,45 +39,59 @@ class Parser < LL::Driver
35
39
  [3, 10, 0, 4, 0, 10, 1, 8, 1, 8], # 10
36
40
  [3, 11, 2, 0], # 11
37
41
  [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
42
+ [3, 13, 0, 20, 1, 4], # 13
43
+ [3, 14, 0, 20, 1, 5], # 14
40
44
  [3, 15, 0, 9, 0, 10], # 15
41
45
  [3, 16, 0, 8], # 16
42
46
  [3, 17, 2, 0], # 17
43
47
  [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
48
+ [3, 19, 0, 12, 0, 13], # 19
49
+ [3, 20, 0, 15, 1, 15, 0, 8, 1, 14], # 20
50
+ [3, 21, 0, 11], # 21
51
+ [3, 22, 2, 0], # 22
52
+ [3, 23, 0, 14, 0, 10], # 23
53
+ [3, 24, 0, 15], # 24
54
+ [3, 25, 2, 0], # 25
55
+ [3, 26, 1, 13], # 26
56
+ [3, 27, 1, 12], # 27
57
+ [3, 28, 0, 11], # 28
58
+ [3, 29, 0, 17], # 29
59
+ [3, 30, 1, 10], # 30
60
+ [3, 31, 0, 19, 0, 16], # 31
61
+ [3, 32, 0, 20], # 32
62
+ [3, 33, 2, 0], # 33
63
+ [3, 34, 1, 1], # 34
64
+ [3, 35, 0, 22, 0, 18], # 35
65
+ [3, 36, 0, 21, 1, 9], # 36
66
+ [3, 37, 2, 0], # 37
67
+ [3, 38, 1, 11, 0, 21, 1, 7, 0, 10], # 38
55
68
  ].freeze
56
69
 
57
70
  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
71
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 0
72
+ [3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3], # 1
73
+ [-1, -1, 5, 6, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 2
74
+ [-1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 3
75
+ [11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 11], # 4
76
+ [-1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 5
77
+ [-1, -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 6
78
+ [-1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 7
79
+ [-1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 8
80
+ [17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17], # 9
81
+ [-1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 10
82
+ [-1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, 20, -1], # 11
83
+ [22, 22, 22, 22, 22, 22, 21, 22, 22, 22, 22, 22, 22, 22, 21, 22], # 12
84
+ [-1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 13
85
+ [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 24, 25, 25], # 14
86
+ [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, 26, -1, -1], # 15
87
+ [-1, -1, -1, -1, -1, -1, 28, -1, -1, -1, 29, -1, -1, -1, 28, -1], # 16
88
+ [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1], # 17
89
+ [-1, -1, -1, -1, -1, -1, 31, -1, -1, -1, 31, -1, -1, -1, 31, -1], # 18
90
+ [33, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33], # 19
91
+ [-1, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 20
92
+ [-1, -1, -1, -1, -1, -1, 35, -1, -1, -1, 35, -1, -1, -1, 35, -1], # 21
93
+ [37, 37, 37, 37, 37, 37, 37, 37, 37, 36, 37, 37, 37, 37, 37, 37], # 22
94
+ [-1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1], # 23
77
95
  ].freeze
78
96
 
79
97
  CONFIG.actions = [
@@ -96,17 +114,26 @@ class Parser < LL::Driver
96
114
  [:_rule_16, 1], # 16
97
115
  [:_rule_17, 0], # 17
98
116
  [:_rule_18, 1], # 18
99
- [:_rule_19, 1], # 19
100
- [:_rule_20, 1], # 20
117
+ [:_rule_19, 2], # 19
118
+ [:_rule_20, 4], # 20
101
119
  [:_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
120
+ [:_rule_22, 0], # 22
121
+ [:_rule_23, 2], # 23
122
+ [:_rule_24, 1], # 24
123
+ [:_rule_25, 0], # 25
124
+ [:_rule_26, 1], # 26
125
+ [:_rule_27, 1], # 27
126
+ [:_rule_28, 1], # 28
127
+ [:_rule_29, 1], # 29
128
+ [:_rule_30, 1], # 30
129
+ [:_rule_31, 2], # 31
130
+ [:_rule_32, 1], # 32
131
+ [:_rule_33, 0], # 33
132
+ [:_rule_34, 1], # 34
133
+ [:_rule_35, 2], # 35
134
+ [:_rule_36, 2], # 36
135
+ [:_rule_37, 0], # 37
136
+ [:_rule_38, 4], # 38
110
137
  ].freeze
111
138
 
112
139
  ##
@@ -158,7 +185,7 @@ class Parser < LL::Driver
158
185
  end
159
186
 
160
187
  def _rule_2(val)
161
- val[0] + val[1]
188
+ [val[0], *val[1]]
162
189
  end
163
190
 
164
191
  def _rule_3(val)
@@ -166,23 +193,23 @@ class Parser < LL::Driver
166
193
  end
167
194
 
168
195
  def _rule_4(val)
169
- val
196
+ val[0]
170
197
  end
171
198
 
172
199
  def _rule_5(val)
173
- val
200
+ val[0]
174
201
  end
175
202
 
176
203
  def _rule_6(val)
177
- val
204
+ val[0]
178
205
  end
179
206
 
180
207
  def _rule_7(val)
181
- val
208
+ val[0]
182
209
  end
183
210
 
184
211
  def _rule_8(val)
185
- val
212
+ val[0]
186
213
  end
187
214
 
188
215
  def _rule_9(val)
@@ -192,7 +219,7 @@ class Parser < LL::Driver
192
219
  end
193
220
 
194
221
  def _rule_10(val)
195
- [val[2]] + val[3]
222
+ [val[2], *val[3]]
196
223
  end
197
224
 
198
225
  def _rule_11(val)
@@ -218,7 +245,7 @@ class Parser < LL::Driver
218
245
  end
219
246
 
220
247
  def _rule_15(val)
221
- [val[0]] + val[1]
248
+ [val[0], *val[1]]
222
249
  end
223
250
 
224
251
  def _rule_16(val)
@@ -236,22 +263,62 @@ class Parser < LL::Driver
236
263
  end
237
264
 
238
265
  def _rule_19(val)
266
+ [val[0], *val[1]]
267
+ end
268
+
269
+ def _rule_20(val)
270
+
271
+ [s(val[3][0], val[1], :source_line => val[0].source_line)]
272
+
273
+ end
274
+
275
+ def _rule_21(val)
276
+ val[0]
277
+ end
278
+
279
+ def _rule_22(val)
280
+ val
281
+ end
282
+
283
+ def _rule_23(val)
284
+
285
+ val[1] ? s(val[1][0], [val[0]], :source_line => val[1][1]) : val[0]
286
+
287
+ end
288
+
289
+ def _rule_24(val)
290
+ val[0]
291
+ end
292
+
293
+ def _rule_25(val)
294
+ nil
295
+ end
296
+
297
+ def _rule_26(val)
298
+ [:plus, val[0].source_line]
299
+ end
300
+
301
+ def _rule_27(val)
302
+ [:star, val[0].source_line]
303
+ end
304
+
305
+ def _rule_28(val)
239
306
 
240
307
  s(:steps, val[0], :source_line => val[0][0].source_line)
241
308
 
242
309
  end
243
310
 
244
- def _rule_20(val)
311
+ def _rule_29(val)
245
312
 
246
313
  s(:steps, [val[0]], :source_line => val[0].source_line)
247
314
 
248
315
  end
249
316
 
250
- def _rule_21(val)
317
+ def _rule_30(val)
251
318
  s(:epsilon, [], :source_line => val[0].source_line)
252
319
  end
253
320
 
254
- def _rule_22(val)
321
+ def _rule_31(val)
255
322
 
256
323
  steps = [val[0]]
257
324
 
@@ -261,31 +328,31 @@ class Parser < LL::Driver
261
328
 
262
329
  end
263
330
 
264
- def _rule_23(val)
331
+ def _rule_32(val)
265
332
  val[0]
266
333
  end
267
334
 
268
- def _rule_24(val)
335
+ def _rule_33(val)
269
336
  nil
270
337
  end
271
338
 
272
- def _rule_25(val)
339
+ def _rule_34(val)
273
340
  s(:ruby, [val[0].value], :source_line => val[0].source_line)
274
341
  end
275
342
 
276
- def _rule_26(val)
277
- [val[0]] + val[1]
343
+ def _rule_35(val)
344
+ [val[0], *val[1]]
278
345
  end
279
346
 
280
- def _rule_27(val)
347
+ def _rule_36(val)
281
348
  val[1]
282
349
  end
283
350
 
284
- def _rule_28(val)
351
+ def _rule_37(val)
285
352
  val
286
353
  end
287
354
 
288
- def _rule_29(val)
355
+ def _rule_38(val)
289
356
 
290
357
  s(:rule, [val[0], *val[2]], :source_line => val[0].source_line)
291
358
 
data/lib/ll/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LL
2
- VERSION = '1.1.3'
2
+ VERSION = '2.0.0'
3
3
  end # LL
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-ll
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yorick Peterse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-17 00:00:00.000000000 Z
11
+ date: 2015-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast
@@ -150,6 +150,7 @@ files:
150
150
  - bin/ruby-ll
151
151
  - doc/DCO.md
152
152
  - doc/css/common.css
153
+ - doc/driver_architecture.md
153
154
  - ext/c/driver.c
154
155
  - ext/c/driver.h
155
156
  - ext/c/driver_config.c
@@ -180,6 +181,7 @@ files:
180
181
  - lib/ll/grammar_compiler.rb
181
182
  - lib/ll/lexer.rb
182
183
  - lib/ll/message.rb
184
+ - lib/ll/operator.rb
183
185
  - lib/ll/parser.rb
184
186
  - lib/ll/parser_error.rb
185
187
  - lib/ll/rule.rb