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