rley 0.4.06 → 0.4.07
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/.rubocop.yml +22 -13
- data/.travis.yml +8 -7
- data/CHANGELOG.md +9 -0
- data/README.md +9 -10
- data/examples/NLP/mini_en_demo.rb +7 -7
- data/examples/data_formats/JSON/cli_options.rb +5 -6
- data/examples/data_formats/JSON/{JSON_demo.rb → json_demo.rb} +2 -2
- data/examples/data_formats/JSON/{JSON_grammar.rb → json_grammar.rb} +10 -10
- data/examples/data_formats/JSON/{JSON_lexer.rb → json_lexer.rb} +17 -22
- data/examples/data_formats/JSON/{JSON_parser.rb → json_parser.rb} +2 -2
- data/examples/general/calc/calc_demo.rb +1 -1
- data/examples/general/calc/calc_grammar.rb +5 -5
- data/examples/general/calc/calc_lexer.rb +14 -17
- data/examples/general/calc/calc_parser.rb +2 -2
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/formatter/asciitree.rb +15 -16
- data/lib/rley/formatter/bracket_notation.rb +3 -6
- data/lib/rley/formatter/debug.rb +0 -1
- data/lib/rley/formatter/json.rb +0 -1
- data/lib/rley/gfg/grm_flow_graph.rb +11 -10
- data/lib/rley/parse_forest_visitor.rb +0 -3
- data/lib/rley/parse_tree_visitor.rb +0 -3
- data/lib/rley/parser/error_reason.rb +1 -5
- data/lib/rley/parser/gfg_chart.rb +2 -2
- data/lib/rley/parser/gfg_earley_parser.rb +1 -2
- data/lib/rley/parser/gfg_parsing.rb +3 -7
- data/lib/rley/parser/parse_entry.rb +0 -1
- data/lib/rley/parser/parse_entry_set.rb +15 -16
- data/lib/rley/parser/parse_forest_builder.rb +8 -23
- data/lib/rley/parser/parse_state.rb +1 -1
- data/lib/rley/parser/parse_tree_builder.rb +2 -30
- data/lib/rley/parser/parse_tree_factory.rb +1 -1
- data/lib/rley/parser/parse_walker_factory.rb +3 -6
- data/lib/rley/parser/state_set.rb +0 -1
- data/lib/rley/ptree/parse_tree.rb +0 -1
- data/lib/rley/ptree/terminal_node.rb +4 -1
- data/lib/rley/rley_error.rb +1 -1
- data/lib/rley/sppf/composite_node.rb +0 -1
- data/lib/rley/sppf/parse_forest.rb +0 -1
- data/lib/rley/syntax/grammar.rb +5 -9
- data/lib/rley/syntax/grammar_builder.rb +8 -11
- data/lib/rley/syntax/grm_symbol.rb +0 -1
- data/lib/rley/syntax/production.rb +5 -4
- data/lib/rley/tokens/token_range.rb +0 -1
- data/spec/rley/formatter/bracket_notation_spec.rb +3 -1
- data/spec/rley/gfg/grm_flow_graph_spec.rb +15 -46
- data/spec/rley/gfg/item_vertex_spec.rb +1 -1
- data/spec/rley/parse_forest_visitor_spec.rb +1 -1
- data/spec/rley/parse_tree_visitor_spec.rb +2 -2
- data/spec/rley/parser/error_reason_spec.rb +19 -14
- data/spec/rley/parser/gfg_chart_spec.rb +1 -1
- data/spec/rley/parser/gfg_earley_parser_spec.rb +15 -15
- data/spec/rley/parser/gfg_parsing_spec.rb +3 -3
- data/spec/rley/parser/groucho_spec.rb +6 -7
- data/spec/rley/parser/parse_forest_builder_spec.rb +5 -5
- data/spec/rley/parser/parse_forest_factory_spec.rb +5 -5
- data/spec/rley/parser/parse_state_spec.rb +8 -0
- data/spec/rley/parser/parse_tracer_spec.rb +1 -1
- data/spec/rley/parser/parse_tree_builder_spec.rb +26 -29
- data/spec/rley/parser/parse_tree_factory_spec.rb +5 -5
- data/spec/rley/parser/parse_walker_factory_spec.rb +5 -5
- data/spec/rley/ptree/parse_tree_node_spec.rb +2 -2
- data/spec/rley/ptree/terminal_node_spec.rb +1 -1
- data/spec/rley/support/ambiguous_grammar_helper.rb +1 -1
- data/spec/rley/support/expectation_helper.rb +0 -1
- data/spec/rley/support/grammar_abc_helper.rb +1 -1
- data/spec/rley/support/grammar_ambig01_helper.rb +2 -3
- data/spec/rley/support/grammar_b_expr_helper.rb +2 -2
- data/spec/rley/support/grammar_l0_helper.rb +7 -8
- data/spec/rley/support/grammar_pb_helper.rb +3 -4
- data/spec/rley/support/grammar_sppf_helper.rb +4 -4
- data/spec/rley/syntax/grammar_builder_spec.rb +5 -4
- data/spec/rley/syntax/grammar_spec.rb +10 -11
- data/spec/rley/syntax/symbol_seq_spec.rb +2 -2
- data/spec/rley/syntax/terminal_spec.rb +1 -1
- metadata +31 -31
@@ -23,13 +23,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
23
23
|
builder = Rley::Syntax::GrammarBuilder.new do
|
24
24
|
add_terminals('N', 'V', 'Pro') # N(oun), V(erb), Pro(noun)
|
25
25
|
add_terminals('Det', 'P') # Det(erminer), P(reposition)
|
26
|
-
rule 'S' => %w
|
27
|
-
rule 'NP' => %w
|
28
|
-
rule 'NP' => %w
|
26
|
+
rule 'S' => %w[NP VP]
|
27
|
+
rule 'NP' => %w[Det N]
|
28
|
+
rule 'NP' => %w[Det N PP]
|
29
29
|
rule 'NP' => 'Pro'
|
30
|
-
rule 'VP' => %w
|
31
|
-
rule 'VP' => %w
|
32
|
-
rule 'PP' => %w
|
30
|
+
rule 'VP' => %w[V NP]
|
31
|
+
rule 'VP' => %w[VP PP]
|
32
|
+
rule 'PP' => %w[P NP]
|
33
33
|
end
|
34
34
|
builder.grammar
|
35
35
|
end
|
@@ -111,7 +111,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
111
111
|
end
|
112
112
|
|
113
113
|
context 'Parse ambiguous sentence' do
|
114
|
-
|
115
114
|
subject { ParseForestBuilder.new(sentence_tokens) }
|
116
115
|
|
117
116
|
it 'should build a parse forest with a correct root node' do
|
@@ -24,18 +24,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
24
24
|
builder = Syntax::GrammarBuilder.new do
|
25
25
|
add_terminals('a', 'b')
|
26
26
|
rule 'Phi' => 'S'
|
27
|
-
rule 'S' => %w
|
28
|
-
rule 'S' => %w
|
27
|
+
rule 'S' => %w[A T]
|
28
|
+
rule 'S' => %w[a T]
|
29
29
|
rule 'A' => 'a'
|
30
|
-
rule 'A' => %w
|
30
|
+
rule 'A' => %w[B A]
|
31
31
|
rule 'B' => []
|
32
|
-
rule 'T' => %w
|
32
|
+
rule 'T' => %w[b b b]
|
33
33
|
end
|
34
34
|
builder.grammar
|
35
35
|
end
|
36
36
|
|
37
37
|
let(:sample_tokens) do
|
38
|
-
build_token_sequence(%w
|
38
|
+
build_token_sequence(%w[a b b b], sample_grammar)
|
39
39
|
end
|
40
40
|
|
41
41
|
let(:sample_result) do
|
@@ -23,18 +23,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
23
23
|
builder = Syntax::GrammarBuilder.new do
|
24
24
|
add_terminals('a', 'b')
|
25
25
|
rule 'Phi' => 'S'
|
26
|
-
rule 'S' => %w
|
27
|
-
rule 'S' => %w
|
26
|
+
rule 'S' => %w[A T]
|
27
|
+
rule 'S' => %w[a T]
|
28
28
|
rule 'A' => 'a'
|
29
|
-
rule 'A' => %w
|
29
|
+
rule 'A' => %w[B A]
|
30
30
|
rule 'B' => []
|
31
|
-
rule 'T' => %w
|
31
|
+
rule 'T' => %w[b b b]
|
32
32
|
end
|
33
33
|
builder.grammar
|
34
34
|
end
|
35
35
|
|
36
36
|
let(:sample_tokens) do
|
37
|
-
build_token_sequence(%w
|
37
|
+
build_token_sequence(%w[a b b b], sample_grammar)
|
38
38
|
end
|
39
39
|
|
40
40
|
let(:sample_result) do
|
@@ -74,6 +74,14 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
74
74
|
diff_rule = ParseState.new(other_dotted_rule, 3)
|
75
75
|
expect(subject == diff_rule).to eq(false)
|
76
76
|
end
|
77
|
+
|
78
|
+
it 'should know if the parsing is at the start of the production' do
|
79
|
+
expect(subject).not_to be_predicted
|
80
|
+
at_start = DottedItem.new(sample_prod, 0)
|
81
|
+
|
82
|
+
instance = ParseState.new(at_start, 0)
|
83
|
+
expect(instance).to be_predicted
|
84
|
+
end
|
77
85
|
|
78
86
|
it 'should know if the parsing reached the end of the production' do
|
79
87
|
expect(subject).not_to be_complete
|
@@ -17,7 +17,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
17
17
|
let(:output) { StringIO.new('', 'w') }
|
18
18
|
|
19
19
|
let(:token_seq) do
|
20
|
-
literals = %w
|
20
|
+
literals = %w[I saw John with a dog]
|
21
21
|
literals.map { |lexeme| Tokens::Token.new(lexeme, nil) }
|
22
22
|
end
|
23
23
|
|
@@ -16,7 +16,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
16
16
|
include GrammarBExprHelper # Mix-in for basic arithmetic language
|
17
17
|
|
18
18
|
let(:sample_grammar) do
|
19
|
-
builder = grammar_expr_builder
|
19
|
+
builder = grammar_expr_builder
|
20
20
|
builder.grammar
|
21
21
|
end
|
22
22
|
|
@@ -33,9 +33,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
33
33
|
|
34
34
|
# Emit a text representation of the current path.
|
35
35
|
def path_to_s()
|
36
|
-
text_parts = subject.curr_path.map
|
37
|
-
path_element.to_s
|
38
|
-
end
|
36
|
+
text_parts = subject.curr_path.map(&:to_s)
|
39
37
|
return text_parts.join('/')
|
40
38
|
end
|
41
39
|
|
@@ -94,7 +92,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
94
92
|
next_event(:visit, 'P => S . | 0') # Event 2
|
95
93
|
next_event(:visit, 'S. | 0') # Event 3
|
96
94
|
next_event(:visit, 'S => S + M . | 0') # Event 4
|
97
|
-
expected_curr_path('P[0, 5]/S[0, 5]')
|
95
|
+
expected_curr_path('P[0, 5]/S[0, 5]')
|
98
96
|
next_event(:visit, 'M. | 2') # Event 5
|
99
97
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
100
98
|
next_event(:visit, 'M => M * T . | 2') # Event 6
|
@@ -112,7 +110,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
112
110
|
next_event(:visit, 'T => . integer | 4') # Event 9
|
113
111
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]/T[4, 5]')
|
114
112
|
expected_first_child("integer[4, 5]: '4'")
|
115
|
-
expect(subject.curr_parent.subnodes.size).to eq(1)
|
113
|
+
expect(subject.curr_parent.subnodes.size).to eq(1)
|
116
114
|
end
|
117
115
|
|
118
116
|
it 'should handle the remaining events' do
|
@@ -125,8 +123,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
125
123
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
126
124
|
|
127
125
|
next_event(:visit, 'M => M * . T | 2') # Event 11
|
128
|
-
|
129
|
-
next_event(:visit, 'M => M . * T | 2') # Event 12
|
126
|
+
|
127
|
+
next_event(:visit, 'M => M . * T | 2') # Event 12
|
130
128
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
131
129
|
expect(subject.curr_parent.subnodes.size).to eq(2)
|
132
130
|
expected_first_child("*[3, 4]: '*'")
|
@@ -146,44 +144,44 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
146
144
|
expected_first_child("integer[2, 3]: '3'")
|
147
145
|
|
148
146
|
next_event(:visit, 'T => . integer | 2') # Event 17
|
149
|
-
|
147
|
+
|
150
148
|
next_event(:visit, '.T | 2') # Event 18
|
151
|
-
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]/M[2, 3]')
|
149
|
+
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]/M[2, 3]')
|
152
150
|
|
153
151
|
next_event(:visit, 'M => . T | 2') # Event 19
|
154
152
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]/M[2, 3]')
|
155
153
|
|
156
154
|
next_event(:visit, '.M | 2') # Event 20
|
157
155
|
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
158
|
-
|
156
|
+
|
159
157
|
next_event(:visit, 'M => . M * T | 2') # Event 21
|
160
|
-
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
158
|
+
expected_curr_path('P[0, 5]/S[0, 5]/M[2, 5]')
|
161
159
|
|
162
160
|
next_event(:revisit, '.M | 2') # Revisit Event 22
|
163
|
-
expected_curr_path('P[0, 5]/S[0, 5]')
|
164
|
-
|
161
|
+
expected_curr_path('P[0, 5]/S[0, 5]')
|
162
|
+
|
165
163
|
next_event(:visit, 'S => S + . M | 0') # Event 23
|
166
164
|
expected_curr_path('P[0, 5]/S[0, 5]')
|
167
165
|
|
168
166
|
next_event(:visit, 'S => S . + M | 0') # Event 24
|
169
167
|
expected_curr_path('P[0, 5]/S[0, 5]')
|
170
168
|
expect(subject.curr_parent.subnodes.size).to eq(2)
|
171
|
-
expected_first_child("+[1, 2]: '+'")
|
172
|
-
|
169
|
+
expected_first_child("+[1, 2]: '+'")
|
170
|
+
|
173
171
|
next_event(:visit, 'S. | 0') # Event 25
|
174
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
172
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
175
173
|
|
176
174
|
next_event(:visit, 'S => M . | 0') # Event 26
|
177
175
|
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
178
|
-
|
176
|
+
|
179
177
|
next_event(:visit, 'M. | 0') # Event 27
|
180
178
|
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
181
179
|
|
182
180
|
next_event(:visit, 'M => T . | 0') # Event 28
|
183
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
181
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
184
182
|
|
185
183
|
next_event(:visit, 'T. | 0') # Event 29
|
186
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]/T[0, 1]')
|
184
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]/T[0, 1]')
|
187
185
|
|
188
186
|
next_event(:visit, 'T => integer . | 0') # Event 30
|
189
187
|
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]/T[0, 1]')
|
@@ -194,17 +192,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
194
192
|
expected_first_child("integer[0, 1]: '2'")
|
195
193
|
|
196
194
|
next_event(:visit, '.T | 0') # Event 32
|
197
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
195
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
198
196
|
|
199
197
|
next_event(:visit, 'M => . T | 0') # Event 33
|
200
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
198
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]/M[0, 1]')
|
201
199
|
|
202
200
|
next_event(:visit, '.M | 0') # Event 34
|
203
|
-
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
201
|
+
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
204
202
|
|
205
203
|
next_event(:visit, 'S => . M | 0') # Event 35
|
206
204
|
expected_curr_path('P[0, 5]/S[0, 5]/S[0, 1]')
|
207
|
-
|
205
|
+
|
208
206
|
next_event(:visit, '.S | 0') # Event 36
|
209
207
|
expected_curr_path('P[0, 5]/S[0, 5]')
|
210
208
|
|
@@ -215,12 +213,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
215
213
|
expected_curr_path('P[0, 5]')
|
216
214
|
|
217
215
|
next_event(:visit, 'P => . S | 0') # Event 39
|
218
|
-
expected_curr_path('P[0, 5]')
|
216
|
+
expected_curr_path('P[0, 5]')
|
219
217
|
|
220
|
-
next_event(:visit, '.P | 0') # Event 39
|
218
|
+
next_event(:visit, '.P | 0') # Event 39
|
221
219
|
expect(path_to_s).to be_empty
|
222
220
|
end
|
223
|
-
|
221
|
+
|
224
222
|
it 'should build parse trees' do
|
225
223
|
loop do
|
226
224
|
event = @walker.next
|
@@ -241,10 +239,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
241
239
|
second_grandchild = child_node.subnodes[1]
|
242
240
|
expect(second_grandchild.to_s).to eq("+[1, 2]: '+'")
|
243
241
|
third_grandchild = child_node.subnodes[2]
|
244
|
-
expect(third_grandchild.to_s).to eq('M[2, 5]')
|
242
|
+
expect(third_grandchild.to_s).to eq('M[2, 5]')
|
245
243
|
end
|
246
244
|
end # context
|
247
|
-
|
248
245
|
end # describe
|
249
246
|
end # module
|
250
247
|
end # module
|
@@ -23,18 +23,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
23
23
|
builder = Syntax::GrammarBuilder.new do
|
24
24
|
add_terminals('a', 'b')
|
25
25
|
rule 'Phi' => 'S'
|
26
|
-
rule 'S' => %w
|
27
|
-
rule 'S' => %w
|
26
|
+
rule 'S' => %w[A T]
|
27
|
+
rule 'S' => %w[a T]
|
28
28
|
rule 'A' => 'a'
|
29
|
-
rule 'A' => %w
|
29
|
+
rule 'A' => %w[B A]
|
30
30
|
rule 'B' => []
|
31
|
-
rule 'T' => %w
|
31
|
+
rule 'T' => %w[b b b]
|
32
32
|
end
|
33
33
|
builder.grammar
|
34
34
|
end
|
35
35
|
|
36
36
|
let(:sample_tokens) do
|
37
|
-
build_token_sequence(%w
|
37
|
+
build_token_sequence(%w[a b b b], sample_grammar)
|
38
38
|
end
|
39
39
|
|
40
40
|
let(:sample_result) do
|
@@ -46,18 +46,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
46
46
|
builder = Syntax::GrammarBuilder.new do
|
47
47
|
add_terminals('a', 'b')
|
48
48
|
rule'Phi' => 'S'
|
49
|
-
rule'S' => %w
|
50
|
-
rule'S' => %w
|
49
|
+
rule'S' => %w[A T]
|
50
|
+
rule'S' => %w[a T]
|
51
51
|
rule'A' => 'a'
|
52
|
-
rule'A' => %w
|
52
|
+
rule'A' => %w[B A]
|
53
53
|
rule'B' => []
|
54
|
-
rule'T' => %w
|
54
|
+
rule'T' => %w[b b b]
|
55
55
|
end
|
56
56
|
builder.grammar
|
57
57
|
end
|
58
58
|
|
59
59
|
let(:sample_tokens) do
|
60
|
-
build_token_sequence(%w
|
60
|
+
build_token_sequence(%w[a b b b], sample_grammar)
|
61
61
|
end
|
62
62
|
|
63
63
|
let(:sample_result) do
|
@@ -28,12 +28,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
28
28
|
|
29
29
|
context 'Initialization:' do
|
30
30
|
it 'should assign undefined range bounds' do
|
31
|
-
partial_range =
|
31
|
+
partial_range = { low: 0 } # High bound left undefined
|
32
32
|
instance = ParseTreeNode.new(sample_symbol, partial_range)
|
33
33
|
|
34
34
|
another = { low: 1, high: 4 } # High bound is specified
|
35
35
|
instance.range = another
|
36
|
-
expect(instance.range).to eq(
|
36
|
+
expect(instance.range).to eq(low: 0, high: 4)
|
37
37
|
end
|
38
38
|
end # context
|
39
39
|
end # describe
|
@@ -16,7 +16,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
16
16
|
subject { TerminalNode.new(sample_token, sample_range) }
|
17
17
|
|
18
18
|
context 'Initialization:' do
|
19
|
-
it
|
19
|
+
it 'should be bound to a token' do
|
20
20
|
expect(subject.token).to eq(sample_token)
|
21
21
|
end
|
22
22
|
end # context
|
@@ -12,15 +12,14 @@ module GrammarAmbig01Helper
|
|
12
12
|
builder = Rley::Syntax::GrammarBuilder.new do
|
13
13
|
add_terminals('integer', '+', '*')
|
14
14
|
rule 'P' => 'S'
|
15
|
-
rule 'S' => %w
|
16
|
-
rule 'S' => %w
|
15
|
+
rule 'S' => %w[S + S]
|
16
|
+
rule 'S' => %w[S * S]
|
17
17
|
rule 'S' => 'L'
|
18
18
|
rule 'L' => 'integer'
|
19
19
|
end
|
20
20
|
builder
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
23
|
# Highly simplified tokenizer implementation.
|
25
24
|
def tokenizer_ambig01(aText, aGrammar)
|
26
25
|
tokens = aText.scan(/\S+/).map do |lexeme|
|
@@ -11,9 +11,9 @@ module GrammarBExprHelper
|
|
11
11
|
builder = Rley::Syntax::GrammarBuilder.new do
|
12
12
|
add_terminals('+', '*', 'integer')
|
13
13
|
rule 'P' => 'S'
|
14
|
-
rule 'S' => %w
|
14
|
+
rule 'S' => %w[S + M]
|
15
15
|
rule 'S' => 'M'
|
16
|
-
rule 'M' => %w
|
16
|
+
rule 'M' => %w[M * T]
|
17
17
|
rule 'M' => 'T'
|
18
18
|
rule 'T' => 'integer'
|
19
19
|
end
|
@@ -13,17 +13,17 @@ module GrammarL0Helper
|
|
13
13
|
builder = Rley::Syntax::GrammarBuilder.new do
|
14
14
|
add_terminals('Noun', 'Verb', 'Pronoun', 'Proper-Noun')
|
15
15
|
add_terminals('Determiner', 'Preposition')
|
16
|
-
rule 'S' => %w
|
16
|
+
rule 'S' => %w[NP VP]
|
17
17
|
rule 'NP' => 'Pronoun'
|
18
18
|
rule 'NP' => 'Proper-Noun'
|
19
|
-
rule 'NP' => %w
|
20
|
-
rule 'Nominal' => %w
|
19
|
+
rule 'NP' => %w[Determiner Nominal]
|
20
|
+
rule 'Nominal' => %w[Nominal Noun]
|
21
21
|
rule 'Nominal' => 'Noun'
|
22
22
|
rule 'VP' => 'Verb'
|
23
|
-
rule 'VP' => %w
|
24
|
-
rule 'VP' => %w
|
25
|
-
rule 'VP' => %w
|
26
|
-
rule 'PP' => %w
|
23
|
+
rule 'VP' => %w[Verb NP]
|
24
|
+
rule 'VP' => %w[Verb NP PP]
|
25
|
+
rule 'VP' => %w[Verb PP]
|
26
|
+
rule 'PP' => %w[Preposition PP]
|
27
27
|
end
|
28
28
|
builder
|
29
29
|
end
|
@@ -65,7 +65,6 @@ module GrammarL0Helper
|
|
65
65
|
}
|
66
66
|
end
|
67
67
|
|
68
|
-
|
69
68
|
# Highly simplified tokenizer implementation.
|
70
69
|
def tokenizer_l0(aText, aGrammar)
|
71
70
|
tokens = aText.scan(/\S+/).map do |word|
|
@@ -5,7 +5,6 @@ require_relative '../../../lib/rley/tokens/token'
|
|
5
5
|
|
6
6
|
# Utility class.
|
7
7
|
class GrammarPBHelper
|
8
|
-
|
9
8
|
# Factory method. Creates a grammar for a basic arithmetic
|
10
9
|
# expression based on example found in paper of
|
11
10
|
# K. Pingali and G. Bilardi:
|
@@ -20,8 +19,8 @@ class GrammarPBHelper
|
|
20
19
|
add_terminals(t_int, t_plus, t_lparen, t_rparen)
|
21
20
|
rule 'S' => 'E'
|
22
21
|
rule 'E' => 'int'
|
23
|
-
rule 'E' => %w(
|
24
|
-
rule 'E' => %w
|
22
|
+
rule 'E' => %w[( E + E )]
|
23
|
+
rule 'E' => %w[E + E]
|
25
24
|
end
|
26
25
|
builder.grammar
|
27
26
|
end
|
@@ -45,4 +44,4 @@ class GrammarPBHelper
|
|
45
44
|
return tokens
|
46
45
|
end
|
47
46
|
end # module
|
48
|
-
# End of file
|
47
|
+
# End of file
|