rley 0.4.06 → 0.4.07
Sign up to get free protection for your applications and to get access to all the features.
- 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
|