rley 0.8.06 → 0.8.08
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/appveyor.yml +1 -3
- data/examples/NLP/benchmark_pico_en.rb +6 -6
- data/examples/NLP/engtagger.rb +6 -6
- data/examples/general/calc_iter1/calc_lexer.rb +1 -1
- data/examples/general/calc_iter2/calc_lexer.rb +1 -1
- data/examples/general/left.rb +1 -1
- data/examples/general/right.rb +1 -1
- data/examples/tokenizer/loxxy_raw_scanner.rex.rb +3 -0
- data/examples/tokenizer/loxxy_tokenizer.rb +2 -2
- data/examples/tokenizer/run_tokenizer.rb +1 -1
- data/examples/tokenizer/{tokens.yaml → tokens.yml} +0 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/engine.rb +2 -2
- data/lib/rley/interface.rb +3 -3
- data/lib/rley/lexical/token.rb +1 -1
- data/lib/rley/ptree/non_terminal_node.rb +1 -1
- data/lib/rley/rgn/all_notation_nodes.rb +5 -0
- data/lib/rley/{notation → rgn}/ast_builder.rb +19 -12
- data/lib/rley/{notation → rgn}/ast_node.rb +12 -11
- data/lib/rley/{notation → rgn}/ast_visitor.rb +10 -10
- data/lib/rley/rgn/composite_node.rb +28 -0
- data/lib/rley/{notation → rgn}/grammar.rb +1 -1
- data/lib/rley/{notation → rgn}/grammar_builder.rb +86 -124
- data/lib/rley/{notation → rgn}/parser.rb +4 -4
- data/lib/rley/rgn/repetition_node.rb +62 -0
- data/lib/rley/rgn/sequence_node.rb +30 -0
- data/lib/rley/{notation → rgn}/symbol_node.rb +15 -7
- data/lib/rley/{notation → rgn}/tokenizer.rb +1 -1
- data/spec/rley/parser/dangling_else_spec.rb +3 -3
- data/spec/rley/parser/gfg_earley_parser_spec.rb +48 -48
- data/spec/rley/{notation → rgn}/grammar_builder_spec.rb +58 -54
- data/spec/rley/{notation → rgn}/parser_spec.rb +36 -24
- data/spec/rley/rgn/repetition_node_spec.rb +56 -0
- data/spec/rley/rgn/sequence_node_spec.rb +48 -0
- data/spec/rley/rgn/symbol_node_spec.rb +33 -0
- data/spec/rley/{notation → rgn}/tokenizer_spec.rb +2 -2
- data/spec/rley/support/ambiguous_grammar_helper.rb +2 -2
- data/spec/rley/support/grammar_int_seq_helper.rb +2 -2
- metadata +31 -24
- data/lib/rley/notation/all_notation_nodes.rb +0 -4
- data/lib/rley/notation/grouping_node.rb +0 -23
- data/lib/rley/notation/sequence_node.rb +0 -35
@@ -3,10 +3,10 @@
|
|
3
3
|
require_relative '../../spec_helper'
|
4
4
|
|
5
5
|
# Load the class under test
|
6
|
-
require_relative '../../../lib/rley/
|
6
|
+
require_relative '../../../lib/rley/rgn/grammar_builder'
|
7
7
|
|
8
8
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
9
|
-
module
|
9
|
+
module RGN # Open this namespace to avoid module qualifier prefixes
|
10
10
|
describe GrammarBuilder do
|
11
11
|
context 'Initialization without argument:' do
|
12
12
|
it 'could be created without argument' do
|
@@ -123,11 +123,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
123
123
|
# implicitly called: rule('arguments_qmark' => 'arguments').tag suffix_qmark_one
|
124
124
|
# implicitly called: rule('arguments_qmark' => '').tag suffix_qmark_none
|
125
125
|
expect(instance.productions.size).to eq(3)
|
126
|
-
prod_star = instance.productions.select { |prod| prod.lhs.name == '
|
126
|
+
prod_star = instance.productions.select { |prod| prod.lhs.name == 'rep_arguments_qmark' }
|
127
127
|
expect(prod_star.size).to eq(2)
|
128
128
|
first_prod = instance.productions.first
|
129
129
|
expect(first_prod.lhs.name).to eq('argument_list')
|
130
|
-
expect(first_prod.rhs.members[1].name).to eq('
|
130
|
+
expect(first_prod.rhs.members[1].name).to eq('rep_arguments_qmark')
|
131
|
+
expect(instance.productions.last.rhs.members).to be_empty
|
131
132
|
end
|
132
133
|
|
133
134
|
it "should support Kleene's star" do
|
@@ -137,14 +138,14 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
137
138
|
instance.rule 'program' => 'declaration* EOF'
|
138
139
|
instance.grammar_complete!
|
139
140
|
|
140
|
-
# implicitly called: rule('
|
141
|
-
# implicitly called: rule('
|
141
|
+
# implicitly called: rule('rep_declaration_star' => 'rep_declaration_star declaration').tag suffix_star_more
|
142
|
+
# implicitly called: rule('rep_declaration_star' => '').tag suffix_star_last
|
142
143
|
expect(instance.productions.size).to eq(3)
|
143
|
-
prod_star = instance.productions.select { |prod| prod.lhs.name == '
|
144
|
+
prod_star = instance.productions.select { |prod| prod.lhs.name == 'rep_declaration_star' }
|
144
145
|
expect(prod_star.size).to eq(2)
|
145
146
|
first_prod = instance.productions.first
|
146
147
|
expect(first_prod.lhs.name).to eq('program')
|
147
|
-
expect(first_prod.rhs.members[0].name).to eq('
|
148
|
+
expect(first_prod.rhs.members[0].name).to eq('rep_declaration_star')
|
148
149
|
end
|
149
150
|
|
150
151
|
it "should support symbols decorated with Kleene's plus" do
|
@@ -163,11 +164,11 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
163
164
|
# implicitly called: rule('digit_plus' => 'digit_plus digit').tag suffix_plus_more
|
164
165
|
# implicitly called: rule('digit_plus' => 'digit').tag suffix_plus_last
|
165
166
|
expect(instance.productions.size).to eq(7) # Two additional rules generated
|
166
|
-
prod_plus = instance.productions.select { |prod| prod.lhs.name == '
|
167
|
+
prod_plus = instance.productions.select { |prod| prod.lhs.name == 'rep_digit_plus' }
|
167
168
|
expect(prod_plus.size).to eq(2)
|
168
169
|
val_prod = instance.productions[4]
|
169
170
|
expect(val_prod.lhs.name).to eq('value')
|
170
|
-
expect(val_prod.rhs.members[0].name).to eq('
|
171
|
+
expect(val_prod.rhs.members[0].name).to eq('rep_digit_plus')
|
171
172
|
end
|
172
173
|
|
173
174
|
it 'should support optional grouping' do
|
@@ -180,21 +181,23 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
180
181
|
# implicitly called: rule('seq_EQUAL_expression' => 'EQUAL expression').tag 'return_children'
|
181
182
|
# implicitly called: rule('seq_EQUAL_expression_qmark' => 'seq_EQUAL_expression').tag suffix_qmark_one
|
182
183
|
# implicitly called: rule('seq_EQUAL_expression_qmark' => '').tag suffix_qmark_none
|
183
|
-
expect(instance.productions.size).to eq(
|
184
|
+
expect(instance.productions.size).to eq(3)
|
184
185
|
first_prod = instance.productions.first
|
185
186
|
expect(first_prod.lhs.name).to eq('var_decl')
|
186
|
-
expect(first_prod.rhs.members[2].name).to eq('
|
187
|
-
(
|
188
|
-
expect(p0.lhs.name).to eq('
|
189
|
-
expect(p0.rhs[0].name).to eq('EQUAL')
|
190
|
-
expect(p0.rhs[1].name).to eq('expression')
|
191
|
-
expect(p0.name).to eq('return_children')
|
192
|
-
|
193
|
-
expect(p1.lhs.name).to eq('
|
194
|
-
expect(p1.rhs[0].name).to eq('
|
195
|
-
expect(p1.name).to eq('
|
196
|
-
|
197
|
-
expect(
|
187
|
+
expect(first_prod.rhs.members[2].name).to eq('rep_seq_EQUAL_expression_qmark')
|
188
|
+
(p1, p2) = instance.productions[1..2]
|
189
|
+
# expect(p0.lhs.name).to eq('rep_seq_EQUAL_expression_qmark')
|
190
|
+
# expect(p0.rhs[0].name).to eq('EQUAL')
|
191
|
+
# expect(p0.rhs[1].name).to eq('expression')
|
192
|
+
# expect(p0.name).to eq('return_children')
|
193
|
+
|
194
|
+
expect(p1.lhs.name).to eq('rep_seq_EQUAL_expression_qmark')
|
195
|
+
expect(p1.rhs[0].name).to eq('EQUAL')
|
196
|
+
expect(p1.rhs[1].name).to eq('expression')
|
197
|
+
# expect(p1.rhs[0].name).to eq('seq_EQUAL_expression')
|
198
|
+
expect(p1.name).to eq('return_children') # TODO _qmark_one
|
199
|
+
|
200
|
+
expect(p2.lhs.name).to eq('rep_seq_EQUAL_expression_qmark')
|
198
201
|
expect(p2.rhs).to be_empty
|
199
202
|
expect(p2.name).to eq('_qmark_none')
|
200
203
|
end
|
@@ -212,7 +215,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
212
215
|
expect(instance.productions.size).to eq(4)
|
213
216
|
first_prod = instance.productions.first
|
214
217
|
expect(first_prod.lhs.name).to eq('logic_or')
|
215
|
-
expect(first_prod.rhs.members[1].name).to eq('
|
218
|
+
expect(first_prod.rhs.members[1].name).to eq('rep_seq_OR_logic_and_star')
|
216
219
|
|
217
220
|
(p0, p1, p2) = instance.productions[1..3]
|
218
221
|
expect(p0.lhs.name).to eq('seq_OR_logic_and')
|
@@ -220,12 +223,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
220
223
|
expect(p0.rhs[1].name).to eq('logic_and')
|
221
224
|
expect(p0.name).to eq('return_children')
|
222
225
|
|
223
|
-
expect(p1.lhs.name).to eq('
|
224
|
-
expect(p1.rhs[0].name).to eq('
|
226
|
+
expect(p1.lhs.name).to eq('rep_seq_OR_logic_and_star')
|
227
|
+
expect(p1.rhs[0].name).to eq('rep_seq_OR_logic_and_star')
|
225
228
|
expect(p1.rhs[1].name).to eq('seq_OR_logic_and')
|
226
229
|
expect(p1.name).to eq('_star_more')
|
227
230
|
|
228
|
-
expect(p2.lhs.name).to eq('
|
231
|
+
expect(p2.lhs.name).to eq('rep_seq_OR_logic_and_star')
|
229
232
|
expect(p2.rhs).to be_empty
|
230
233
|
expect(p2.name).to eq('_star_none')
|
231
234
|
end
|
@@ -243,7 +246,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
243
246
|
expect(instance.productions.size).to eq(4)
|
244
247
|
first_prod = instance.productions.first
|
245
248
|
expect(first_prod.lhs.name).to eq('path')
|
246
|
-
expect(first_prod.rhs.members[1].name).to eq('
|
249
|
+
expect(first_prod.rhs.members[1].name).to eq('rep_seq_TO_POINT_plus')
|
247
250
|
|
248
251
|
(p0, p1, p2) = instance.productions[1..3]
|
249
252
|
expect(p0.lhs.name).to eq('seq_TO_POINT')
|
@@ -251,12 +254,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
251
254
|
expect(p0.rhs[1].name).to eq('POINT')
|
252
255
|
expect(p0.name).to eq('return_children')
|
253
256
|
|
254
|
-
expect(p1.lhs.name).to eq('
|
255
|
-
expect(p1.rhs[0].name).to eq('
|
257
|
+
expect(p1.lhs.name).to eq('rep_seq_TO_POINT_plus')
|
258
|
+
expect(p1.rhs[0].name).to eq('rep_seq_TO_POINT_plus')
|
256
259
|
expect(p1.rhs[1].name).to eq('seq_TO_POINT')
|
257
260
|
expect(p1.name).to eq('_plus_more')
|
258
261
|
|
259
|
-
expect(p2.lhs.name).to eq('
|
262
|
+
expect(p2.lhs.name).to eq('rep_seq_TO_POINT_plus')
|
260
263
|
expect(p2.rhs[0].name).to eq('seq_TO_POINT')
|
261
264
|
expect(p2.name).to eq('_plus_one')
|
262
265
|
end
|
@@ -268,29 +271,30 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
268
271
|
instance.rule('if_stmt' => st)
|
269
272
|
instance.grammar_complete!
|
270
273
|
|
271
|
-
# implicitly called: rule('
|
272
|
-
# implicitly called: rule('
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
expect(
|
277
|
-
expect(
|
278
|
-
|
279
|
-
(p0
|
280
|
-
expect(p0.
|
281
|
-
expect(p0.
|
282
|
-
expect(p0.
|
283
|
-
expect(p0.
|
284
|
-
expect(p0.constraints.
|
285
|
-
|
286
|
-
expect(
|
287
|
-
expect(
|
288
|
-
|
289
|
-
expect(p1.
|
290
|
-
expect(p1.
|
291
|
-
expect(p1.
|
292
|
-
|
293
|
-
|
274
|
+
# implicitly called: rule('rep_seq_ELSE_stmt_qmark' => 'ELSE stmt').tag return_children'
|
275
|
+
# implicitly called: rule('rep_seq_ELSE_stmt_qmark' => '').tag suffix_qmark_none
|
276
|
+
expect(instance.productions.size).to eq(3)
|
277
|
+
(p0, p1, p2) = instance.productions[0..2]
|
278
|
+
expect(p0.lhs.name).to eq('if_stmt')
|
279
|
+
expect(p0.rhs.members[5].name).to eq('rep_seq_ELSE_stmt_qmark')
|
280
|
+
# expect(p0.lhs.name).to eq('seq_ELSE_stmt')
|
281
|
+
# expect(p0.rhs[0].name).to eq('ELSE')
|
282
|
+
# expect(p0.rhs[1].name).to eq('stmt')
|
283
|
+
# expect(p0.name).to eq('return_children')
|
284
|
+
# expect(p0.constraints.size).to eq(1)
|
285
|
+
# expect(p0.constraints[0]).to be_kind_of(Syntax::MatchClosest)
|
286
|
+
# expect(p0.constraints[0].idx_symbol).to eq(0) # ELSE is on position 0
|
287
|
+
# expect(p0.constraints[0].closest_symb).to eq('IF')
|
288
|
+
|
289
|
+
expect(p1.lhs.name).to eq('rep_seq_ELSE_stmt_qmark')
|
290
|
+
expect(p1.rhs[0].name).to eq('ELSE')
|
291
|
+
expect(p1.rhs[1].name).to eq('stmt')
|
292
|
+
expect(p1.name).to eq('return_children')
|
293
|
+
expect(p1.constraints.size).to eq(1)
|
294
|
+
expect(p1.constraints[0]).to be_kind_of(Syntax::MatchClosest)
|
295
|
+
expect(p1.constraints[0].closest_symb).to eq('IF')
|
296
|
+
|
297
|
+
expect(p2.lhs.name).to eq('rep_seq_ELSE_stmt_qmark')
|
294
298
|
expect(p2.rhs).to be_empty
|
295
299
|
expect(p2.name).to eq('_qmark_none')
|
296
300
|
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
require_relative '../../spec_helper' # Use the RSpec framework
|
4
4
|
|
5
|
-
require_relative '../../../lib/rley/
|
5
|
+
require_relative '../../../lib/rley/rgn/ast_builder'
|
6
6
|
# Load the class under test
|
7
|
-
require_relative '../../../lib/rley/
|
7
|
+
require_relative '../../../lib/rley/rgn/parser'
|
8
8
|
|
9
9
|
module Rley
|
10
|
-
module
|
10
|
+
module RGN
|
11
11
|
describe Parser do
|
12
12
|
subject { Parser.new }
|
13
13
|
|
@@ -44,7 +44,7 @@ module Rley
|
|
44
44
|
it 'should parse single symbol names' do
|
45
45
|
samples = %w[IF ifCondition statement]
|
46
46
|
|
47
|
-
# One drawback
|
47
|
+
# One drawback of CSTs: they have a deeply nested structure
|
48
48
|
samples.each do |source|
|
49
49
|
ptree = subject.parse(source)
|
50
50
|
expect(ptree.root).to be_kind_of(Rley::PTree::NonTerminalNode)
|
@@ -82,7 +82,7 @@ module Rley
|
|
82
82
|
ptree = subject.parse(source)
|
83
83
|
expect(ptree.root).to be_kind_of(SymbolNode)
|
84
84
|
expect(ptree.root.name).to eq(source)
|
85
|
-
expect(ptree.root.
|
85
|
+
expect(ptree.root.annotation).to be_empty
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -103,8 +103,10 @@ module Rley
|
|
103
103
|
optional = 'member_seq?'
|
104
104
|
|
105
105
|
ptree = subject.parse(optional)
|
106
|
-
expect(ptree.root).to be_kind_of(
|
107
|
-
expect(ptree.root.name).to eq('
|
106
|
+
expect(ptree.root).to be_kind_of(RepetitionNode)
|
107
|
+
expect(ptree.root.name).to eq('rep_member_seq_qmark')
|
108
|
+
expect(ptree.root.child).to be_kind_of(SymbolNode)
|
109
|
+
expect(ptree.root.child.name).to eq('member_seq')
|
108
110
|
expect(ptree.root.repetition).to eq(:zero_or_one)
|
109
111
|
end
|
110
112
|
|
@@ -112,8 +114,10 @@ module Rley
|
|
112
114
|
one_or_more = 'member+'
|
113
115
|
|
114
116
|
ptree = subject.parse(one_or_more)
|
115
|
-
expect(ptree.root).to be_kind_of(
|
116
|
-
expect(ptree.root.name).to eq('
|
117
|
+
expect(ptree.root).to be_kind_of(RepetitionNode)
|
118
|
+
expect(ptree.root.name).to eq('rep_member_plus')
|
119
|
+
expect(ptree.root.child).to be_kind_of(SymbolNode)
|
120
|
+
expect(ptree.root.child.name).to eq('member')
|
117
121
|
expect(ptree.root.repetition).to eq(:one_or_more)
|
118
122
|
end
|
119
123
|
|
@@ -122,12 +126,14 @@ module Rley
|
|
122
126
|
|
123
127
|
ptree = subject.parse(zero_or_more)
|
124
128
|
expect(ptree.root).to be_kind_of(SequenceNode)
|
125
|
-
expect(ptree.root.
|
126
|
-
expect(ptree.root.subnodes[0]
|
129
|
+
expect(ptree.root.name).to eq('seq_rep_declaration_star_EOF')
|
130
|
+
expect(ptree.root.subnodes[0]).to be_kind_of(RepetitionNode)
|
131
|
+
expect(ptree.root.subnodes[0].name).to eq('rep_declaration_star')
|
127
132
|
expect(ptree.root.subnodes[0].repetition).to eq(:zero_or_more)
|
133
|
+
expect(ptree.root.subnodes[0].child).to be_kind_of(SymbolNode)
|
134
|
+
expect(ptree.root.subnodes[0].child.name).to eq('declaration')
|
128
135
|
expect(ptree.root.subnodes[1]).to be_kind_of(SymbolNode)
|
129
136
|
expect(ptree.root.subnodes[1].name).to eq('EOF')
|
130
|
-
expect(ptree.root.subnodes[1].repetition).to eq(:exactly_one)
|
131
137
|
end
|
132
138
|
|
133
139
|
it 'should parse a grouping with a modifier' do
|
@@ -141,21 +147,25 @@ module Rley
|
|
141
147
|
expect(ptree.root.subnodes[1].name).to eq('ifCondition')
|
142
148
|
expect(ptree.root.subnodes[2]).to be_kind_of(SymbolNode)
|
143
149
|
expect(ptree.root.subnodes[2].name).to eq('statement')
|
144
|
-
expect(ptree.root.subnodes[3]).to be_kind_of(
|
150
|
+
expect(ptree.root.subnodes[3]).to be_kind_of(RepetitionNode)
|
151
|
+
expect(ptree.root.subnodes[3].name).to eq('rep_seq_ELSE_statement_qmark')
|
145
152
|
expect(ptree.root.subnodes[3].repetition).to eq(:zero_or_one)
|
146
|
-
expect(ptree.root.subnodes[3].
|
147
|
-
expect(ptree.root.subnodes[3].subnodes[0]
|
148
|
-
expect(ptree.root.subnodes[3].subnodes[
|
149
|
-
expect(ptree.root.subnodes[3].subnodes[1]
|
153
|
+
expect(ptree.root.subnodes[3].child).to be_kind_of(SequenceNode)
|
154
|
+
expect(ptree.root.subnodes[3].child.subnodes[0]).to be_kind_of(SymbolNode)
|
155
|
+
expect(ptree.root.subnodes[3].child.subnodes[0].name).to eq('ELSE')
|
156
|
+
expect(ptree.root.subnodes[3].child.subnodes[1]).to be_kind_of(SymbolNode)
|
157
|
+
expect(ptree.root.subnodes[3].child.subnodes[1].name).to eq('statement')
|
150
158
|
end
|
151
159
|
|
152
160
|
it 'should parse an annotated symbol' do
|
153
161
|
optional = 'member_seq{repeat: 0..1}'
|
154
162
|
|
155
163
|
ptree = subject.parse(optional)
|
156
|
-
expect(ptree.root).to be_kind_of(
|
157
|
-
expect(ptree.root.name).to eq('
|
164
|
+
expect(ptree.root).to be_kind_of(RepetitionNode)
|
165
|
+
expect(ptree.root.name).to eq('rep_member_seq_qmark')
|
158
166
|
expect(ptree.root.repetition).to eq(:zero_or_one)
|
167
|
+
expect(ptree.root.child).to be_kind_of(SymbolNode)
|
168
|
+
expect(ptree.root.child.name).to eq('member_seq')
|
159
169
|
end
|
160
170
|
|
161
171
|
it 'should parse a grouping with embedded annotation' do
|
@@ -170,12 +180,14 @@ module Rley
|
|
170
180
|
expect(ptree.root.subnodes[2]).to be_kind_of(SymbolNode)
|
171
181
|
expect(ptree.root.subnodes[2].name).to eq('statement')
|
172
182
|
optional = ptree.root.subnodes[3]
|
173
|
-
expect(optional).to be_kind_of(
|
183
|
+
expect(optional).to be_kind_of(RepetitionNode)
|
184
|
+
expect(optional.name).to eq('rep_seq_ELSE_statement_qmark')
|
174
185
|
expect(optional.repetition).to eq(:zero_or_one)
|
175
|
-
expect(optional.
|
176
|
-
expect(optional.subnodes[0]
|
177
|
-
expect(optional.subnodes[0].
|
178
|
-
expect(optional.subnodes[
|
186
|
+
expect(optional.child).to be_kind_of(SequenceNode)
|
187
|
+
expect(optional.child.subnodes[0]).to be_kind_of(SymbolNode)
|
188
|
+
expect(optional.child.subnodes[0].name).to eq('ELSE')
|
189
|
+
expect(optional.child.subnodes[0].annotation).to eq({ 'match_closest' => 'IF' })
|
190
|
+
expect(optional.child.subnodes[1].name).to eq('statement')
|
179
191
|
end
|
180
192
|
end # context
|
181
193
|
end # describe
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper'
|
4
|
+
|
5
|
+
require_relative '../../../lib/rley/lexical/token'
|
6
|
+
require_relative '../../../lib/rley/rgn/symbol_node'
|
7
|
+
|
8
|
+
# Load the class under test
|
9
|
+
require_relative '../../../lib/rley/rgn/repetition_node'
|
10
|
+
|
11
|
+
module Rley # Open this namespace to avoid module qualifier prefixes
|
12
|
+
module RGN # Open this namespace to avoid module qualifier prefixes
|
13
|
+
describe RepetitionNode do
|
14
|
+
let(:a_name) { 'arguments' }
|
15
|
+
let(:a_pos) { Lexical::Position.new(3, 4) }
|
16
|
+
let(:a_child) { SymbolNode.new(a_pos, a_name) }
|
17
|
+
let(:star) { :zero_or_more }
|
18
|
+
|
19
|
+
# Default instantiation rule
|
20
|
+
subject { RepetitionNode.new(a_child, star) }
|
21
|
+
|
22
|
+
context 'Initialization:' do
|
23
|
+
it 'should be created with a child node and a symbol' do
|
24
|
+
expect { RepetitionNode.new(a_child, star) }.not_to raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should know its child' do
|
28
|
+
expect(subject.subnodes.size).to eq(1)
|
29
|
+
expect(subject.subnodes.first).to eq(a_child)
|
30
|
+
expect(subject.child).to eq(a_child)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should know its repetition' do
|
34
|
+
expect(subject.repetition).to eq(star)
|
35
|
+
end
|
36
|
+
end # context
|
37
|
+
|
38
|
+
context 'Provided services:' do
|
39
|
+
it 'should know its name' do
|
40
|
+
# Case repetition == :zero_or_one
|
41
|
+
instance = RepetitionNode.new(a_child, :zero_or_one)
|
42
|
+
expect(instance.name).to eq('rep_arguments_qmark')
|
43
|
+
|
44
|
+
# Case repetition == :zero_or_more
|
45
|
+
expect(subject.name).to eq('rep_arguments_star')
|
46
|
+
|
47
|
+
# Case repetition == :one_or_more
|
48
|
+
instance = RepetitionNode.new(a_child, :one_or_more)
|
49
|
+
expect(instance.name).to eq('rep_arguments_plus')
|
50
|
+
end
|
51
|
+
end # context
|
52
|
+
end # describe
|
53
|
+
end # module
|
54
|
+
end # module
|
55
|
+
|
56
|
+
# End of file
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper'
|
4
|
+
|
5
|
+
require_relative '../../../lib/rley/lexical/token'
|
6
|
+
require_relative '../../../lib/rley/rgn/symbol_node'
|
7
|
+
|
8
|
+
# Load the class under test
|
9
|
+
require_relative '../../../lib/rley/rgn/sequence_node'
|
10
|
+
|
11
|
+
module Rley # Open this namespace to avoid module qualifier prefixes
|
12
|
+
module RGN # Open this namespace to avoid module qualifier prefixes
|
13
|
+
describe SequenceNode do
|
14
|
+
let(:name1) { 'LPAR' }
|
15
|
+
let(:name2) { 'arguments' }
|
16
|
+
let(:name3) { 'RPAR' }
|
17
|
+
let(:pos1) { Lexical::Position.new(3, 7) }
|
18
|
+
let(:pos2) { Lexical::Position.new(3, 9) }
|
19
|
+
let(:pos3) { Lexical::Position.new(3, 19) }
|
20
|
+
let(:child1) { SymbolNode.new(pos1, name1) }
|
21
|
+
let(:child2) { SymbolNode.new(pos2, name2) }
|
22
|
+
let(:child3) { SymbolNode.new(pos3, name3) }
|
23
|
+
|
24
|
+
# Default instantiation rule
|
25
|
+
subject { SequenceNode.new([child1, child2, child3]) }
|
26
|
+
|
27
|
+
context 'Initialization:' do
|
28
|
+
it 'should be created with an array of child nodes' do
|
29
|
+
children = [child1, child2, child3]
|
30
|
+
expect { SequenceNode.new(children) }.not_to raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should know its subnodes' do
|
34
|
+
expect(subject.subnodes.size).to eq(3)
|
35
|
+
expect(subject.subnodes).to eq([child1, child2, child3])
|
36
|
+
end
|
37
|
+
end # context
|
38
|
+
|
39
|
+
context 'Provided services:' do
|
40
|
+
it 'should know its name' do
|
41
|
+
expect(subject.name).to eq('seq_LPAR_arguments_RPAR')
|
42
|
+
end
|
43
|
+
end # context
|
44
|
+
end # describe
|
45
|
+
end # module
|
46
|
+
end # module
|
47
|
+
|
48
|
+
# End of file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper'
|
4
|
+
|
5
|
+
require_relative '../../../lib/rley/lexical/token'
|
6
|
+
|
7
|
+
# Load the class under test
|
8
|
+
require_relative '../../../lib/rley/rgn/symbol_node'
|
9
|
+
|
10
|
+
|
11
|
+
module Rley # Open this namespace to avoid module qualifier prefixes
|
12
|
+
module RGN # Open this namespace to avoid module qualifier prefixes
|
13
|
+
describe SymbolNode do
|
14
|
+
let(:a_name) { 'arguments' }
|
15
|
+
let(:a_pos) { Lexical::Position.new(3, 4) }
|
16
|
+
|
17
|
+
context 'Initialization:' do
|
18
|
+
# Default instantiation rule
|
19
|
+
subject { SymbolNode.new(a_pos, a_name) }
|
20
|
+
|
21
|
+
it 'should be created with a name and position' do
|
22
|
+
expect { SymbolNode.new(a_pos, a_name) }.not_to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should know its name' do
|
26
|
+
expect(subject.name).to eq(a_name)
|
27
|
+
end
|
28
|
+
end # context
|
29
|
+
end # describe
|
30
|
+
end # module
|
31
|
+
end # module
|
32
|
+
|
33
|
+
# End of file
|
@@ -3,10 +3,10 @@
|
|
3
3
|
require_relative '../../spec_helper'
|
4
4
|
|
5
5
|
# Load the class under test
|
6
|
-
require_relative '../../../lib/rley/
|
6
|
+
require_relative '../../../lib/rley/rgn/tokenizer'
|
7
7
|
|
8
8
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
9
|
-
module
|
9
|
+
module RGN # Open this namespace to avoid module qualifier prefixes
|
10
10
|
describe Tokenizer do
|
11
11
|
# Utility method for comparing actual and expected token
|
12
12
|
# sequence. The final EOF is removed from the input sequence.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Load the builder class
|
4
|
-
require_relative '../../../lib/rley/
|
4
|
+
require_relative '../../../lib/rley/rgn/grammar_builder'
|
5
5
|
require_relative '../../../lib/rley/lexical/token'
|
6
6
|
|
7
7
|
|
@@ -10,7 +10,7 @@ module AmbiguousGrammarHelper
|
|
10
10
|
# expression grammar.
|
11
11
|
# (based on an example from Fisher and LeBlanc: "Crafting a Compiler")
|
12
12
|
def grammar_builder
|
13
|
-
Rley::
|
13
|
+
Rley::RGN::GrammarBuilder.new do
|
14
14
|
add_terminals('+', 'id')
|
15
15
|
rule 'S' => 'E'
|
16
16
|
rule 'E' => 'E + E'
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'strscan'
|
4
4
|
|
5
5
|
# Load the builder class
|
6
|
-
require_relative '../../../lib/rley/
|
6
|
+
require_relative '../../../lib/rley/rgn/grammar_builder'
|
7
7
|
require_relative '../../../lib/rley/lexical/token'
|
8
8
|
|
9
9
|
|
@@ -11,7 +11,7 @@ module GrammarIntSeqHelper
|
|
11
11
|
# Factory method. Creates a builder for a grammar of sequence
|
12
12
|
# of positive integers.
|
13
13
|
def grammar_int_seq_builder
|
14
|
-
Rley::
|
14
|
+
Rley::RGN::GrammarBuilder.new do
|
15
15
|
add_terminals('comma', 'digit')
|
16
16
|
rule 'S' => 'sequence'
|
17
17
|
rule 'S' => ''
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.08
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '13.0'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 13.0.0
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '13.0'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 13.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,7 +128,7 @@ files:
|
|
128
128
|
- examples/tokenizer/loxxy_raw_scanner.rex.rb
|
129
129
|
- examples/tokenizer/loxxy_tokenizer.rb
|
130
130
|
- examples/tokenizer/run_tokenizer.rb
|
131
|
-
- examples/tokenizer/tokens.
|
131
|
+
- examples/tokenizer/tokens.yml
|
132
132
|
- lib/rley.rb
|
133
133
|
- lib/rley/base/base_parser.rb
|
134
134
|
- lib/rley/base/dotted_item.rb
|
@@ -156,17 +156,6 @@ files:
|
|
156
156
|
- lib/rley/lexical/literal.rb
|
157
157
|
- lib/rley/lexical/token.rb
|
158
158
|
- lib/rley/lexical/token_range.rb
|
159
|
-
- lib/rley/notation/all_notation_nodes.rb
|
160
|
-
- lib/rley/notation/ast_builder.rb
|
161
|
-
- lib/rley/notation/ast_node.rb
|
162
|
-
- lib/rley/notation/ast_visitor.rb
|
163
|
-
- lib/rley/notation/grammar.rb
|
164
|
-
- lib/rley/notation/grammar_builder.rb
|
165
|
-
- lib/rley/notation/grouping_node.rb
|
166
|
-
- lib/rley/notation/parser.rb
|
167
|
-
- lib/rley/notation/sequence_node.rb
|
168
|
-
- lib/rley/notation/symbol_node.rb
|
169
|
-
- lib/rley/notation/tokenizer.rb
|
170
159
|
- lib/rley/parse_forest_visitor.rb
|
171
160
|
- lib/rley/parse_rep/ast_base_builder.rb
|
172
161
|
- lib/rley/parse_rep/cst_builder.rb
|
@@ -188,6 +177,18 @@ files:
|
|
188
177
|
- lib/rley/ptree/parse_tree.rb
|
189
178
|
- lib/rley/ptree/parse_tree_node.rb
|
190
179
|
- lib/rley/ptree/terminal_node.rb
|
180
|
+
- lib/rley/rgn/all_notation_nodes.rb
|
181
|
+
- lib/rley/rgn/ast_builder.rb
|
182
|
+
- lib/rley/rgn/ast_node.rb
|
183
|
+
- lib/rley/rgn/ast_visitor.rb
|
184
|
+
- lib/rley/rgn/composite_node.rb
|
185
|
+
- lib/rley/rgn/grammar.rb
|
186
|
+
- lib/rley/rgn/grammar_builder.rb
|
187
|
+
- lib/rley/rgn/parser.rb
|
188
|
+
- lib/rley/rgn/repetition_node.rb
|
189
|
+
- lib/rley/rgn/sequence_node.rb
|
190
|
+
- lib/rley/rgn/symbol_node.rb
|
191
|
+
- lib/rley/rgn/tokenizer.rb
|
191
192
|
- lib/rley/rley_error.rb
|
192
193
|
- lib/rley/sppf/alternative_node.rb
|
193
194
|
- lib/rley/sppf/composite_node.rb
|
@@ -228,9 +229,6 @@ files:
|
|
228
229
|
- spec/rley/lexical/literal_spec.rb
|
229
230
|
- spec/rley/lexical/token_range_spec.rb
|
230
231
|
- spec/rley/lexical/token_spec.rb
|
231
|
-
- spec/rley/notation/grammar_builder_spec.rb
|
232
|
-
- spec/rley/notation/parser_spec.rb
|
233
|
-
- spec/rley/notation/tokenizer_spec.rb
|
234
232
|
- spec/rley/parse_forest_visitor_spec.rb
|
235
233
|
- spec/rley/parse_rep/ambiguous_parse_spec.rb
|
236
234
|
- spec/rley/parse_rep/ast_builder_spec.rb
|
@@ -252,6 +250,12 @@ files:
|
|
252
250
|
- spec/rley/ptree/parse_tree_node_spec.rb
|
253
251
|
- spec/rley/ptree/parse_tree_spec.rb
|
254
252
|
- spec/rley/ptree/terminal_node_spec.rb
|
253
|
+
- spec/rley/rgn/grammar_builder_spec.rb
|
254
|
+
- spec/rley/rgn/parser_spec.rb
|
255
|
+
- spec/rley/rgn/repetition_node_spec.rb
|
256
|
+
- spec/rley/rgn/sequence_node_spec.rb
|
257
|
+
- spec/rley/rgn/symbol_node_spec.rb
|
258
|
+
- spec/rley/rgn/tokenizer_spec.rb
|
255
259
|
- spec/rley/sppf/alternative_node_spec.rb
|
256
260
|
- spec/rley/sppf/non_terminal_node_spec.rb
|
257
261
|
- spec/rley/sppf/token_node_spec.rb
|
@@ -326,9 +330,6 @@ test_files:
|
|
326
330
|
- spec/rley/lexical/literal_spec.rb
|
327
331
|
- spec/rley/lexical/token_range_spec.rb
|
328
332
|
- spec/rley/lexical/token_spec.rb
|
329
|
-
- spec/rley/notation/grammar_builder_spec.rb
|
330
|
-
- spec/rley/notation/parser_spec.rb
|
331
|
-
- spec/rley/notation/tokenizer_spec.rb
|
332
333
|
- spec/rley/parser/dangling_else_spec.rb
|
333
334
|
- spec/rley/parser/error_reason_spec.rb
|
334
335
|
- spec/rley/parser/gfg_chart_spec.rb
|
@@ -350,6 +351,12 @@ test_files:
|
|
350
351
|
- spec/rley/ptree/parse_tree_node_spec.rb
|
351
352
|
- spec/rley/ptree/parse_tree_spec.rb
|
352
353
|
- spec/rley/ptree/terminal_node_spec.rb
|
354
|
+
- spec/rley/rgn/grammar_builder_spec.rb
|
355
|
+
- spec/rley/rgn/parser_spec.rb
|
356
|
+
- spec/rley/rgn/repetition_node_spec.rb
|
357
|
+
- spec/rley/rgn/sequence_node_spec.rb
|
358
|
+
- spec/rley/rgn/symbol_node_spec.rb
|
359
|
+
- spec/rley/rgn/tokenizer_spec.rb
|
353
360
|
- spec/rley/sppf/alternative_node_spec.rb
|
354
361
|
- spec/rley/sppf/non_terminal_node_spec.rb
|
355
362
|
- spec/rley/sppf/token_node_spec.rb
|