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
data/lib/rattler/parsers/list.rb
CHANGED
@@ -15,41 +15,10 @@ module Rattler::Parsers
|
|
15
15
|
#
|
16
16
|
# @author Jason Arhart
|
17
17
|
#
|
18
|
-
class List <
|
19
|
-
|
18
|
+
class List < ListParser
|
19
|
+
protected
|
20
20
|
|
21
|
-
|
22
|
-
def self.parsed(results, *_) #:nodoc:
|
23
|
-
self[*results]
|
24
|
-
end
|
25
|
-
|
26
|
-
# Create a new list parser that matches terms with +term_parser+ and
|
27
|
-
# separators with +sep_parser+
|
28
|
-
def self.[](term_parser, sep_parser)
|
29
|
-
self.new(term_parser, :sep_parser => sep_parser)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Parse terms matched by the term parser in a list with separators matched
|
33
|
-
# by the separator parser. Return the terms in an array, or +true+ if the
|
34
|
-
# term parser is not <tt>capturing?</tt>.
|
35
|
-
#
|
36
|
-
# @param (see Parser#parse_labeled)
|
37
|
-
#
|
38
|
-
# @return [Array, true] an array containing the term parser's parse results,
|
39
|
-
# or +true+ if the term parser is not <tt>capturing?</tt>
|
40
|
-
def parse(scanner, rules, labeled = {})
|
41
|
-
a = []
|
42
|
-
p = scanner.pos
|
43
|
-
while result = child.parse(scanner, rules)
|
44
|
-
p = scanner.pos
|
45
|
-
a << result
|
46
|
-
break unless sep_parser.parse(scanner, rules)
|
47
|
-
end
|
48
|
-
scanner.pos = p
|
49
|
-
capturing? ? a : true
|
50
|
-
end
|
51
|
-
|
52
|
-
def variable_capture_count?
|
21
|
+
def enough?(results)
|
53
22
|
true
|
54
23
|
end
|
55
24
|
|
@@ -15,43 +15,11 @@ module Rattler::Parsers
|
|
15
15
|
#
|
16
16
|
# @author Jason Arhart
|
17
17
|
#
|
18
|
-
class List1 <
|
19
|
-
|
18
|
+
class List1 < ListParser
|
19
|
+
protected
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
self[*results]
|
24
|
-
end
|
25
|
-
|
26
|
-
# Create a new list1 parser that matches terms with +term_parser+ and
|
27
|
-
# separators with +sep_parser+
|
28
|
-
def self.[](term_parser, sep_parser)
|
29
|
-
self.new(term_parser, :sep_parser => sep_parser)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Parse terms matched by the term parser in a list with separators matched
|
33
|
-
# by the separator parser. Return the terms in an array, or +true+ if the
|
34
|
-
# term parser is not <tt>capturing?</tt>, or +false+ if no terms matched..
|
35
|
-
#
|
36
|
-
# @param (see Parser#parse_labeled)
|
37
|
-
#
|
38
|
-
# @return [Array, true] an array containing the term parser's parse results,
|
39
|
-
# or +true+ if the term parser is not <tt>capturing?</tt>, or +false+ if
|
40
|
-
# no terms matched.
|
41
|
-
def parse(scanner, rules, labeled = {})
|
42
|
-
a = []
|
43
|
-
p = scanner.pos
|
44
|
-
while result = child.parse(scanner, rules)
|
45
|
-
p = scanner.pos
|
46
|
-
a << result
|
47
|
-
break unless sep_parser.parse(scanner, rules)
|
48
|
-
end
|
49
|
-
scanner.pos = p
|
50
|
-
(capturing? ? a : true) unless a.empty?
|
51
|
-
end
|
52
|
-
|
53
|
-
def variable_capture_count?
|
54
|
-
true
|
21
|
+
def enough?(results)
|
22
|
+
not results.empty?
|
55
23
|
end
|
56
24
|
|
57
25
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/parsers/list.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rattler/parsers'
|
9
|
+
|
10
|
+
module Rattler::Parsers
|
11
|
+
#
|
12
|
+
# +ListParser+ matches terms matched by a term parser in a list with
|
13
|
+
# separators matched by a separator parser.
|
14
|
+
#
|
15
|
+
# @author Jason Arhart
|
16
|
+
#
|
17
|
+
class ListParser < Parser
|
18
|
+
include Combining
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def self.parsed(results, *_) #:nodoc:
|
22
|
+
self[*results]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create a new list parser that matches terms with +term_parser+ and
|
26
|
+
# separators with +sep_parser+
|
27
|
+
def self.[](term_parser, sep_parser)
|
28
|
+
self.new(term_parser, sep_parser.skip)
|
29
|
+
end
|
30
|
+
|
31
|
+
def term_parser
|
32
|
+
children[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def sep_parser
|
36
|
+
children[1]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Parse terms matched by the term parser in a list with separators matched
|
40
|
+
# by the separator parser. Return the terms in an array, or +true+ if the
|
41
|
+
# term parser is not <tt>capturing?</tt>.
|
42
|
+
#
|
43
|
+
# @param (see Parser#parse_labeled)
|
44
|
+
#
|
45
|
+
# @return [Array, true] an array containing the term parser's parse results,
|
46
|
+
# or +true+ if the term parser is not <tt>capturing?</tt>
|
47
|
+
def parse(scanner, rules, scope = {})
|
48
|
+
a = []
|
49
|
+
p = scanner.pos
|
50
|
+
while result = term_parser.parse(scanner, rules, scope)
|
51
|
+
p = scanner.pos
|
52
|
+
a << result
|
53
|
+
break unless sep_parser.parse(scanner, rules, scope)
|
54
|
+
end
|
55
|
+
scanner.pos = p
|
56
|
+
(capturing? ? a : true) if enough? a
|
57
|
+
end
|
58
|
+
|
59
|
+
def variable_capture_count?
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -16,7 +16,7 @@ module Rattler::Parsers
|
|
16
16
|
# @author Jason Arhart
|
17
17
|
#
|
18
18
|
class Match < Parser
|
19
|
-
|
19
|
+
|
20
20
|
# Create a new parser that matches with +re+.
|
21
21
|
#
|
22
22
|
# @param [Regexp] re the pattern to match
|
@@ -26,62 +26,27 @@ module Rattler::Parsers
|
|
26
26
|
def self.[](re)
|
27
27
|
self.new(:re => re)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# @private
|
31
31
|
def self.parsed(results, *_) #:nodoc:
|
32
32
|
self[eval(results.first)]
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
# If the +Regexp+ matches at the parse position, return the matched
|
36
36
|
# string, otherwise return a false value.
|
37
37
|
#
|
38
38
|
# @param (see Parser#parse_labeled)
|
39
39
|
#
|
40
40
|
# @return the matched string, or +nil+
|
41
|
-
def parse(scanner, rules,
|
41
|
+
def parse(scanner, rules, scope={})
|
42
42
|
scanner.scan re
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
# @param (see Parser#with_ws)
|
46
46
|
# @return (see Parser#with_ws)
|
47
47
|
def with_ws(ws)
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
# @private
|
52
|
-
def re_optional #:nodoc:
|
53
|
-
Match[/#{atomic_re.source}?/]
|
54
|
-
end
|
55
|
-
|
56
|
-
# @private
|
57
|
-
def re_zero_or_more #:nodoc:
|
58
|
-
Match[/#{atomic_re.source}*/]
|
59
|
-
end
|
60
|
-
|
61
|
-
# @private
|
62
|
-
def re_one_or_more #:nodoc:
|
63
|
-
Match[/#{atomic_re.source}+/]
|
48
|
+
ws.skip & self
|
64
49
|
end
|
65
|
-
|
66
|
-
# @private
|
67
|
-
def assert_re #:nodoc:
|
68
|
-
/(?=#{re.source})/
|
69
|
-
end
|
70
|
-
|
71
|
-
# @private
|
72
|
-
def disallow_re #:nodoc:
|
73
|
-
/(?!#{re.source})/
|
74
|
-
end
|
75
|
-
|
76
|
-
# @private
|
77
|
-
def atomic_re #:nodoc:
|
78
|
-
/(?>#{re.source})/
|
79
|
-
end
|
80
|
-
|
81
|
-
# @private
|
82
|
-
def as_match #:nodoc:
|
83
|
-
self
|
84
|
-
end
|
85
|
-
|
50
|
+
|
86
51
|
end
|
87
52
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# = rattler/parsers/node_code.rb
|
3
|
+
#
|
4
|
+
# Author:: Jason Arhart
|
5
|
+
# Documentation:: Author
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rattler/parsers'
|
9
|
+
|
10
|
+
module Rattler::Parsers
|
11
|
+
# @private
|
12
|
+
class NodeCode #:nodoc:
|
13
|
+
|
14
|
+
def self.bindable_code(action)
|
15
|
+
self.new(action.target, action.method_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(target_name, method_name)
|
19
|
+
@target_name = target_name
|
20
|
+
@method_name = method_name
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :target_name, :method_name
|
24
|
+
|
25
|
+
def bind(scope, bind_args)
|
26
|
+
args = [array_expr(bind_args)]
|
27
|
+
if not scope.empty?
|
28
|
+
labeled = '{' + scope.map {|k, v| ":#{k} => #{v}"}.join(', ') + '}'
|
29
|
+
args << ":labeled => #{labeled}"
|
30
|
+
end
|
31
|
+
t = target_name == 'self' ? '' : "#{target_name}."
|
32
|
+
"#{t}#{method_name}(#{args.join ', '})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def array_expr(bind_args)
|
36
|
+
if bind_args.respond_to? :to_str
|
37
|
+
bind_args
|
38
|
+
else
|
39
|
+
'[' + bind_args.join(', ') + ']'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -16,12 +16,12 @@ module Rattler::Parsers
|
|
16
16
|
#
|
17
17
|
class OneOrMore < Parser
|
18
18
|
include Combining
|
19
|
-
|
19
|
+
|
20
20
|
# Parse using the wrapped parser repeatedly until it fails. If the
|
21
21
|
# wrapped parser succeeds at least once return the results in an array,
|
22
22
|
# or +true+ if the wrapped parser is not <tt>capturing?</tt>. Return
|
23
23
|
# +false+ if the wrapped parser does not succeed at least once.
|
24
|
-
|
24
|
+
|
25
25
|
# Parse using the decorated parser as many times as it succeeds. If it does
|
26
26
|
# not succeeds at least once return +false+, otherwise the results in an
|
27
27
|
# array, or +true+ if the decorated parser is not <tt>capturing?</tt>.
|
@@ -29,39 +29,19 @@ module Rattler::Parsers
|
|
29
29
|
# @param (see Parser#parse_labeled)
|
30
30
|
#
|
31
31
|
# @return [Array, Boolean] an array containing the decorated parser's parse
|
32
|
-
#
|
32
|
+
# results, or +true+ if the decorated parser is not <tt>capturing?</tt>,
|
33
33
|
# or +false+ if the decorated parser does not succeed at least once.
|
34
|
-
def parse(scanner, rules,
|
34
|
+
def parse(scanner, rules, scope = {})
|
35
35
|
a = []
|
36
|
-
while result = child.parse(scanner, rules)
|
36
|
+
while result = child.parse(scanner, rules, scope)
|
37
37
|
a << result
|
38
38
|
end
|
39
39
|
(capturing? ? a : true) unless a.empty?
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def variable_capture_count?
|
43
43
|
true
|
44
44
|
end
|
45
|
-
|
46
|
-
# @private
|
47
|
-
def token_optimized #:nodoc:
|
48
|
-
to = super
|
49
|
-
if Match === to.child
|
50
|
-
to.child.re_one_or_more
|
51
|
-
else
|
52
|
-
to
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# @private
|
57
|
-
def skip_optimized #:nodoc:
|
58
|
-
to = super
|
59
|
-
if Match === to.child
|
60
|
-
to.child.re_one_or_more
|
61
|
-
else
|
62
|
-
to
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
45
|
+
|
66
46
|
end
|
67
47
|
end
|
@@ -15,7 +15,7 @@ module Rattler::Parsers
|
|
15
15
|
#
|
16
16
|
class Optional < Parser
|
17
17
|
include Combining
|
18
|
-
|
18
|
+
|
19
19
|
# Parse using the decorated parser and always succeed. If the decorated
|
20
20
|
# parser is <tt>capturing?</tt> return the result in an array, or an empty
|
21
21
|
# array if the wrapped parser fails. If the decorated parser is not
|
@@ -26,37 +26,17 @@ module Rattler::Parsers
|
|
26
26
|
# @return [Array, true] an array containing the decorated parser's parse
|
27
27
|
# results if it matches or an empty array if not, or always +true+ if the
|
28
28
|
# decorated parser is not <tt>capturing?</tt>
|
29
|
-
def parse(scanner, rules,
|
30
|
-
if result = child.parse(scanner, rules)
|
29
|
+
def parse(scanner, rules, scope = {})
|
30
|
+
if result = child.parse(scanner, rules, scope)
|
31
31
|
capturing? ? [result] : true
|
32
32
|
else
|
33
33
|
capturing? ? [] : true
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def variable_capture_count?
|
38
38
|
true
|
39
39
|
end
|
40
|
-
|
41
|
-
# @private
|
42
|
-
def token_optimized #:nodoc:
|
43
|
-
to = super
|
44
|
-
if Match === to.child
|
45
|
-
to.child.re_optional
|
46
|
-
else
|
47
|
-
to
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# @private
|
52
|
-
def skip_optimized #:nodoc:
|
53
|
-
so = super
|
54
|
-
if Match === so.child
|
55
|
-
so.child.re_optional
|
56
|
-
else
|
57
|
-
so
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
40
|
+
|
61
41
|
end
|
62
42
|
end
|
@@ -14,12 +14,12 @@ module Rattler::Parsers
|
|
14
14
|
# @author Jason Arhart
|
15
15
|
#
|
16
16
|
class Parser < Rattler::Util::Node
|
17
|
-
|
17
|
+
|
18
18
|
# @private
|
19
19
|
def self.parsed(*args) #:nodoc:
|
20
20
|
self[*args]
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Return +true+ if the parser returns parse results on success, or
|
24
24
|
# +false+ if the parser simply returns +true+ on success.
|
25
25
|
#
|
@@ -28,11 +28,11 @@ module Rattler::Parsers
|
|
28
28
|
def capturing?
|
29
29
|
true
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def variable_capture_count?
|
33
33
|
false
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# Return +true+ if the parser associates a label with parse results. Only
|
37
37
|
# instances of +Label+ should return +true+.
|
38
38
|
#
|
@@ -40,77 +40,49 @@ module Rattler::Parsers
|
|
40
40
|
def labeled?
|
41
41
|
false
|
42
42
|
end
|
43
|
-
|
44
|
-
# Parse and on success associate the label with the parse result if
|
45
|
-
# +labeled?+ and +capturing?+.
|
46
|
-
#
|
47
|
-
# @param [StringScanner] scanner the scanner used match patterns
|
48
|
-
# @param [Rules] rules the parse rules defining the parser
|
49
|
-
# @param [Hash] labeled a hash for associating labels with children
|
50
|
-
#
|
51
|
-
# @return the parse result on success, or a false value on failure
|
52
|
-
def parse_labeled(scanner, rules, labeled)
|
53
|
-
parse(scanner, rules, labeled)
|
54
|
-
end
|
55
|
-
|
43
|
+
|
56
44
|
# @param [Parser] other the parser to try if this parser fails.
|
57
45
|
# @return a new parser that tries this parser first and if it fails tries
|
58
46
|
# +other+
|
59
47
|
def |(other)
|
60
48
|
Choice[self, other]
|
61
49
|
end
|
62
|
-
|
50
|
+
|
63
51
|
# @param [Parser] other the next parser to try if this parser succeeds.
|
64
52
|
# @return a new parser that tries both this parser and +other+ and fails
|
65
53
|
# unless both parse in sequence
|
66
54
|
def &(other)
|
67
55
|
Sequence[self, other]
|
68
56
|
end
|
69
|
-
|
57
|
+
|
70
58
|
# @return a new parser that tries this parser but returns +true+ if it
|
71
59
|
# fails
|
72
60
|
def optional
|
73
61
|
Optional[self]
|
74
62
|
end
|
75
|
-
|
63
|
+
|
76
64
|
# @return a new parser that tries this parser until it fails and returns
|
77
65
|
# all of the results
|
78
66
|
def zero_or_more
|
79
67
|
ZeroOrMore[self]
|
80
68
|
end
|
81
|
-
|
69
|
+
|
82
70
|
# @return a new parser that tries this parser until it fails and returns
|
83
71
|
# all of the results if it succeeded at least once and fails otherwise
|
84
72
|
def one_or_more
|
85
73
|
OneOrMore[self]
|
86
74
|
end
|
87
|
-
|
75
|
+
|
76
|
+
# @return a new parser that skips over what this parser matches
|
77
|
+
def skip
|
78
|
+
Skip[self]
|
79
|
+
end
|
80
|
+
|
88
81
|
# @param [Parser] ws the parser used to skip whitespace
|
89
82
|
# @return [Parser] a new parser that uses +ws+ to skip whitespace
|
90
83
|
def with_ws(ws)
|
91
84
|
self
|
92
85
|
end
|
93
|
-
|
94
|
-
# @return [Parser] a parser that parses identically but may have a more
|
95
|
-
# optimized structure
|
96
|
-
def optimized
|
97
|
-
self
|
98
|
-
end
|
99
|
-
|
100
|
-
# @private
|
101
|
-
def token_optimized #:nodoc:
|
102
|
-
self
|
103
|
-
end
|
104
|
-
|
105
|
-
# @private
|
106
|
-
def skip_optimized #:nodoc:
|
107
|
-
self
|
108
|
-
end
|
109
|
-
|
110
|
-
# @private
|
111
|
-
def as_match #:nodoc:
|
112
|
-
nil
|
113
|
-
end
|
114
|
-
|
86
|
+
|
115
87
|
end
|
116
88
|
end
|