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,17 @@
|
|
1
|
+
require 'rattler'
|
2
|
+
|
3
|
+
module Rattler::BackEnd::Optimizer
|
4
|
+
# @private
|
5
|
+
module Flattening #:nodoc:
|
6
|
+
|
7
|
+
def _applies_to?(parser, context)
|
8
|
+
parser.any? {|_| eligible_child? _ }
|
9
|
+
end
|
10
|
+
|
11
|
+
def _apply(parser, context)
|
12
|
+
children = parser.map {|_| eligible_child?(_) ? _.to_a : [_] }.reduce(:+)
|
13
|
+
parser.class.new(children, parser.attrs)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/inline_regular_rules.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# References to regular parse rules can be inlined without affecting how they
|
12
|
+
# parse, assuming the referenced rule does not change. This optimization is
|
13
|
+
# only applied if the referenced rule is explicitly marked for inlining or
|
14
|
+
# the :standalone option is used.
|
15
|
+
#
|
16
|
+
# @author Jason Arhart
|
17
|
+
#
|
18
|
+
class InlineRegularRules < Optimization
|
19
|
+
|
20
|
+
include Rattler::Parsers
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def _applies_to?(parser, context)
|
25
|
+
parser.is_a? Apply and
|
26
|
+
inlineable? parser.rule_name, context
|
27
|
+
end
|
28
|
+
|
29
|
+
def _apply(parser, context)
|
30
|
+
optimize context.rules[parser.rule_name].expr, context
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def inlineable?(rule_name, context)
|
36
|
+
inline_allowed? rule_name, context and
|
37
|
+
context.analysis.regular? rule_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def inline_allowed?(rule_name, context)
|
41
|
+
context.standalone? or
|
42
|
+
context.rules[rule_name].attrs[:inline]
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_match_capturing_sequence.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# Sequences of Regexp matches can be joined into a single Regexp match using
|
12
|
+
# capturing groups if necessary.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinMatchCapturingSequence < Optimization
|
17
|
+
include MatchJoining
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
include Rattler::BackEnd::ParserGenerator
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def _applies_to?(parser, context)
|
25
|
+
context.capturing? and
|
26
|
+
parser.is_a?(Sequence) and
|
27
|
+
any_neighbors?(parser) {|_| eligible_child? _ }
|
28
|
+
end
|
29
|
+
|
30
|
+
def eligible_child?(child)
|
31
|
+
child.is_a? Match or
|
32
|
+
(child.is_a? GroupMatch and child.num_groups == 1) or
|
33
|
+
(child.is_a? Skip and child.child.is_a? Match)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_patterns(parsers)
|
37
|
+
num_groups = 0
|
38
|
+
patterns = parsers.map do |parser|
|
39
|
+
case parser
|
40
|
+
|
41
|
+
when Match
|
42
|
+
num_groups += 1
|
43
|
+
"(#{parser.re.source})"
|
44
|
+
|
45
|
+
when GroupMatch
|
46
|
+
num_groups += parser.num_groups
|
47
|
+
"(?>#{parser.re.source})"
|
48
|
+
|
49
|
+
when Skip
|
50
|
+
"(?>#{parser.child.re.source})"
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
return {:patterns => patterns, :num_groups => num_groups }
|
55
|
+
end
|
56
|
+
|
57
|
+
def join_patterns(info)
|
58
|
+
return info.merge(:pattern => info[:patterns].join)
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_match(info)
|
62
|
+
match = super(info[:pattern])
|
63
|
+
if info[:num_groups] > 0
|
64
|
+
GroupMatch[match, {:num_groups => info[:num_groups]}]
|
65
|
+
else
|
66
|
+
Skip[match]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_match_choice.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A choice of Regexp matches can be joined into a single Regexp match without
|
12
|
+
# affecting how it parses.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinMatchChoice < Optimization
|
17
|
+
include MatchJoining
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def _applies_to?(parser, context)
|
24
|
+
parser.is_a?(Choice) and
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def join_patterns(patterns)
|
29
|
+
patterns.join '|'
|
30
|
+
end
|
31
|
+
|
32
|
+
def eligible_child?(child)
|
33
|
+
child.is_a? Match
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_match_matching_sequence.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# Sequences of Regexp matches can be joined into a single Regexp without
|
12
|
+
# affecting how they match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinMatchMatchingSequence < Optimization
|
17
|
+
include MatchJoining
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def _applies_to?(parser, context)
|
24
|
+
context.matching? and
|
25
|
+
parser.is_a?(Sequence) and
|
26
|
+
any_neighbors?(parser) {|_| eligible_child? _ }
|
27
|
+
end
|
28
|
+
|
29
|
+
def eligible_child?(child)
|
30
|
+
child.is_a? Match
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_pattern(match)
|
34
|
+
"(?>#{match.re.source})"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_match_sequence.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler/back_end/optimizer'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# Sequences of Regexp matches can be joined into a single Regexp match using
|
12
|
+
# capturing groups if necessary.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
JoinMatchSequence = JoinMatchMatchingSequence >> JoinMatchCapturingSequence
|
17
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_predicate_bare_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A predicate and an adjacent Regexp match in a Sequence can be joined into a
|
12
|
+
# single Regexp match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinPredicateBareMatch < Optimization
|
17
|
+
include CompositeReducing
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def _applies_to?(parser, context)
|
24
|
+
parser.is_a?(Sequence) and
|
25
|
+
parser.children.each_cons(2).any? {|a, b| eligible_pair? a, b }
|
26
|
+
end
|
27
|
+
|
28
|
+
def _apply(parser, context)
|
29
|
+
a = []
|
30
|
+
parser.each {|_| a << (eligible_pair?(a.last, _) ? reduce(a.pop, _) : _)}
|
31
|
+
finish_reduce parser, a
|
32
|
+
end
|
33
|
+
|
34
|
+
def reduce(*pair)
|
35
|
+
Match[Regexp.new(pair.map {|_| prepare_pattern _ }.join)]
|
36
|
+
end
|
37
|
+
|
38
|
+
def prepare_pattern(child)
|
39
|
+
case child
|
40
|
+
when Match then "(?>#{child.re.source})"
|
41
|
+
when Assert then "(?=#{child.child.re.source})"
|
42
|
+
when Disallow then "(?!#{child.child.re.source})"
|
43
|
+
when Eof then "\\z"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def eligible_pair?(a, b)
|
48
|
+
(eligible_match? a and eligible_predicate? b) or
|
49
|
+
(eligible_predicate? a and eligible_match? b)
|
50
|
+
end
|
51
|
+
|
52
|
+
def eligible_match?(parser)
|
53
|
+
parser.is_a? Match
|
54
|
+
end
|
55
|
+
|
56
|
+
def eligible_predicate?(parser)
|
57
|
+
case parser
|
58
|
+
when Eof
|
59
|
+
true
|
60
|
+
when Assert, Disallow
|
61
|
+
parser.child.is_a? Match
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_predicate_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler/back_end/optimizer'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A predicate and an adjacent Regexp match in a Sequence can be joined into a
|
12
|
+
# single Regexp match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
JoinPredicateMatch = JoinPredicateBareMatch >> JoinPredicateNestedMatch
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_predicate_nested_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A predicate and an adjacent skip of a Regexp match in a Sequence can be
|
12
|
+
# joined into a single skip of a Regexp match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinPredicateNestedMatch < JoinPredicateBareMatch
|
17
|
+
include CompositeReducing
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def reduce(*pair)
|
24
|
+
pair.find {|_| _.is_a? Skip }.with_child super
|
25
|
+
end
|
26
|
+
|
27
|
+
def prepare_pattern(parser)
|
28
|
+
super(parser.is_a?(Skip) ? parser.child : parser)
|
29
|
+
end
|
30
|
+
|
31
|
+
def eligible_match?(parser)
|
32
|
+
parser.is_a? Skip and
|
33
|
+
super parser.child
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_predicate_or_bare_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A predicate and an adjacent Regexp match in a Choice can be joined into a
|
12
|
+
# single Regexp match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
class JoinPredicateOrBareMatch < Optimization
|
17
|
+
include CompositeReducing
|
18
|
+
|
19
|
+
include Rattler::Parsers
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def _applies_to?(parser, context)
|
24
|
+
parser.is_a?(Choice) and
|
25
|
+
parser.children.each_cons(2).any? {|a, b| eligible_pair? a, b }
|
26
|
+
end
|
27
|
+
|
28
|
+
def _apply(parser, context)
|
29
|
+
a = []
|
30
|
+
parser.each {|_| a << (eligible_pair?(a.last, _) ? reduce(a.pop, _) : _)}
|
31
|
+
finish_reduce parser, a
|
32
|
+
end
|
33
|
+
|
34
|
+
def reduce(*pair)
|
35
|
+
Match[Regexp.new(pair.map {|_| prepare_pattern _ }.join '|' )]
|
36
|
+
end
|
37
|
+
|
38
|
+
def prepare_pattern(child)
|
39
|
+
case child
|
40
|
+
when Match then child.re.source
|
41
|
+
when Assert then "(?=#{child.child.re.source})"
|
42
|
+
when Disallow then "(?!#{child.child.re.source})"
|
43
|
+
when Eof then "\\z"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def eligible_pair?(a, b)
|
48
|
+
(eligible_match? a and eligible_predicate? b) or
|
49
|
+
(eligible_predicate? a and eligible_match? b)
|
50
|
+
end
|
51
|
+
|
52
|
+
def eligible_match?(parser)
|
53
|
+
parser.is_a? Match
|
54
|
+
end
|
55
|
+
|
56
|
+
def eligible_predicate?(parser)
|
57
|
+
case parser
|
58
|
+
when Eof
|
59
|
+
true
|
60
|
+
when Assert, Disallow
|
61
|
+
parser.child.is_a? Match
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/join_predicate_or_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler/back_end/optimizer'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A predicate and an adjacent Regexp match in a Choice can be joined into a
|
12
|
+
# single Regexp match.
|
13
|
+
#
|
14
|
+
# @author Jason Arhart
|
15
|
+
#
|
16
|
+
JoinPredicateOrMatch = JoinPredicateOrBareMatch >> JoinPredicateOrNestedMatch
|
17
|
+
end
|