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
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::BackEnd::Optimizer
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe JoinPredicateOrBareMatch do
|
7
|
+
|
8
|
+
let(:match) { Match[/a/] }
|
9
|
+
|
10
|
+
let(:assert) { Assert[Match[/b/]] }
|
11
|
+
let(:disallow) { Disallow[Match[/b/]] }
|
12
|
+
|
13
|
+
describe '#apply' do
|
14
|
+
|
15
|
+
context 'given a choice with a match followed by a predicate' do
|
16
|
+
|
17
|
+
let(:choice) { Choice[Apply[:a], match, predicate] }
|
18
|
+
|
19
|
+
context 'with an assert of a match' do
|
20
|
+
|
21
|
+
let(:predicate) { assert }
|
22
|
+
|
23
|
+
it 'reduces the match and assert into an equivalent single match' do
|
24
|
+
subject.apply(choice, :any).should ==
|
25
|
+
Choice[Apply[:a], Match[/a|(?=b)/]]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with a disallow of a match' do
|
30
|
+
|
31
|
+
let(:predicate) { disallow }
|
32
|
+
|
33
|
+
it 'reduces the match and disallow into an equivalent single match' do
|
34
|
+
subject.apply(choice, :any).should ==
|
35
|
+
Choice[Apply[:a], Match[/a|(?!b)/]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with Eof' do
|
40
|
+
|
41
|
+
let(:predicate) { Eof[] }
|
42
|
+
|
43
|
+
it 'reduces the match and Eof into an equivalent single match' do
|
44
|
+
subject.apply(choice, :any).should ==
|
45
|
+
Choice[Apply[:a], Match[/a|\z/]]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'given a choice with a predicate followed by a match' do
|
51
|
+
|
52
|
+
let(:choice) { Choice[Apply[:a], predicate, match] }
|
53
|
+
|
54
|
+
context 'with an assert of a match' do
|
55
|
+
|
56
|
+
let(:predicate) { assert }
|
57
|
+
|
58
|
+
it 'reduces the match and assert into an equivalent single match' do
|
59
|
+
subject.apply(choice, :any).should ==
|
60
|
+
Choice[Apply[:a], Match[/(?=b)|a/]]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with a disallow of a match' do
|
65
|
+
|
66
|
+
let(:predicate) { disallow }
|
67
|
+
|
68
|
+
it 'reduces the match and disallow into an equivalent single match' do
|
69
|
+
subject.apply(choice, :any).should ==
|
70
|
+
Choice[Apply[:a], Match[/(?!b)|a/]]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with Eof' do
|
75
|
+
|
76
|
+
let(:predicate) { Eof[] }
|
77
|
+
|
78
|
+
it 'reduces the match and Eof into an equivalent single match' do
|
79
|
+
subject.apply(choice, :any).should ==
|
80
|
+
Choice[Apply[:a], Match[/\z|a/]]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#applies_to?' do
|
87
|
+
|
88
|
+
context 'given a choice with a match followed by a predicate' do
|
89
|
+
|
90
|
+
let(:choice) { Choice[Apply[:a], match, predicate] }
|
91
|
+
|
92
|
+
context 'with an assert of a match' do
|
93
|
+
|
94
|
+
let(:predicate) { assert }
|
95
|
+
|
96
|
+
it 'returns true' do
|
97
|
+
subject.applies_to?(choice, :any).should be_true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with a disallow of a match' do
|
102
|
+
|
103
|
+
let(:predicate) { disallow }
|
104
|
+
|
105
|
+
it 'returns true' do
|
106
|
+
subject.applies_to?(choice, :any).should be_true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with Eof' do
|
111
|
+
|
112
|
+
let(:predicate) { Eof[] }
|
113
|
+
|
114
|
+
it 'returns true' do
|
115
|
+
subject.applies_to?(choice, :any).should be_true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'given a choice with a predicate followed by a match' do
|
121
|
+
|
122
|
+
let(:choice) { Choice[Apply[:a], predicate, match] }
|
123
|
+
|
124
|
+
context 'with an assert of a match' do
|
125
|
+
|
126
|
+
let(:predicate) { assert }
|
127
|
+
|
128
|
+
it 'returns true' do
|
129
|
+
subject.applies_to?(choice, :any).should be_true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'with a disallow of a match' do
|
134
|
+
|
135
|
+
let(:predicate) { disallow }
|
136
|
+
|
137
|
+
it 'returns true' do
|
138
|
+
subject.applies_to?(choice, :any).should be_true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'with Eof' do
|
143
|
+
|
144
|
+
let(:predicate) { Eof[] }
|
145
|
+
|
146
|
+
it 'returns true' do
|
147
|
+
subject.applies_to?(choice, :any).should be_true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::BackEnd::Optimizer
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe JoinPredicateOrNestedMatch do
|
7
|
+
|
8
|
+
let(:skip) { Skip[Match[/a/]] }
|
9
|
+
|
10
|
+
let(:assert) { Assert[Match[/b/]] }
|
11
|
+
let(:disallow) { Disallow[Match[/b/]] }
|
12
|
+
|
13
|
+
describe '#apply' do
|
14
|
+
|
15
|
+
context 'given a choice with a skip of a match followed by a predicate' do
|
16
|
+
|
17
|
+
let(:choice) { Choice[Apply[:a], skip, predicate] }
|
18
|
+
|
19
|
+
context 'with an assert of a match' do
|
20
|
+
|
21
|
+
let(:predicate) { assert }
|
22
|
+
|
23
|
+
it 'reduces the match and assert into an equivalent skip of a match' do
|
24
|
+
subject.apply(choice, :any).should ==
|
25
|
+
Choice[Apply[:a], Skip[Match[/a|(?=b)/]]]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with a disallow of a match' do
|
30
|
+
|
31
|
+
let(:predicate) { disallow }
|
32
|
+
|
33
|
+
it 'reduces the match and disallow into an equivalent skip of a match' do
|
34
|
+
subject.apply(choice, :any).should ==
|
35
|
+
Choice[Apply[:a], Skip[Match[/a|(?!b)/]]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with Eof' do
|
40
|
+
|
41
|
+
let(:predicate) { Eof[] }
|
42
|
+
|
43
|
+
it 'reduces the match and Eof into an equivalent skip of a match' do
|
44
|
+
subject.apply(choice, :any).should ==
|
45
|
+
Choice[Apply[:a], Skip[Match[/a|\z/]]]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'given a choice with a predicate followed by a skip of a match' do
|
51
|
+
|
52
|
+
let(:choice) { Choice[Apply[:a], predicate, skip] }
|
53
|
+
|
54
|
+
context 'with an assert of a match' do
|
55
|
+
|
56
|
+
let(:predicate) { assert }
|
57
|
+
|
58
|
+
it 'reduces the match and assert into an equivalent skip of a match' do
|
59
|
+
subject.apply(choice, :any).should ==
|
60
|
+
Choice[Apply[:a], Skip[Match[/(?=b)|a/]]]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with a disallow of a match' do
|
65
|
+
|
66
|
+
let(:predicate) { disallow }
|
67
|
+
|
68
|
+
it 'reduces the match and disallow into an equivalent skip of a match' do
|
69
|
+
subject.apply(choice, :any).should ==
|
70
|
+
Choice[Apply[:a], Skip[Match[/(?!b)|a/]]]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with Eof' do
|
75
|
+
|
76
|
+
let(:predicate) { Eof[] }
|
77
|
+
|
78
|
+
it 'reduces the match and Eof into an equivalent skip of a match' do
|
79
|
+
subject.apply(choice, :any).should ==
|
80
|
+
Choice[Apply[:a], Skip[Match[/\z|a/]]]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#applies_to?' do
|
87
|
+
|
88
|
+
context 'given a choice with a skip of a match followed by a predicate' do
|
89
|
+
|
90
|
+
let(:choice) { Choice[Apply[:a], skip, predicate] }
|
91
|
+
|
92
|
+
context 'with an assert of a match' do
|
93
|
+
|
94
|
+
let(:predicate) { assert }
|
95
|
+
|
96
|
+
it 'returns true' do
|
97
|
+
subject.applies_to?(choice, :any).should be_true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with a disallow of a match' do
|
102
|
+
|
103
|
+
let(:predicate) { disallow }
|
104
|
+
|
105
|
+
it 'returns true' do
|
106
|
+
subject.applies_to?(choice, :any).should be_true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with Eof' do
|
111
|
+
|
112
|
+
let(:predicate) { Eof[] }
|
113
|
+
|
114
|
+
it 'returns true' do
|
115
|
+
subject.applies_to?(choice, :any).should be_true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'given a choice with a predicate followed by a skip of a match' do
|
121
|
+
|
122
|
+
let(:choice) { Choice[Apply[:a], predicate, skip] }
|
123
|
+
|
124
|
+
context 'with an assert of a match' do
|
125
|
+
|
126
|
+
let(:predicate) { assert }
|
127
|
+
|
128
|
+
it 'returns true' do
|
129
|
+
subject.applies_to?(choice, :any).should be_true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'with a disallow of a match' do
|
134
|
+
|
135
|
+
let(:predicate) { disallow }
|
136
|
+
|
137
|
+
it 'returns true' do
|
138
|
+
subject.applies_to?(choice, :any).should be_true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'with Eof' do
|
143
|
+
|
144
|
+
let(:predicate) { Eof[] }
|
145
|
+
|
146
|
+
it 'returns true' do
|
147
|
+
subject.applies_to?(choice, :any).should be_true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::BackEnd::Optimizer
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe ReduceRepeatMatch do
|
7
|
+
|
8
|
+
let(:matching) { OptimizationContext[:type => :matching] }
|
9
|
+
let(:capturing) { OptimizationContext[:type => :capturing] }
|
10
|
+
|
11
|
+
describe '#apply' do
|
12
|
+
|
13
|
+
context 'given a zero-or-more match' do
|
14
|
+
|
15
|
+
let(:repeat) { ZeroOrMore[Match[/a/]] }
|
16
|
+
|
17
|
+
it 'converts it to an equivalent match' do
|
18
|
+
subject.apply(repeat, matching).should == Match[/(?>a)*/]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'given a one-or-more of a match' do
|
23
|
+
|
24
|
+
let(:repeat) { OneOrMore[Match[/a/]] }
|
25
|
+
|
26
|
+
it 'returns true' do
|
27
|
+
subject.apply(repeat, matching).should == Match[/(?>a)+/]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'given an optional match' do
|
32
|
+
|
33
|
+
let(:repeat) { Optional[Match[/a/]] }
|
34
|
+
|
35
|
+
it 'returns true' do
|
36
|
+
subject.apply(repeat, matching).should == Match[/(?>a)?/]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#applies_to?' do
|
42
|
+
|
43
|
+
context 'in the :capturing context' do
|
44
|
+
|
45
|
+
let(:repeat) { ZeroOrMore[Match[/a/]] }
|
46
|
+
|
47
|
+
it 'returns false' do
|
48
|
+
subject.applies_to?(repeat, capturing).should be_false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'given a zero-or-more of a match' do
|
53
|
+
|
54
|
+
let(:repeat) { ZeroOrMore[Match[/a/]] }
|
55
|
+
|
56
|
+
it 'returns true' do
|
57
|
+
subject.applies_to?(repeat, matching).should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'given a one-or-more of a match' do
|
62
|
+
|
63
|
+
let(:repeat) { OneOrMore[Match[/a/]] }
|
64
|
+
|
65
|
+
it 'returns true' do
|
66
|
+
subject.applies_to?(repeat, matching).should be_true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'given an optional match' do
|
71
|
+
|
72
|
+
let(:repeat) { Optional[Match[/a/]] }
|
73
|
+
|
74
|
+
it 'returns true' do
|
75
|
+
subject.applies_to?(repeat, matching).should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'given a repeat of something other than a match' do
|
80
|
+
|
81
|
+
let(:repeat) { ZeroOrMore[Apply[:a]] }
|
82
|
+
|
83
|
+
it 'returns false' do
|
84
|
+
subject.applies_to?(repeat, matching).should be_false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'given something other than a repeat' do
|
89
|
+
|
90
|
+
let(:other) { Assert[Match[/a/]] }
|
91
|
+
|
92
|
+
it 'returns false' do
|
93
|
+
subject.applies_to?(other, matching).should be_false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::BackEnd::Optimizer
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe SimplifyRedundantRepeat do
|
7
|
+
|
8
|
+
let(:matching) { OptimizationContext[:type => :matching] }
|
9
|
+
let(:capturing) { OptimizationContext[:type => :capturing] }
|
10
|
+
|
11
|
+
describe '#apply' do
|
12
|
+
|
13
|
+
context 'given a zero-or-more' do
|
14
|
+
|
15
|
+
let(:parser) { ZeroOrMore[child] }
|
16
|
+
|
17
|
+
context 'with a zero-or-more' do
|
18
|
+
|
19
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
20
|
+
|
21
|
+
it 'returns the inner ZeroOrMore' do
|
22
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with a one-or-more' do
|
27
|
+
|
28
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
29
|
+
|
30
|
+
it 'returns a ZeroOrMore' do
|
31
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with an optional' do
|
36
|
+
|
37
|
+
let(:child) { Optional[Match[/a/]] }
|
38
|
+
|
39
|
+
it 'returns a ZeroOrMore' do
|
40
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'given a one-or-more' do
|
46
|
+
|
47
|
+
let(:parser) { OneOrMore[child] }
|
48
|
+
|
49
|
+
context 'with a zero-or-more' do
|
50
|
+
|
51
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
52
|
+
|
53
|
+
it 'returns the inner ZeroOrMore' do
|
54
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with a one-or-more' do
|
59
|
+
|
60
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
61
|
+
|
62
|
+
it 'returns the inner OneOrMore' do
|
63
|
+
subject.apply(parser, matching).should == OneOrMore[Match[/a/]]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with an optional' do
|
68
|
+
|
69
|
+
let(:child) { Optional[Match[/a/]] }
|
70
|
+
|
71
|
+
it 'returns a ZeroOrMore' do
|
72
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'given an optional' do
|
78
|
+
|
79
|
+
let(:parser) { Optional[child] }
|
80
|
+
|
81
|
+
context 'with a zero-or-more' do
|
82
|
+
|
83
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
84
|
+
|
85
|
+
it 'returns the inner ZeroOrMore' do
|
86
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with a one-or-more' do
|
91
|
+
|
92
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
93
|
+
|
94
|
+
it 'returns a ZeroOrMore' do
|
95
|
+
subject.apply(parser, matching).should == ZeroOrMore[Match[/a/]]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with an optional' do
|
100
|
+
|
101
|
+
let(:child) { Optional[Match[/a/]] }
|
102
|
+
|
103
|
+
it 'returns the inner Optional' do
|
104
|
+
subject.apply(parser, matching).should == Optional[Match[/a/]]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#applies_to?' do
|
111
|
+
|
112
|
+
context 'given a zero-or-more' do
|
113
|
+
|
114
|
+
let(:parser) { ZeroOrMore[child] }
|
115
|
+
|
116
|
+
context 'with a zero-or-more' do
|
117
|
+
|
118
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
119
|
+
|
120
|
+
context 'in the :matching context' do
|
121
|
+
it 'returns true' do
|
122
|
+
subject.applies_to?(parser, matching).should be_true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'in the :capturing context' do
|
127
|
+
it 'returns false' do
|
128
|
+
subject.applies_to?(parser, capturing).should be_false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'with something other than a repeat' do
|
134
|
+
|
135
|
+
let(:child) { Match[/a/] }
|
136
|
+
|
137
|
+
it 'returns false' do
|
138
|
+
subject.applies_to?(parser, matching).should be_false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'with a one-or-more' do
|
143
|
+
|
144
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
145
|
+
|
146
|
+
it 'returns true' do
|
147
|
+
subject.applies_to?(parser, matching).should be_true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'with an optional' do
|
152
|
+
|
153
|
+
let(:child) { Optional[Match[/a/]] }
|
154
|
+
|
155
|
+
it 'returns true' do
|
156
|
+
subject.applies_to?(parser, matching).should be_true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'given a one-or-more' do
|
162
|
+
|
163
|
+
let(:parser) { OneOrMore[child] }
|
164
|
+
|
165
|
+
context 'with a zero-or-more' do
|
166
|
+
|
167
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
168
|
+
|
169
|
+
it 'returns true' do
|
170
|
+
subject.applies_to?(parser, matching).should be_true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'with a one-or-more' do
|
175
|
+
|
176
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
177
|
+
|
178
|
+
it 'returns true' do
|
179
|
+
subject.applies_to?(parser, matching).should be_true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'with an optional' do
|
184
|
+
|
185
|
+
let(:child) { Optional[Match[/a/]] }
|
186
|
+
|
187
|
+
it 'returns true' do
|
188
|
+
subject.applies_to?(parser, matching).should be_true
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'given an optional' do
|
194
|
+
|
195
|
+
let(:parser) { Optional[child] }
|
196
|
+
|
197
|
+
context 'with a zero-or-more' do
|
198
|
+
|
199
|
+
let(:child) { ZeroOrMore[Match[/a/]] }
|
200
|
+
|
201
|
+
it 'returns true' do
|
202
|
+
subject.applies_to?(parser, matching).should be_true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with a one-or-more' do
|
207
|
+
|
208
|
+
let(:child) { OneOrMore[Match[/a/]] }
|
209
|
+
|
210
|
+
it 'returns true' do
|
211
|
+
subject.applies_to?(parser, matching).should be_true
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'with an optional' do
|
216
|
+
|
217
|
+
let(:child) { Optional[Match[/a/]] }
|
218
|
+
|
219
|
+
it 'returns true' do
|
220
|
+
subject.applies_to?(parser, matching).should be_true
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|