rattler 0.3.0 → 0.4.0
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.
- data/README.rdoc +57 -37
- data/features/command_line/dest_option.feature +8 -21
- data/features/command_line/lib_option.feature +37 -0
- data/features/command_line/parser_generator.feature +7 -4
- data/features/grammar/back_reference.feature +37 -0
- data/features/grammar/fail.feature +3 -3
- data/features/grammar/labels.feature +11 -3
- data/features/grammar/list_matching.feature +14 -5
- data/features/grammar/literal.feature +30 -4
- data/features/grammar/nonterminal.feature +1 -1
- data/features/grammar/ordered_choice.feature +2 -2
- data/features/grammar/skip_operator.feature +1 -1
- data/features/grammar/symantic_action.feature +7 -7
- data/features/grammar/whitespace.feature +2 -2
- data/features/step_definitions/grammar_steps.rb +2 -2
- data/lib/rattler/back_end.rb +1 -0
- data/lib/rattler/back_end/compiler.rb +19 -20
- data/lib/rattler/back_end/optimizer.rb +100 -0
- data/lib/rattler/back_end/optimizer/composite_reducing.rb +18 -0
- data/lib/rattler/back_end/optimizer/flatten_choice.rb +31 -0
- data/lib/rattler/back_end/optimizer/flatten_sequence.rb +59 -0
- data/lib/rattler/back_end/optimizer/flattening.rb +17 -0
- data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +46 -0
- data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rb +71 -0
- data/lib/rattler/back_end/optimizer/join_match_choice.rb +37 -0
- data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rb +38 -0
- data/lib/rattler/back_end/optimizer/join_match_sequence.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rb +68 -0
- data/lib/rattler/back_end/optimizer/join_predicate_match.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rb +37 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rb +68 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +17 -0
- data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rb +36 -0
- data/lib/rattler/back_end/optimizer/match_joining.rb +60 -0
- data/lib/rattler/back_end/optimizer/optimization.rb +94 -0
- data/lib/rattler/back_end/optimizer/optimization_context.rb +72 -0
- data/lib/rattler/back_end/optimizer/optimization_sequence.rb +37 -0
- data/lib/rattler/back_end/optimizer/optimize_children.rb +46 -0
- data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +44 -0
- data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +32 -0
- data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +43 -0
- data/lib/rattler/back_end/optimizer/simplify_token_match.rb +38 -0
- data/lib/rattler/back_end/parser_generator.rb +21 -14
- data/lib/rattler/back_end/parser_generator/apply_generator.rb +35 -35
- data/lib/rattler/back_end/parser_generator/assert_generator.rb +29 -30
- data/lib/rattler/back_end/parser_generator/back_reference_generator.rb +93 -0
- data/lib/rattler/back_end/parser_generator/choice_generator.rb +33 -49
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +14 -14
- data/lib/rattler/back_end/parser_generator/disallow_generator.rb +29 -30
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +11 -13
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +36 -56
- data/lib/rattler/back_end/parser_generator/fail_generator.rb +18 -18
- data/lib/rattler/back_end/parser_generator/group_match.rb +18 -0
- data/lib/rattler/back_end/parser_generator/group_match_generator.rb +76 -0
- data/lib/rattler/back_end/parser_generator/label_generator.rb +25 -6
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +7 -7
- data/lib/rattler/back_end/parser_generator/list_generating.rb +19 -20
- data/lib/rattler/back_end/parser_generator/list_generator.rb +5 -5
- data/lib/rattler/back_end/parser_generator/match_generator.rb +52 -52
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +6 -6
- data/lib/rattler/back_end/parser_generator/optional_generator.rb +30 -29
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +8 -8
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +23 -25
- data/lib/rattler/back_end/parser_generator/rule_generator.rb +27 -79
- data/lib/rattler/back_end/parser_generator/rule_set_generator.rb +102 -0
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +49 -41
- data/lib/rattler/back_end/parser_generator/skip_generator.rb +14 -20
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +4 -4
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +6 -0
- data/lib/rattler/back_end/parser_generator/token_generator.rb +12 -12
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +2 -2
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +4 -4
- data/lib/rattler/grammar.rb +4 -3
- data/lib/rattler/grammar/analysis.rb +91 -0
- data/lib/rattler/grammar/grammar.rb +37 -25
- data/lib/rattler/grammar/grammar_parser.rb +19 -11
- data/lib/rattler/grammar/metagrammar.rb +569 -800
- data/lib/rattler/grammar/rattler.rtlr +162 -144
- data/lib/rattler/parsers.rb +5 -1
- data/lib/rattler/parsers/action_code.rb +29 -15
- data/lib/rattler/parsers/apply.rb +5 -5
- data/lib/rattler/parsers/assert.rb +4 -18
- data/lib/rattler/parsers/back_reference.rb +46 -0
- data/lib/rattler/parsers/choice.rb +6 -39
- data/lib/rattler/parsers/combinator_parser.rb +32 -0
- data/lib/rattler/parsers/combining.rb +3 -29
- data/lib/rattler/parsers/direct_action.rb +27 -30
- data/lib/rattler/parsers/disallow.rb +4 -18
- data/lib/rattler/parsers/dispatch_action.rb +30 -25
- data/lib/rattler/parsers/label.rb +9 -18
- data/lib/rattler/parsers/list.rb +3 -34
- data/lib/rattler/parsers/list1.rb +4 -36
- data/lib/rattler/parsers/list_parser.rb +64 -0
- data/lib/rattler/parsers/match.rb +7 -42
- data/lib/rattler/parsers/node_code.rb +44 -0
- data/lib/rattler/parsers/one_or_more.rb +7 -27
- data/lib/rattler/parsers/optional.rb +5 -25
- data/lib/rattler/parsers/parser.rb +16 -44
- data/lib/rattler/parsers/parser_dsl.rb +13 -3
- data/lib/rattler/parsers/predicate.rb +4 -12
- data/lib/rattler/parsers/rule.rb +18 -19
- data/lib/rattler/parsers/rule_set.rb +63 -0
- data/lib/rattler/parsers/sequence.rb +12 -46
- data/lib/rattler/parsers/skip.rb +12 -26
- data/lib/rattler/parsers/token.rb +6 -21
- data/lib/rattler/parsers/zero_or_more.rb +6 -26
- data/lib/rattler/runner.rb +66 -28
- data/lib/rattler/runtime/extended_packrat_parser.rb +26 -20
- data/lib/rattler/runtime/packrat_parser.rb +17 -21
- data/lib/rattler/runtime/parser.rb +12 -2
- data/lib/rattler/runtime/recursive_descent_parser.rb +3 -11
- data/lib/rattler/util.rb +2 -1
- data/lib/rattler/util/graphviz.rb +29 -0
- data/lib/rattler/util/graphviz/digraph_builder.rb +71 -0
- data/lib/rattler/util/graphviz/node_builder.rb +84 -0
- data/lib/rattler/util/node.rb +37 -19
- data/lib/rattler/util/parser_spec_helper.rb +61 -35
- data/spec/rattler/back_end/compiler_spec.rb +6 -860
- data/spec/rattler/back_end/optimizer/flatten_choice_spec.rb +70 -0
- data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rb +130 -0
- data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +80 -0
- data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rb +241 -0
- data/spec/rattler/back_end/optimizer/join_match_choice_spec.rb +100 -0
- data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rb +112 -0
- data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rb +194 -0
- data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rb +180 -0
- data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rb +153 -0
- data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rb +153 -0
- data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +98 -0
- data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +226 -0
- data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rb +85 -0
- data/spec/rattler/back_end/parser_generator/apply_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/assert_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rb +181 -0
- data/spec/rattler/back_end/parser_generator/choice_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +185 -0
- data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +10 -5
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +10 -5
- data/spec/rattler/back_end/parser_generator/match_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/rule_generator_spec.rb +13 -46
- data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rb +97 -0
- data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/skip_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/token_generator_spec.rb +38 -33
- data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +39 -34
- data/spec/rattler/back_end/shared_compiler_examples.rb +885 -0
- data/spec/rattler/grammar/analysis_spec.rb +167 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +169 -179
- data/spec/rattler/grammar/grammar_spec.rb +24 -21
- data/spec/rattler/parsers/action_code_spec.rb +64 -19
- data/spec/rattler/parsers/apply_spec.rb +9 -9
- data/spec/rattler/parsers/back_reference_spec.rb +38 -0
- data/spec/rattler/parsers/combinator_parser_spec.rb +14 -0
- data/spec/rattler/parsers/direct_action_spec.rb +16 -2
- data/spec/rattler/parsers/dispatch_action_spec.rb +15 -32
- data/spec/rattler/parsers/fail_spec.rb +6 -4
- data/spec/rattler/parsers/label_spec.rb +10 -28
- data/spec/rattler/parsers/node_code_spec.rb +48 -0
- data/spec/rattler/parsers/parser_dsl_spec.rb +1 -1
- data/spec/rattler/parsers/rule_set_spec.rb +35 -0
- data/spec/rattler/parsers/sequence_spec.rb +15 -24
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +22 -17
- data/spec/rattler/runtime/packrat_parser_spec.rb +1 -1
- data/spec/rattler/runtime/parse_node_spec.rb +15 -19
- data/spec/rattler/runtime/recursive_descent_parser_spec.rb +1 -1
- data/spec/rattler/runtime/shared_parser_examples.rb +61 -28
- data/spec/rattler/util/graphviz/node_builder_spec.rb +84 -0
- data/spec/rattler/util/node_spec.rb +92 -65
- data/spec/rattler_spec.rb +16 -16
- data/spec/support/combinator_parser_spec_helper.rb +19 -18
- data/spec/support/compiler_spec_helper.rb +56 -87
- data/spec/support/runtime_parser_spec_helper.rb +6 -14
- metadata +117 -22
- data/features/grammar/regex.feature +0 -24
- data/lib/rattler/parsers/match_joining.rb +0 -67
- data/lib/rattler/parsers/rules.rb +0 -43
@@ -1,22 +1,23 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
2
|
|
3
|
+
include Rattler::BackEnd::ParserGenerator
|
3
4
|
include Rattler::Parsers
|
4
5
|
|
5
|
-
describe
|
6
|
-
|
6
|
+
describe DisallowGenerator do
|
7
|
+
|
7
8
|
include ParserGeneratorSpecHelper
|
8
|
-
|
9
|
+
|
9
10
|
let(:disallow) { Disallow[Match[/\d/]] }
|
10
|
-
|
11
|
+
|
11
12
|
describe '#gen_basic' do
|
12
|
-
|
13
|
+
|
13
14
|
context 'when nested' do
|
14
15
|
it 'generates nested negative lookahead code' do
|
15
16
|
nested_code {|g| g.gen_basic disallow }.
|
16
17
|
should == '(@scanner.skip(/(?!\d)/) && true)'
|
17
18
|
end
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
context 'when top-level' do
|
21
22
|
it 'generates top level negative lookahead code' do
|
22
23
|
top_level_code {|g| g.gen_basic disallow }.
|
@@ -24,31 +25,31 @@ describe Rattler::BackEnd::ParserGenerator::DisallowGenerator do
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
describe '#gen_assert' do
|
29
|
-
|
30
|
+
|
30
31
|
context 'when nested' do
|
31
32
|
it 'generates "false"' do
|
32
33
|
nested_code {|g| g.gen_assert disallow }.should == 'false'
|
33
34
|
end
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
context 'when top-level' do
|
37
38
|
it 'generates "false"' do
|
38
39
|
top_level_code {|g| g.gen_assert disallow }.should == 'false'
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
describe '#gen_disallow' do
|
44
|
-
|
45
|
+
|
45
46
|
context 'when nested' do
|
46
47
|
it 'generates nested negative lookahead code' do
|
47
48
|
nested_code {|g| g.gen_disallow disallow }.
|
48
49
|
should == '(@scanner.skip(/(?!\d)/) && true)'
|
49
50
|
end
|
50
51
|
end
|
51
|
-
|
52
|
+
|
52
53
|
context 'when top-level' do
|
53
54
|
it 'generates top level negative lookahead code' do
|
54
55
|
top_level_code {|g| g.gen_disallow disallow }.
|
@@ -56,12 +57,14 @@ describe Rattler::BackEnd::ParserGenerator::DisallowGenerator do
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
59
|
-
|
60
|
+
|
60
61
|
describe '#gen_dispatch_action' do
|
61
|
-
|
62
|
+
|
63
|
+
let(:code) { NodeCode.new('Word', 'parsed') }
|
64
|
+
|
62
65
|
context 'when nested' do
|
63
66
|
it 'generates nested negative lookahead code with a dispatch action' do
|
64
|
-
nested_code {|g| g.gen_dispatch_action disallow,
|
67
|
+
nested_code {|g| g.gen_dispatch_action disallow, code }.
|
65
68
|
should == (<<-CODE).strip
|
66
69
|
begin
|
67
70
|
@scanner.skip(/(?!\\d)/) &&
|
@@ -70,10 +73,10 @@ end
|
|
70
73
|
CODE
|
71
74
|
end
|
72
75
|
end
|
73
|
-
|
76
|
+
|
74
77
|
context 'when top-level' do
|
75
78
|
it 'generates top level negative lookahead code with a dispatch action' do
|
76
|
-
top_level_code {|g| g.gen_dispatch_action disallow,
|
79
|
+
top_level_code {|g| g.gen_dispatch_action disallow, code }.
|
77
80
|
should == (<<-CODE).strip
|
78
81
|
@scanner.skip(/(?!\\d)/) &&
|
79
82
|
Word.parsed([])
|
@@ -81,12 +84,14 @@ Word.parsed([])
|
|
81
84
|
end
|
82
85
|
end
|
83
86
|
end
|
84
|
-
|
87
|
+
|
85
88
|
describe '#gen_direct_action' do
|
86
|
-
|
89
|
+
|
90
|
+
let(:code) { ActionCode.new(':t') }
|
91
|
+
|
87
92
|
context 'when nested' do
|
88
93
|
it 'generates nested negative lookahead code with a direct action' do
|
89
|
-
nested_code {|g| g.gen_direct_action disallow,
|
94
|
+
nested_code {|g| g.gen_direct_action disallow, code }.
|
90
95
|
should == (<<-CODE).strip
|
91
96
|
begin
|
92
97
|
@scanner.skip(/(?!\\d)/) &&
|
@@ -95,10 +100,10 @@ end
|
|
95
100
|
CODE
|
96
101
|
end
|
97
102
|
end
|
98
|
-
|
103
|
+
|
99
104
|
context 'when top-level' do
|
100
105
|
it 'generates top level negative lookahead code with a direct action' do
|
101
|
-
top_level_code {|g| g.gen_direct_action disallow,
|
106
|
+
top_level_code {|g| g.gen_direct_action disallow, code }.
|
102
107
|
should == (<<-CODE).strip
|
103
108
|
@scanner.skip(/(?!\\d)/) &&
|
104
109
|
(:t)
|
@@ -106,9 +111,9 @@ end
|
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
109
|
-
|
114
|
+
|
110
115
|
describe '#gen_token' do
|
111
|
-
|
116
|
+
|
112
117
|
context 'when nested' do
|
113
118
|
it 'generates nested negative lookahead and empty string string code' do
|
114
119
|
nested_code {|g| g.gen_token disallow }.
|
@@ -120,7 +125,7 @@ end
|
|
120
125
|
CODE
|
121
126
|
end
|
122
127
|
end
|
123
|
-
|
128
|
+
|
124
129
|
context 'when top-level' do
|
125
130
|
it 'generates top-level negative lookahead and empty string string code' do
|
126
131
|
top_level_code {|g| g.gen_token disallow }.
|
@@ -131,16 +136,16 @@ end
|
|
131
136
|
end
|
132
137
|
end
|
133
138
|
end
|
134
|
-
|
139
|
+
|
135
140
|
describe '#gen_skip' do
|
136
|
-
|
141
|
+
|
137
142
|
context 'when nested' do
|
138
143
|
it 'generates nested negative lookahead code' do
|
139
144
|
nested_code {|g| g.gen_skip disallow }.
|
140
145
|
should == '(@scanner.skip(/(?!\d)/) && true)'
|
141
146
|
end
|
142
147
|
end
|
143
|
-
|
148
|
+
|
144
149
|
context 'when top-level' do
|
145
150
|
it 'generates top level negative lookahead code' do
|
146
151
|
top_level_code {|g| g.gen_skip disallow }.
|
@@ -148,32 +153,32 @@ end
|
|
148
153
|
end
|
149
154
|
end
|
150
155
|
end
|
151
|
-
|
156
|
+
|
152
157
|
describe '#gen_intermediate' do
|
153
158
|
it 'generates intermediate negative lookahead code' do
|
154
159
|
nested_code {|g| g.gen_intermediate disallow }.
|
155
160
|
should == '@scanner.skip(/(?!\d)/)'
|
156
161
|
end
|
157
162
|
end
|
158
|
-
|
163
|
+
|
159
164
|
describe '#gen_intermediate_assert' do
|
160
165
|
it 'generates "false"' do
|
161
166
|
nested_code {|g| g.gen_intermediate_assert disallow }.should == 'false'
|
162
167
|
end
|
163
168
|
end
|
164
|
-
|
169
|
+
|
165
170
|
describe '#gen_intermediate_disallow' do
|
166
171
|
it 'generates intermediate negative lookahead code' do
|
167
172
|
nested_code {|g| g.gen_intermediate_disallow disallow }.
|
168
173
|
should == '@scanner.skip(/(?!\d)/)'
|
169
174
|
end
|
170
175
|
end
|
171
|
-
|
176
|
+
|
172
177
|
describe '#gen_intermediate_skip' do
|
173
178
|
it 'generates intermediate negative lookahead code' do
|
174
179
|
nested_code {|g| g.gen_intermediate_skip disallow }.
|
175
180
|
should == '@scanner.skip(/(?!\d)/)'
|
176
181
|
end
|
177
182
|
end
|
178
|
-
|
183
|
+
|
179
184
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
2
|
|
3
|
+
include Rattler::BackEnd::ParserGenerator
|
3
4
|
include Rattler::Parsers
|
4
5
|
|
5
|
-
describe
|
6
|
-
|
6
|
+
describe DispatchActionGenerator do
|
7
|
+
|
7
8
|
include ParserGeneratorSpecHelper
|
8
|
-
|
9
|
+
|
9
10
|
let(:action) { DispatchAction[Match[/\w+/]] }
|
10
|
-
|
11
|
+
|
11
12
|
describe '#gen_basic' do
|
12
|
-
|
13
|
+
|
13
14
|
context 'when nested' do
|
14
15
|
it 'generates nested matching code with a dispatch action' do
|
15
16
|
nested_code {|g| g.gen_basic action }.
|
@@ -21,7 +22,7 @@ end
|
|
21
22
|
CODE
|
22
23
|
end
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
context 'when top-level' do
|
26
27
|
it 'generates top level matching code with a dispatch action' do
|
27
28
|
top_level_code {|g| g.gen_basic action }.
|
@@ -32,16 +33,16 @@ Rattler::Runtime::ParseNode.parsed([r])
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
describe '#gen_assert' do
|
37
|
-
|
38
|
+
|
38
39
|
context 'when nested' do
|
39
40
|
it 'generates nested positive lookahead code' do
|
40
41
|
nested_code {|g| g.gen_assert action }.
|
41
42
|
should == '(@scanner.skip(/(?=\w+)/) && true)'
|
42
43
|
end
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
context 'when top-level' do
|
46
47
|
it 'generates top level positive lookahead code' do
|
47
48
|
top_level_code {|g| g.gen_assert action }.
|
@@ -49,16 +50,16 @@ Rattler::Runtime::ParseNode.parsed([r])
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
describe '#gen_disallow' do
|
54
|
-
|
55
|
+
|
55
56
|
context 'when nested' do
|
56
57
|
it 'generates nested negative lookahead code' do
|
57
58
|
nested_code {|g| g.gen_disallow action }.
|
58
59
|
should == '(@scanner.skip(/(?!\w+)/) && true)'
|
59
60
|
end
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
context 'when top-level' do
|
63
64
|
it 'generates top level negative lookahead code' do
|
64
65
|
top_level_code {|g| g.gen_disallow action }.
|
@@ -66,12 +67,14 @@ Rattler::Runtime::ParseNode.parsed([r])
|
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
describe '#gen_dispatch_action' do
|
71
|
-
|
72
|
+
|
73
|
+
let(:code) { NodeCode.new('Word', 'parsed') }
|
74
|
+
|
72
75
|
context 'when nested' do
|
73
76
|
it 'generates nested matching code with nested dispatch actions' do
|
74
|
-
nested_code {|g| g.gen_dispatch_action action,
|
77
|
+
nested_code {|g| g.gen_dispatch_action action, code }.
|
75
78
|
should == (<<-CODE).strip
|
76
79
|
begin
|
77
80
|
(r = begin
|
@@ -83,10 +86,10 @@ end
|
|
83
86
|
CODE
|
84
87
|
end
|
85
88
|
end
|
86
|
-
|
89
|
+
|
87
90
|
context 'when top-level' do
|
88
91
|
it 'generates top level matching code with nested dispatch actions' do
|
89
|
-
top_level_code {|g| g.gen_dispatch_action action,
|
92
|
+
top_level_code {|g| g.gen_dispatch_action action, code }.
|
90
93
|
should == (<<-CODE).strip
|
91
94
|
(r = begin
|
92
95
|
(r = @scanner.scan(/\\w+/)) &&
|
@@ -97,12 +100,14 @@ Word.parsed([r])
|
|
97
100
|
end
|
98
101
|
end
|
99
102
|
end
|
100
|
-
|
103
|
+
|
101
104
|
describe '#gen_direct_action' do
|
102
|
-
|
105
|
+
|
106
|
+
let(:code) { ActionCode.new('|_| _.children') }
|
107
|
+
|
103
108
|
context 'when nested' do
|
104
109
|
it 'generates nested matching code with a dispatch action and a direct action' do
|
105
|
-
nested_code {|g| g.gen_direct_action action,
|
110
|
+
nested_code {|g| g.gen_direct_action action, code }.
|
106
111
|
should == (<<-CODE).strip
|
107
112
|
begin
|
108
113
|
(r = begin
|
@@ -114,10 +119,10 @@ end
|
|
114
119
|
CODE
|
115
120
|
end
|
116
121
|
end
|
117
|
-
|
122
|
+
|
118
123
|
context 'when top-level' do
|
119
124
|
it 'generates top level matching code with a dispatch action and a direct action' do
|
120
|
-
top_level_code {|g| g.gen_direct_action action,
|
125
|
+
top_level_code {|g| g.gen_direct_action action, code }.
|
121
126
|
should == (<<-CODE).strip
|
122
127
|
(r = begin
|
123
128
|
(r = @scanner.scan(/\\w+/)) &&
|
@@ -128,16 +133,16 @@ end) &&
|
|
128
133
|
end
|
129
134
|
end
|
130
135
|
end
|
131
|
-
|
136
|
+
|
132
137
|
describe '#gen_token' do
|
133
|
-
|
138
|
+
|
134
139
|
context 'when nested' do
|
135
140
|
it 'generates nested token matching code' do
|
136
141
|
nested_code {|g| g.gen_token action }.
|
137
142
|
should == '@scanner.scan(/\w+/)'
|
138
143
|
end
|
139
144
|
end
|
140
|
-
|
145
|
+
|
141
146
|
context 'when top-level' do
|
142
147
|
it 'generates top level token matching code' do
|
143
148
|
top_level_code {|g| g.gen_token action }.
|
@@ -145,16 +150,16 @@ end) &&
|
|
145
150
|
end
|
146
151
|
end
|
147
152
|
end
|
148
|
-
|
153
|
+
|
149
154
|
describe '#gen_skip' do
|
150
|
-
|
155
|
+
|
151
156
|
context 'when nested' do
|
152
157
|
it 'generates nested skipping code' do
|
153
158
|
nested_code {|g| g.gen_skip action }.
|
154
159
|
should == '(@scanner.skip(/\w+/) && true)'
|
155
160
|
end
|
156
161
|
end
|
157
|
-
|
162
|
+
|
158
163
|
context 'when top-level' do
|
159
164
|
it 'generates top level skipping code' do
|
160
165
|
top_level_code {|g| g.gen_skip action }.
|
@@ -162,7 +167,7 @@ end) &&
|
|
162
167
|
end
|
163
168
|
end
|
164
169
|
end
|
165
|
-
|
170
|
+
|
166
171
|
describe '#gen_intermediate' do
|
167
172
|
it 'generates nested matching code with a dispatch action' do
|
168
173
|
nested_code {|g| g.gen_intermediate action }.
|
@@ -174,26 +179,26 @@ end
|
|
174
179
|
CODE
|
175
180
|
end
|
176
181
|
end
|
177
|
-
|
182
|
+
|
178
183
|
describe '#gen_intermediate_assert' do
|
179
184
|
it 'generates intermediate positive lookahead code' do
|
180
185
|
nested_code {|g| g.gen_intermediate_assert action }.
|
181
186
|
should == '@scanner.skip(/(?=\w+)/)'
|
182
187
|
end
|
183
188
|
end
|
184
|
-
|
189
|
+
|
185
190
|
describe '#gen_intermediate_disallow' do
|
186
191
|
it 'generates intermediate negative lookahead code' do
|
187
192
|
nested_code {|g| g.gen_intermediate_disallow action }.
|
188
193
|
should == '@scanner.skip(/(?!\w+)/)'
|
189
194
|
end
|
190
195
|
end
|
191
|
-
|
196
|
+
|
192
197
|
describe '#gen_intermediate_skip' do
|
193
198
|
it 'generates intermediate skipping code' do
|
194
199
|
nested_code {|g| g.gen_intermediate_skip action }.
|
195
200
|
should == '@scanner.skip(/\w+/)'
|
196
201
|
end
|
197
202
|
end
|
198
|
-
|
203
|
+
|
199
204
|
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::BackEnd::ParserGenerator
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe GroupMatchGenerator do
|
7
|
+
|
8
|
+
include ParserGeneratorSpecHelper
|
9
|
+
|
10
|
+
let(:single_group) { GroupMatch[Match[/\s*(\w+)/], {:num_groups => 1}] }
|
11
|
+
|
12
|
+
let(:multi_group) { GroupMatch[Match[/\s*(\w+)\s+(\w+)/], {:num_groups => 2}] }
|
13
|
+
|
14
|
+
describe '#gen_basic' do
|
15
|
+
|
16
|
+
context 'given a single-group match' do
|
17
|
+
|
18
|
+
context 'when nested' do
|
19
|
+
it 'generates nested regex group matching code returning the group' do
|
20
|
+
nested_code {|g| g.gen_basic single_group }.
|
21
|
+
should == (<<-CODE).strip
|
22
|
+
begin
|
23
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
24
|
+
@scanner[1]
|
25
|
+
end
|
26
|
+
CODE
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when top-level' do
|
31
|
+
it 'generates top-level regex group matching code returning the group' do
|
32
|
+
top_level_code {|g| g.gen_basic single_group }.
|
33
|
+
should == (<<-CODE).strip
|
34
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
35
|
+
@scanner[1]
|
36
|
+
CODE
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'given a multi-group match' do
|
42
|
+
|
43
|
+
context 'when nested' do
|
44
|
+
it 'generates nested regex matching code returning an array of groups' do
|
45
|
+
nested_code {|g| g.gen_basic multi_group }.
|
46
|
+
should == (<<-CODE).strip
|
47
|
+
begin
|
48
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
49
|
+
[@scanner[1], @scanner[2]]
|
50
|
+
end
|
51
|
+
CODE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when top-level' do
|
56
|
+
it 'generates top-level regex matching code returning an array of groups' do
|
57
|
+
top_level_code {|g| g.gen_basic multi_group }.
|
58
|
+
should == (<<-CODE).strip
|
59
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
60
|
+
[@scanner[1], @scanner[2]]
|
61
|
+
CODE
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#gen_dispatch_action' do
|
68
|
+
|
69
|
+
let(:code) { NodeCode.new('Word', 'parsed') }
|
70
|
+
|
71
|
+
context 'given a single-group match' do
|
72
|
+
|
73
|
+
let(:match) { single_group }
|
74
|
+
|
75
|
+
context 'when nested' do
|
76
|
+
it 'generates nested regex group matching code with a dispatch action' do
|
77
|
+
nested_code {|g| g.gen_dispatch_action match, code }.
|
78
|
+
should == (<<-CODE).strip
|
79
|
+
begin
|
80
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
81
|
+
Word.parsed([@scanner[1]])
|
82
|
+
end
|
83
|
+
CODE
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when top-level' do
|
88
|
+
it 'generates top-level regex group matching code with a dispatch action' do
|
89
|
+
top_level_code {|g| g.gen_dispatch_action match, code }.
|
90
|
+
should == (<<-CODE).strip
|
91
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
92
|
+
Word.parsed([@scanner[1]])
|
93
|
+
CODE
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'given a multi-group match' do
|
99
|
+
|
100
|
+
let(:match) { multi_group }
|
101
|
+
|
102
|
+
context 'when nested' do
|
103
|
+
it 'generates nested regex group matching code with a dispatch action' do
|
104
|
+
nested_code {|g| g.gen_dispatch_action match, code }.
|
105
|
+
should == (<<-CODE).strip
|
106
|
+
begin
|
107
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
108
|
+
Word.parsed([@scanner[1], @scanner[2]])
|
109
|
+
end
|
110
|
+
CODE
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when top-level' do
|
115
|
+
it 'generates top-level regex group matching code with a dispatch action' do
|
116
|
+
top_level_code {|g| g.gen_dispatch_action match, code }.
|
117
|
+
should == (<<-CODE).strip
|
118
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
119
|
+
Word.parsed([@scanner[1], @scanner[2]])
|
120
|
+
CODE
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#gen_direct_action' do
|
127
|
+
|
128
|
+
context 'given a single-group match' do
|
129
|
+
|
130
|
+
let(:match) { single_group }
|
131
|
+
let(:code) { ActionCode.new('_.to_sym') }
|
132
|
+
|
133
|
+
context 'when nested' do
|
134
|
+
it 'generates nested regex matching code with a direct action' do
|
135
|
+
nested_code {|g| g.gen_direct_action match, code }.
|
136
|
+
should == (<<-CODE).strip
|
137
|
+
begin
|
138
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
139
|
+
(@scanner[1].to_sym)
|
140
|
+
end
|
141
|
+
CODE
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when top-level' do
|
146
|
+
it 'generates top level regex matching code with a direct action' do
|
147
|
+
top_level_code {|g| g.gen_direct_action match, code }.
|
148
|
+
should == (<<-CODE).strip
|
149
|
+
@scanner.skip(/\\s*(\\w+)/) &&
|
150
|
+
(@scanner[1].to_sym)
|
151
|
+
CODE
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'given a multi-group match' do
|
157
|
+
|
158
|
+
let(:match) { multi_group }
|
159
|
+
let(:code) { ActionCode.new('_.size') }
|
160
|
+
|
161
|
+
context 'when nested' do
|
162
|
+
it 'generates nested regex matching code with a direct action' do
|
163
|
+
nested_code {|g| g.gen_direct_action match, code }.
|
164
|
+
should == (<<-CODE).strip
|
165
|
+
begin
|
166
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
167
|
+
([@scanner[1], @scanner[2]].size)
|
168
|
+
end
|
169
|
+
CODE
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when top-level' do
|
174
|
+
it 'generates top level regex matching code with a direct action' do
|
175
|
+
top_level_code {|g| g.gen_direct_action match, code }.
|
176
|
+
should == (<<-CODE).strip
|
177
|
+
@scanner.skip(/\\s*(\\w+)\\s+(\\w+)/) &&
|
178
|
+
([@scanner[1], @scanner[2]].size)
|
179
|
+
CODE
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|