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 +4 -4
- data/README.md +68 -2
- data/doc/driver_architecture.md +32 -0
- data/ext/c/driver.c +71 -2
- data/ext/c/driver_config.c +1 -1
- data/ext/c/driver_config.h +1 -1
- data/ext/java/org/libll/Driver.java +63 -7
- data/lib/ll.rb +1 -0
- data/lib/ll/branch.rb +7 -1
- data/lib/ll/configuration_compiler.rb +34 -9
- data/lib/ll/driver.rb +4 -0
- data/lib/ll/grammar_compiler.rb +77 -27
- data/lib/ll/lexer.rb +75 -51
- data/lib/ll/operator.rb +26 -0
- data/lib/ll/parser.rb +129 -62
- data/lib/ll/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5d66bcacfb96b5c530ea468c1e6f9cc74a3d916
|
4
|
+
data.tar.gz: 4eba99c6eb0c02fd4945cc2767ec5487cd93b7d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
282
|
-
|
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
|
-
/*
|
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
|
{
|
data/ext/c/driver_config.c
CHANGED
@@ -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(
|
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)
|
data/ext/c/driver_config.h
CHANGED
@@ -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
|
31
|
-
private static long T_RULE
|
32
|
-
private static long T_TERMINAL
|
33
|
-
private static long T_EPSILON
|
34
|
-
private static long T_ACTION
|
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
|
-
//
|
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
@@ -8,11 +8,15 @@ module LL
|
|
8
8
|
# @return [Hash]
|
9
9
|
#
|
10
10
|
TYPES = {
|
11
|
-
:eof
|
12
|
-
:rule
|
13
|
-
:terminal
|
14
|
-
:epsilon
|
15
|
-
:action
|
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
|
-
|
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?(
|
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?(
|
158
|
+
elsif step.is_a?(Rule)
|
141
159
|
row << TYPES[:rule]
|
142
160
|
row << rule_indices[step]
|
143
161
|
|
144
|
-
elsif step.is_a?(
|
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
|
data/lib/ll/grammar_compiler.rb
CHANGED
@@ -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
|
-
|
320
|
+
return lookup_identifiers(node, compiled_grammar)
|
321
|
+
end
|
321
322
|
|
322
|
-
|
323
|
-
|
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
|
-
|
326
|
-
if retval.is_a?(String)
|
327
|
-
step = compiled_grammar.lookup_identifier(retval)
|
335
|
+
rule.add_branch(steps, node.source_line)
|
328
336
|
|
329
|
-
|
330
|
-
# Epsilon
|
331
|
-
else
|
332
|
-
step = retval
|
333
|
-
end
|
337
|
+
rule.increment_references
|
334
338
|
|
335
|
-
|
336
|
-
step.increment_references if step.respond_to?(:increment_references)
|
339
|
+
compiled_grammar.add_rule(rule)
|
337
340
|
|
338
|
-
|
339
|
-
|
340
|
-
|
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
|
-
|
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,
|
68
|
-
|
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
|
-
|
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,
|
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,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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,
|
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,
|
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,
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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,
|
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,
|
168
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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 =
|
477
|
-
# line
|
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
|
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
|
603
|
+
# line 242 "lib/ll/lexer.rl"
|
580
604
|
|
581
605
|
end # Lexer
|
582
606
|
end # Oga
|
data/lib/ll/operator.rb
ADDED
@@ -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,
|
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,
|
39
|
-
[3, 14, 0,
|
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,
|
45
|
-
[3, 20, 0,
|
46
|
-
[3, 21,
|
47
|
-
[3, 22,
|
48
|
-
[3, 23, 0,
|
49
|
-
[3, 24,
|
50
|
-
[3, 25,
|
51
|
-
[3, 26,
|
52
|
-
[3, 27,
|
53
|
-
[3, 28,
|
54
|
-
[3, 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
|
-
[
|
71
|
-
[-1, -1, -1, -1, -1, -1,
|
72
|
-
[
|
73
|
-
[-1,
|
74
|
-
[-1, -1, -1, -1, -1, -1,
|
75
|
-
[
|
76
|
-
[-1, -1, -1, -1, -1, -1,
|
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,
|
100
|
-
[:_rule_20,
|
117
|
+
[:_rule_19, 2], # 19
|
118
|
+
[:_rule_20, 4], # 20
|
101
119
|
[:_rule_21, 1], # 21
|
102
|
-
[:_rule_22,
|
103
|
-
[:_rule_23,
|
104
|
-
[:_rule_24,
|
105
|
-
[:_rule_25,
|
106
|
-
[:_rule_26,
|
107
|
-
[:_rule_27,
|
108
|
-
[:_rule_28,
|
109
|
-
[:_rule_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]
|
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]
|
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]
|
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
|
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
|
317
|
+
def _rule_30(val)
|
251
318
|
s(:epsilon, [], :source_line => val[0].source_line)
|
252
319
|
end
|
253
320
|
|
254
|
-
def
|
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
|
331
|
+
def _rule_32(val)
|
265
332
|
val[0]
|
266
333
|
end
|
267
334
|
|
268
|
-
def
|
335
|
+
def _rule_33(val)
|
269
336
|
nil
|
270
337
|
end
|
271
338
|
|
272
|
-
def
|
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
|
277
|
-
[val[0]
|
343
|
+
def _rule_35(val)
|
344
|
+
[val[0], *val[1]]
|
278
345
|
end
|
279
346
|
|
280
|
-
def
|
347
|
+
def _rule_36(val)
|
281
348
|
val[1]
|
282
349
|
end
|
283
350
|
|
284
|
-
def
|
351
|
+
def _rule_37(val)
|
285
352
|
val
|
286
353
|
end
|
287
354
|
|
288
|
-
def
|
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
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:
|
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-
|
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
|