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,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
|