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,38 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/back_end/optimizer/simplify_token_match.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
require 'rattler'
|
8
|
+
|
9
|
+
module Rattler::BackEnd::Optimizer
|
10
|
+
#
|
11
|
+
# A token wrapping a terminal parser is redundant.
|
12
|
+
#
|
13
|
+
# @author Jason Arhart
|
14
|
+
#
|
15
|
+
class SimplifyTokenMatch < Optimization
|
16
|
+
|
17
|
+
include Rattler::Parsers
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def _applies_to?(parser, context)
|
22
|
+
parser.is_a? Token and
|
23
|
+
terminal? parser.child
|
24
|
+
end
|
25
|
+
|
26
|
+
def _apply(parser, context)
|
27
|
+
parser.child
|
28
|
+
end
|
29
|
+
|
30
|
+
def terminal?(parser)
|
31
|
+
case parser
|
32
|
+
when Match, Token, BackReference then true
|
33
|
+
else false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -14,6 +14,7 @@ module Rattler::BackEnd
|
|
14
14
|
#
|
15
15
|
module ParserGenerator
|
16
16
|
|
17
|
+
autoload :RuleSetGenerator, 'rattler/back_end/parser_generator/rule_set_generator'
|
17
18
|
autoload :RuleGenerator, 'rattler/back_end/parser_generator/rule_generator'
|
18
19
|
autoload :ExprGenerator, 'rattler/back_end/parser_generator/expr_generator'
|
19
20
|
autoload :GeneratorHelper, 'rattler/back_end/parser_generator/generator_helper'
|
@@ -39,12 +40,15 @@ module Rattler::BackEnd
|
|
39
40
|
autoload :TokenGenerator, 'rattler/back_end/parser_generator/token_generator'
|
40
41
|
autoload :SkipGenerator, 'rattler/back_end/parser_generator/skip_generator'
|
41
42
|
autoload :LabelGenerator, 'rattler/back_end/parser_generator/label_generator'
|
43
|
+
autoload :BackReferenceGenerator, 'rattler/back_end/parser_generator/back_reference_generator'
|
42
44
|
autoload :FailGenerator, 'rattler/back_end/parser_generator/fail_generator'
|
43
45
|
autoload :RepeatGenerating, 'rattler/back_end/parser_generator/repeat_generating'
|
44
46
|
autoload :ListGenerating, 'rattler/back_end/parser_generator/list_generating'
|
45
47
|
autoload :PredicatePropogating, 'rattler/back_end/parser_generator/predicate_propogating'
|
46
48
|
autoload :TokenPropogating, 'rattler/back_end/parser_generator/token_propogating'
|
47
49
|
autoload :SkipPropogating, 'rattler/back_end/parser_generator/skip_propogating'
|
50
|
+
autoload :GroupMatchGenerator, 'rattler/back_end/parser_generator/group_match_generator'
|
51
|
+
autoload :GroupMatch, 'rattler/back_end/parser_generator/group_match'
|
48
52
|
autoload :GEN_METHOD_NAMES, 'rattler/back_end/parser_generator/gen_method_names'
|
49
53
|
|
50
54
|
# Generate parsing code for a parser model using a ruby generator +g+.
|
@@ -52,50 +56,53 @@ module Rattler::BackEnd
|
|
52
56
|
# @overload generate(g, grammar)
|
53
57
|
# @param [RubyGenerator] g the ruby generator to use
|
54
58
|
# @param [Rattler::Grammar::Grammar] grammar the grammar model
|
55
|
-
# @return
|
59
|
+
# @return g
|
56
60
|
#
|
57
61
|
# @overload generate(g, rules)
|
58
62
|
# @param [RubyGenerator] g the ruby generator to use
|
59
63
|
# @param [Rules] rules the parse rules
|
60
|
-
# @return
|
64
|
+
# @return g
|
61
65
|
#
|
62
66
|
# @overload generate(g, rule)
|
63
67
|
# @param [RubyGenerator] g the ruby generator to use
|
64
68
|
# @param [Rule] rule the parse rule
|
65
|
-
# @return
|
69
|
+
# @return g
|
66
70
|
#
|
67
71
|
# @overload generate(g, parser)
|
68
72
|
# @param [RubyGenerator] g the ruby generator to use
|
69
73
|
# @param [Parser] parser the parser model
|
70
|
-
# @return
|
74
|
+
# @return g
|
71
75
|
#
|
72
|
-
def self.generate(g, parser)
|
73
|
-
|
74
|
-
|
76
|
+
def self.generate(g, parser, opts={})
|
77
|
+
unless opts[:no_optimize]
|
78
|
+
parser = ::Rattler::BackEnd::Optimizer.optimize(parser, opts)
|
79
|
+
end
|
80
|
+
RuleSetGenerator.new(g).generate(parser, opts)
|
81
|
+
g
|
75
82
|
end
|
76
83
|
|
77
84
|
# Generate parsing code for +parser+ using a new {RubyGenerator} with the
|
78
85
|
# given options and return the generated code.
|
79
86
|
#
|
80
|
-
# @overload code_for(grammar,
|
87
|
+
# @overload code_for(grammar, opts)
|
81
88
|
# @param [Rattler::Grammar::Grammar] grammar the grammar model
|
82
89
|
# @return [String] the generated code
|
83
90
|
#
|
84
|
-
# @overload code_for(rules,
|
91
|
+
# @overload code_for(rules, opts)
|
85
92
|
# @param [Rules] rules the parse rules
|
86
93
|
# @return [String] the generated code
|
87
94
|
#
|
88
|
-
# @overload code_for(rule,
|
95
|
+
# @overload code_for(rule, opts)
|
89
96
|
# @param [Rule] rule the parse rule
|
90
97
|
# @return [String] the generated code
|
91
98
|
#
|
92
|
-
# @overload code_for(parser,
|
99
|
+
# @overload code_for(parser, opts)
|
93
100
|
# @param [Parser] parser the parser model
|
94
101
|
# @return [String] the generated code
|
95
102
|
#
|
96
|
-
def self.code_for(parser,
|
97
|
-
::Rattler::BackEnd::RubyGenerator.code(
|
103
|
+
def self.code_for(parser, opts={})
|
104
|
+
::Rattler::BackEnd::RubyGenerator.code(opts) {|g| generate g, parser, opts }
|
98
105
|
end
|
99
106
|
|
100
107
|
end
|
101
|
-
end
|
108
|
+
end
|
@@ -1,87 +1,87 @@
|
|
1
1
|
require 'rattler/back_end/parser_generator'
|
2
2
|
|
3
3
|
module Rattler::BackEnd::ParserGenerator
|
4
|
-
|
4
|
+
|
5
5
|
# @private
|
6
6
|
class ApplyGenerator < ExprGenerator #:nodoc:
|
7
|
-
|
8
|
-
def gen_basic(apply)
|
7
|
+
|
8
|
+
def gen_basic(apply, scope={})
|
9
9
|
@g << "match(:#{apply.rule_name})"
|
10
10
|
end
|
11
|
-
|
12
|
-
def gen_assert_nested(apply)
|
11
|
+
|
12
|
+
def gen_assert_nested(apply, scope={})
|
13
13
|
atomic_block { gen_assert_top_level apply }
|
14
14
|
end
|
15
|
-
|
16
|
-
def gen_assert_top_level(apply)
|
15
|
+
|
16
|
+
def gen_assert_top_level(apply, scope={})
|
17
17
|
lookahead do
|
18
18
|
@g.surround("#{result_name} = (", ')') { gen_skip_top_level apply }
|
19
19
|
@g.newline
|
20
20
|
end
|
21
21
|
@g << result_name
|
22
22
|
end
|
23
|
-
|
24
|
-
def gen_disallow_nested(apply)
|
23
|
+
|
24
|
+
def gen_disallow_nested(apply, scope={})
|
25
25
|
atomic_block { gen_disallow_top_level apply }
|
26
26
|
end
|
27
|
-
|
28
|
-
def gen_disallow_top_level(apply)
|
27
|
+
|
28
|
+
def gen_disallow_top_level(apply, scope={})
|
29
29
|
lookahead do
|
30
30
|
@g.surround("#{result_name} = !", '') { gen_basic_nested apply }
|
31
31
|
@g.newline
|
32
32
|
end
|
33
33
|
@g << result_name
|
34
34
|
end
|
35
|
-
|
36
|
-
def gen_dispatch_action_nested(apply,
|
37
|
-
atomic_expr { gen_dispatch_action_top_level apply,
|
35
|
+
|
36
|
+
def gen_dispatch_action_nested(apply, code, scope={})
|
37
|
+
atomic_expr { gen_dispatch_action_top_level apply, code }
|
38
38
|
end
|
39
|
-
|
40
|
-
def gen_dispatch_action_top_level(apply,
|
39
|
+
|
40
|
+
def gen_dispatch_action_top_level(apply, code, scope={})
|
41
41
|
@g.surround("(#{result_name} = ", ')') { gen_basic apply }
|
42
|
-
@g << ' && ' <<
|
42
|
+
@g << ' && ' << code.bind(scope, "[#{result_name}]")
|
43
43
|
end
|
44
|
-
|
45
|
-
def gen_direct_action_nested(apply,
|
46
|
-
atomic_expr { gen_direct_action_top_level apply,
|
44
|
+
|
45
|
+
def gen_direct_action_nested(apply, code, scope={})
|
46
|
+
atomic_expr { gen_direct_action_top_level apply, code }
|
47
47
|
end
|
48
|
-
|
49
|
-
def gen_direct_action_top_level(apply,
|
48
|
+
|
49
|
+
def gen_direct_action_top_level(apply, code, scope={})
|
50
50
|
@g.surround("(#{result_name} = ", ')') { gen_basic apply }
|
51
|
-
@g << ' && ' <<
|
51
|
+
@g << ' && (' << code.bind(scope, [result_name]) << ')'
|
52
52
|
end
|
53
|
-
|
54
|
-
def gen_skip_nested(apply)
|
53
|
+
|
54
|
+
def gen_skip_nested(apply, scope={})
|
55
55
|
atomic_expr { gen_skip_top_level apply }
|
56
56
|
end
|
57
|
-
|
58
|
-
def gen_skip_top_level(apply)
|
57
|
+
|
58
|
+
def gen_skip_top_level(apply, scope={})
|
59
59
|
gen_intermediate_skip apply
|
60
60
|
@g << ' && true'
|
61
61
|
end
|
62
|
-
|
63
|
-
def gen_intermediate_skip(apply)
|
62
|
+
|
63
|
+
def gen_intermediate_skip(apply, scope={})
|
64
64
|
gen_basic apply
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
# @private
|
70
70
|
class NestedApplyGenerator < ApplyGenerator #:nodoc:
|
71
71
|
include Nested
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def ApplyGenerator.nested(*args)
|
75
75
|
NestedApplyGenerator.new(*args)
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# @private
|
79
79
|
class TopLevelApplyGenerator < ApplyGenerator #:nodoc:
|
80
80
|
include TopLevel
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def ApplyGenerator.top_level(*args)
|
84
84
|
TopLevelApplyGenerator.new(*args)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
end
|
@@ -5,67 +5,66 @@ module Rattler::BackEnd::ParserGenerator
|
|
5
5
|
# @private
|
6
6
|
class AssertGenerator < ExprGenerator #:nodoc:
|
7
7
|
|
8
|
-
def gen_basic(assert)
|
9
|
-
generate assert.child, :assert
|
8
|
+
def gen_basic(assert, scope={})
|
9
|
+
generate assert.child, :assert, scope
|
10
10
|
end
|
11
11
|
|
12
|
-
def gen_assert(assert)
|
13
|
-
gen_basic assert
|
12
|
+
def gen_assert(assert, scope={})
|
13
|
+
gen_basic assert, scope
|
14
14
|
end
|
15
15
|
|
16
|
-
def gen_disallow(assert)
|
16
|
+
def gen_disallow(assert, scope={})
|
17
17
|
@g << 'false'
|
18
18
|
end
|
19
19
|
|
20
|
-
def gen_skip_nested(assert)
|
21
|
-
gen_basic_nested assert
|
20
|
+
def gen_skip_nested(assert, scope={})
|
21
|
+
gen_basic_nested assert, scope
|
22
22
|
end
|
23
23
|
|
24
|
-
def gen_skip_top_level(assert)
|
25
|
-
gen_basic_top_level assert
|
24
|
+
def gen_skip_top_level(assert, scope={})
|
25
|
+
gen_basic_top_level assert, scope
|
26
26
|
end
|
27
27
|
|
28
|
-
def gen_dispatch_action_nested(assert,
|
29
|
-
atomic_block { gen_dispatch_action_top_level assert,
|
28
|
+
def gen_dispatch_action_nested(assert, code, scope={})
|
29
|
+
atomic_block { gen_dispatch_action_top_level assert, code, scope }
|
30
30
|
end
|
31
31
|
|
32
|
-
def gen_dispatch_action_top_level(assert,
|
33
|
-
gen_action assert,
|
34
|
-
dispatch_action_result(target, method_name, :array_expr => '[]')
|
32
|
+
def gen_dispatch_action_top_level(assert, code, scope={})
|
33
|
+
gen_action assert, code.bind(scope, '[]'), scope
|
35
34
|
end
|
36
35
|
|
37
|
-
def gen_direct_action_nested(assert, code)
|
38
|
-
atomic_block { gen_direct_action_top_level assert, code }
|
36
|
+
def gen_direct_action_nested(assert, code, scope={})
|
37
|
+
atomic_block { gen_direct_action_top_level assert, code, scope }
|
39
38
|
end
|
40
39
|
|
41
|
-
def gen_direct_action_top_level(assert, code)
|
42
|
-
gen_action assert,
|
40
|
+
def gen_direct_action_top_level(assert, code, scope={})
|
41
|
+
gen_action assert, "(#{code.bind scope, []})", scope
|
43
42
|
end
|
44
43
|
|
45
|
-
def gen_token_nested(assert)
|
46
|
-
atomic_block { gen_token_top_level assert }
|
44
|
+
def gen_token_nested(assert, scope={})
|
45
|
+
atomic_block { gen_token_top_level assert, scope }
|
47
46
|
end
|
48
47
|
|
49
|
-
def gen_token_top_level(assert)
|
50
|
-
gen_action assert, "''"
|
48
|
+
def gen_token_top_level(assert, scope={})
|
49
|
+
gen_action assert, "''", scope
|
51
50
|
end
|
52
51
|
|
53
|
-
def gen_intermediate(assert)
|
54
|
-
generate assert.child, :intermediate_assert
|
52
|
+
def gen_intermediate(assert, scope={})
|
53
|
+
generate assert.child, :intermediate_assert, scope
|
55
54
|
end
|
56
55
|
|
57
|
-
def gen_intermediate_assert(assert)
|
58
|
-
gen_intermediate assert
|
56
|
+
def gen_intermediate_assert(assert, scope={})
|
57
|
+
gen_intermediate assert, scope
|
59
58
|
end
|
60
59
|
|
61
|
-
def gen_intermediate_skip(assert)
|
62
|
-
gen_intermediate assert
|
60
|
+
def gen_intermediate_skip(assert, scope={})
|
61
|
+
gen_intermediate assert, scope
|
63
62
|
end
|
64
63
|
|
65
64
|
private
|
66
65
|
|
67
|
-
def gen_action(assert, result_code)
|
68
|
-
gen_intermediate assert
|
66
|
+
def gen_action(assert, result_code, scope={})
|
67
|
+
gen_intermediate assert, scope
|
69
68
|
(@g << ' &&').newline << result_code
|
70
69
|
end
|
71
70
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rattler/back_end/parser_generator'
|
2
|
+
|
3
|
+
module Rattler::BackEnd::ParserGenerator
|
4
|
+
|
5
|
+
# @private
|
6
|
+
class BackReferenceGenerator < ExprGenerator #:nodoc:
|
7
|
+
|
8
|
+
def gen_basic(ref, scope={})
|
9
|
+
@g << "@scanner.scan(#{ref.re_expr(scope)})"
|
10
|
+
end
|
11
|
+
|
12
|
+
def gen_assert_nested(ref, scope={})
|
13
|
+
atomic_expr { gen_assert_top_level ref, scope }
|
14
|
+
end
|
15
|
+
|
16
|
+
def gen_assert_top_level(ref, scope={})
|
17
|
+
gen_intermediate_assert ref, scope
|
18
|
+
@g << ' && true'
|
19
|
+
end
|
20
|
+
|
21
|
+
def gen_disallow_nested(ref, scope={})
|
22
|
+
atomic_expr { gen_disallow_top_level ref, scope }
|
23
|
+
end
|
24
|
+
|
25
|
+
def gen_disallow_top_level(ref, scope={})
|
26
|
+
gen_intermediate_disallow ref, scope
|
27
|
+
@g << ' && true'
|
28
|
+
end
|
29
|
+
|
30
|
+
def gen_dispatch_action_nested(ref, code, scope={})
|
31
|
+
atomic_block { gen_dispatch_action_top_level ref, code, scope }
|
32
|
+
end
|
33
|
+
|
34
|
+
def gen_dispatch_action_top_level(ref, code, scope={})
|
35
|
+
@g.surround("(#{result_name} = ", ')') { gen_basic ref, scope }
|
36
|
+
(@g << ' &&').newline << code.bind(scope, "[#{result_name}]")
|
37
|
+
end
|
38
|
+
|
39
|
+
def gen_direct_action_nested(ref, code, scope={})
|
40
|
+
atomic_block { gen_direct_action_top_level ref, code, scope }
|
41
|
+
end
|
42
|
+
|
43
|
+
def gen_direct_action_top_level(ref, code, scope={})
|
44
|
+
@g.surround("(#{result_name} = ", ')') { gen_basic ref, scope }
|
45
|
+
(@g << ' &&').newline << '(' << code.bind(scope, [result_name]) << ')'
|
46
|
+
end
|
47
|
+
|
48
|
+
def gen_token(ref, scope={})
|
49
|
+
gen_basic ref, scope
|
50
|
+
end
|
51
|
+
|
52
|
+
def gen_skip_nested(ref, scope={})
|
53
|
+
atomic_expr { gen_skip_top_level ref, scope }
|
54
|
+
end
|
55
|
+
|
56
|
+
def gen_skip_top_level(ref, scope={})
|
57
|
+
gen_intermediate_skip ref, scope
|
58
|
+
@g << ' && true'
|
59
|
+
end
|
60
|
+
|
61
|
+
def gen_intermediate_assert(ref, scope={})
|
62
|
+
@g << "@scanner.skip(/(?=#{ref.re_source(scope)})/)"
|
63
|
+
end
|
64
|
+
|
65
|
+
def gen_intermediate_disallow(ref, scope={})
|
66
|
+
@g << "@scanner.skip(/(?!#{ref.re_source(scope)})/)"
|
67
|
+
end
|
68
|
+
|
69
|
+
def gen_intermediate_skip(ref, scope={})
|
70
|
+
@g << "@scanner.skip(#{ref.re_expr(scope)})"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# @private
|
76
|
+
class NestedBackReferenceGenerator < BackReferenceGenerator #:nodoc:
|
77
|
+
include Nested
|
78
|
+
end
|
79
|
+
|
80
|
+
def BackReferenceGenerator.nested(*args)
|
81
|
+
NestedBackReferenceGenerator.new(*args)
|
82
|
+
end
|
83
|
+
|
84
|
+
# @private
|
85
|
+
class TopLevelBackReferenceGenerator < BackReferenceGenerator #:nodoc:
|
86
|
+
include TopLevel
|
87
|
+
end
|
88
|
+
|
89
|
+
def BackReferenceGenerator.top_level(*args)
|
90
|
+
TopLevelBackReferenceGenerator.new(*args)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -6,100 +6,84 @@ module Rattler::BackEnd::ParserGenerator
|
|
6
6
|
class ChoiceGenerator < ExprGenerator #:nodoc:
|
7
7
|
include NestedSubGenerating
|
8
8
|
|
9
|
-
def gen_basic_nested(choice)
|
10
|
-
atomic_block { gen_basic_top_level choice }
|
9
|
+
def gen_basic_nested(choice, scope={})
|
10
|
+
atomic_block { gen_basic_top_level choice, scope }
|
11
11
|
end
|
12
12
|
|
13
|
-
def gen_basic_top_level(choice)
|
14
|
-
@g.intersperse_nl(choice, ' ||') {|_| generate _ }
|
13
|
+
def gen_basic_top_level(choice, scope={})
|
14
|
+
@g.intersperse_nl(choice, ' ||') {|_| generate _, :basic, scope }
|
15
15
|
end
|
16
16
|
|
17
|
-
def gen_assert_nested(choice)
|
18
|
-
atomic_expr { gen_assert_top_level choice }
|
17
|
+
def gen_assert_nested(choice, scope={})
|
18
|
+
atomic_expr { gen_assert_top_level choice, scope }
|
19
19
|
end
|
20
20
|
|
21
|
-
def gen_assert_top_level(choice)
|
22
|
-
gen_intermediate_assert choice
|
21
|
+
def gen_assert_top_level(choice, scope={})
|
22
|
+
gen_intermediate_assert choice, scope
|
23
23
|
@g << ' && true'
|
24
24
|
end
|
25
25
|
|
26
|
-
def gen_disallow(choice)
|
26
|
+
def gen_disallow(choice, scope={})
|
27
27
|
@g << '!'
|
28
|
-
gen_intermediate_assert choice
|
28
|
+
gen_intermediate_assert choice, scope
|
29
29
|
end
|
30
30
|
|
31
|
-
def gen_dispatch_action_nested(choice,
|
32
|
-
atomic_block { gen_dispatch_action_top_level choice,
|
31
|
+
def gen_dispatch_action_nested(choice, code, scope={})
|
32
|
+
atomic_block { gen_dispatch_action_top_level choice, code, scope }
|
33
33
|
end
|
34
34
|
|
35
|
-
def gen_dispatch_action_top_level(choice,
|
36
|
-
gen_action_code
|
37
|
-
dispatch_action_result(target, method_name, :labeled => labeled)
|
38
|
-
end
|
35
|
+
def gen_dispatch_action_top_level(choice, code, scope={})
|
36
|
+
gen_action_code(choice) { code.bind scope, "[#{result_name}]" }
|
39
37
|
end
|
40
38
|
|
41
|
-
def gen_direct_action_nested(choice,
|
42
|
-
atomic_block { gen_direct_action_top_level choice,
|
39
|
+
def gen_direct_action_nested(choice, code, scope={})
|
40
|
+
atomic_block { gen_direct_action_top_level choice, code }
|
43
41
|
end
|
44
42
|
|
45
|
-
def gen_direct_action_top_level(choice,
|
46
|
-
gen_action_code
|
47
|
-
direct_action_result(action, :labeled => labeled)
|
48
|
-
end
|
43
|
+
def gen_direct_action_top_level(choice, code, scope={})
|
44
|
+
gen_action_code(choice) { "(#{code.bind scope, [result_name]})" }
|
49
45
|
end
|
50
46
|
|
51
|
-
def gen_token_nested(choice)
|
52
|
-
atomic_block { gen_token_top_level choice }
|
47
|
+
def gen_token_nested(choice, scope={})
|
48
|
+
atomic_block { gen_token_top_level choice, scope }
|
53
49
|
end
|
54
50
|
|
55
|
-
def gen_token_top_level(choice)
|
56
|
-
@g.intersperse_nl(choice, ' ||') {|_| generate _, :token }
|
51
|
+
def gen_token_top_level(choice, scope={})
|
52
|
+
@g.intersperse_nl(choice, ' ||') {|_| generate _, :token, scope }
|
57
53
|
end
|
58
54
|
|
59
|
-
def gen_skip_nested(choice)
|
60
|
-
@g.surround('(', ')') { gen_skip_top_level choice }
|
55
|
+
def gen_skip_nested(choice, scope={})
|
56
|
+
@g.surround('(', ')') { gen_skip_top_level choice, scope }
|
61
57
|
end
|
62
58
|
|
63
|
-
def gen_skip_top_level(choice)
|
64
|
-
gen_intermediate_skip choice
|
59
|
+
def gen_skip_top_level(choice, scope={})
|
60
|
+
gen_intermediate_skip choice, scope
|
65
61
|
@g << ' && true'
|
66
62
|
end
|
67
63
|
|
68
|
-
def gen_intermediate_assert(choice)
|
64
|
+
def gen_intermediate_assert(choice, scope={})
|
69
65
|
atomic_block do
|
70
66
|
@g.intersperse_nl(choice, ' ||') do |_|
|
71
|
-
generate _, :intermediate_assert
|
67
|
+
generate _, :intermediate_assert, scope
|
72
68
|
end
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
76
|
-
def gen_intermediate_skip(choice)
|
72
|
+
def gen_intermediate_skip(choice, scope={})
|
77
73
|
atomic_block do
|
78
74
|
@g.intersperse_nl(choice, ' ||') do |_|
|
79
|
-
generate _, :intermediate_skip
|
75
|
+
generate _, :intermediate_skip, scope
|
80
76
|
end
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
84
80
|
private
|
85
81
|
|
86
|
-
def gen_action_code(choice)
|
87
|
-
labeled = choice.any? {|_| _.labeled? } ? labeled_name : nil
|
82
|
+
def gen_action_code(choice, scope={})
|
88
83
|
@g.block("(#{result_name} = begin", 'end)') do
|
89
|
-
|
90
|
-
@g.intersperse_nl(choice, ' ||') do |child|
|
91
|
-
if child.labeled?
|
92
|
-
atomic_expr do
|
93
|
-
@g.surround("(#{result_name} = ", ')') { generate child }
|
94
|
-
@g << " && (#{labeled} = {:#{child.label} => #{result_name}})"
|
95
|
-
@g << " && #{result_name}"
|
96
|
-
end
|
97
|
-
else
|
98
|
-
generate child
|
99
|
-
end
|
100
|
-
end
|
84
|
+
@g.intersperse_nl(choice, ' ||') {|child| generate child }
|
101
85
|
end << ' && '
|
102
|
-
@g << yield
|
86
|
+
@g << yield
|
103
87
|
end
|
104
88
|
|
105
89
|
def labeled_name
|