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
@@ -1,20 +1,22 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
|
3
|
+
include Rattler::Parsers
|
4
|
+
|
5
|
+
describe Rattler::Parsers::Fail do
|
4
6
|
include CombinatorParserSpecHelper
|
5
7
|
|
6
8
|
subject { Fail[:expr, 'malformed expression'] }
|
7
|
-
|
9
|
+
|
8
10
|
describe '#parse' do
|
9
11
|
it 'fails' do
|
10
12
|
parsing('anything').should fail
|
11
13
|
end
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
describe '#capturing?' do
|
15
17
|
it 'is false' do
|
16
18
|
subject.should_not be_capturing
|
17
19
|
end
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
end
|
@@ -2,56 +2,38 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
|
3
3
|
describe Label do
|
4
4
|
include CombinatorParserSpecHelper
|
5
|
-
|
5
|
+
|
6
6
|
subject { Label[:name, [Match[/\w+/]]] }
|
7
|
-
|
7
|
+
|
8
8
|
describe '#parse' do
|
9
|
+
|
9
10
|
it 'matches identically to its parser' do
|
10
11
|
parsing('abc123 ').should result_in('abc123').at(6)
|
11
12
|
parsing('==').should fail
|
12
13
|
end
|
13
|
-
|
14
|
-
|
15
|
-
describe '#parse_labeled' do
|
16
|
-
|
17
|
-
it 'matches the same as #parse' do
|
18
|
-
parsing('abc123 ').labeled.should result_in('abc123').at(6)
|
19
|
-
parsing('==').labeled.should fail
|
20
|
-
end
|
21
|
-
|
14
|
+
|
22
15
|
context 'on success' do
|
23
16
|
it 'adds a mapping from its label to its result' do
|
24
|
-
|
25
|
-
parsing('foo ').labeled(l).should result_in('foo')
|
26
|
-
l.should == {:name => 'foo'}
|
17
|
+
parsing('foo ').should result_in('foo').with_scope(:name => 'foo')
|
27
18
|
end
|
28
19
|
end
|
29
|
-
|
30
|
-
context 'on failure' do
|
31
|
-
it 'does not add a label mapping' do
|
32
|
-
l = {}
|
33
|
-
parsing('==').labeled(l).should fail
|
34
|
-
l.should == {}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
20
|
end
|
39
|
-
|
21
|
+
|
40
22
|
describe '#capturing?' do
|
41
|
-
|
23
|
+
|
42
24
|
context 'with a capturing parser' do
|
43
25
|
it 'is true' do
|
44
26
|
subject.should be_capturing
|
45
27
|
end
|
46
28
|
end
|
47
|
-
|
29
|
+
|
48
30
|
context 'with a non-capturing parser' do
|
49
31
|
subject { Label[:name, [Skip[Match[/\s+/]]]] }
|
50
32
|
it 'is false' do
|
51
33
|
subject.should_not be_capturing
|
52
34
|
end
|
53
35
|
end
|
54
|
-
|
36
|
+
|
55
37
|
end
|
56
|
-
|
38
|
+
|
57
39
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Rattler::Parsers::NodeCode do
|
4
|
+
|
5
|
+
subject { described_class.new(target_name, method_name) }
|
6
|
+
|
7
|
+
let(:target_name) { 'Expr' }
|
8
|
+
let(:method_name) { 'parsed' }
|
9
|
+
|
10
|
+
describe '#bind' do
|
11
|
+
|
12
|
+
let(:scope) { {} }
|
13
|
+
|
14
|
+
context 'given empty bind args' do
|
15
|
+
it 'binds "[]"' do
|
16
|
+
subject.bind(scope, []).should == 'Expr.parsed([])'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'given a single bind arg' do
|
21
|
+
it 'binds the an array with the arg' do
|
22
|
+
subject.bind(scope, ['a']).should == 'Expr.parsed([a])'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'given a multiple bind args' do
|
27
|
+
it 'binds the an array with the arg' do
|
28
|
+
subject.bind(scope, ['a', 'b', 'c']).should == 'Expr.parsed([a, b, c])'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'given a string as bind args' do
|
33
|
+
it 'binds the exact string' do
|
34
|
+
subject.bind(scope, 'a').should == 'Expr.parsed(a)'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with scope' do
|
39
|
+
|
40
|
+
let(:scope) { {:word => 'w'} }
|
41
|
+
|
42
|
+
it 'binds the scope as labeled results' do
|
43
|
+
subject.bind(scope, ['a', 'b']).
|
44
|
+
should == 'Expr.parsed([a, b], :labeled => {:word => w})'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Rattler::Parsers::RuleSet do
|
4
|
+
include CombinatorParserSpecHelper
|
5
|
+
|
6
|
+
subject { RuleSet[rule_a, rule_b] }
|
7
|
+
|
8
|
+
let(:rule_a) { Rule[:a, Match[/a/]] }
|
9
|
+
let(:rule_b) { Rule[:b, Match[/b/]] }
|
10
|
+
|
11
|
+
describe '#rule' do
|
12
|
+
it 'returns rules by name' do
|
13
|
+
subject.rule(:a).should == rule_a
|
14
|
+
subject.rule(:b).should == rule_b
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#[]' do
|
19
|
+
|
20
|
+
context 'given a symbol' do
|
21
|
+
it 'returns a rule by name' do
|
22
|
+
subject[:a].should == rule_a
|
23
|
+
subject[:b].should == rule_b
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'given an array argument' do
|
28
|
+
it 'returns a rule by index' do
|
29
|
+
subject[0].should == rule_a
|
30
|
+
subject[1].should == rule_b
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -2,25 +2,25 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
|
3
3
|
describe Sequence do
|
4
4
|
include CombinatorParserSpecHelper
|
5
|
-
|
5
|
+
|
6
6
|
describe '#parse' do
|
7
|
-
|
7
|
+
|
8
8
|
subject do
|
9
9
|
Sequence[Match[/[[:alpha:]]+/], Match[/\=/], Match[/[[:digit:]]+/]]
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
context 'when all of the parsers match in sequence' do
|
13
13
|
it 'matches returning the results in an array' do
|
14
14
|
parsing('val=42').should result_in(['val', '=', '42']).at(6)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
context 'when one of the parsers fails' do
|
19
19
|
it 'fails and backtracks' do
|
20
20
|
parsing('val=x').should fail
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
context 'with non-capturing parsers' do
|
25
25
|
subject do
|
26
26
|
Sequence[Match[/[[:alpha:]]+/], Skip[Match[/\s+/]], Match[/[[:digit:]]+/]]
|
@@ -31,7 +31,7 @@ describe Sequence do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
context 'with only one capturing parser' do
|
36
36
|
subject do
|
37
37
|
Sequence[Skip[Match[/\s+/]], Match[/\w+/]]
|
@@ -42,7 +42,7 @@ describe Sequence do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
context 'with no capturing parsers' do
|
47
47
|
subject do
|
48
48
|
Sequence[Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]]
|
@@ -53,14 +53,14 @@ describe Sequence do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
context 'with an apply parser referencing a non-capturing rule' do
|
58
58
|
subject do
|
59
59
|
Sequence[Match[/[[:alpha:]]+/], Apply[:ws], Match[/[[:digit:]]+/]]
|
60
60
|
end
|
61
|
-
|
62
|
-
let(:rules) {
|
63
|
-
|
61
|
+
|
62
|
+
let(:rules) { RuleSet[Rule[:ws, Skip[Match[/\s+/]]]] }
|
63
|
+
|
64
64
|
context 'when all of the parsers match in sequence' do
|
65
65
|
it 'only includes results of its capturing parsers in the result array' do
|
66
66
|
parsing('foo 42').should result_in ['foo', '42']
|
@@ -68,9 +68,9 @@ describe Sequence do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
describe '#capturing?' do
|
73
|
-
|
73
|
+
|
74
74
|
context 'with any capturing parsers' do
|
75
75
|
subject do
|
76
76
|
Sequence[Skip[Match[/\s*/]], Match[/\w+/]]
|
@@ -79,7 +79,7 @@ describe Sequence do
|
|
79
79
|
subject.should be_capturing
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
context 'with no capturing parsers' do
|
84
84
|
subject do
|
85
85
|
Sequence[Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]]
|
@@ -89,14 +89,5 @@ describe Sequence do
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
93
|
-
describe '#optimized' do
|
94
|
-
context 'with all skips' do
|
95
|
-
it 'returns a skip' do
|
96
|
-
Sequence[Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]].optimized.should ==
|
97
|
-
Skip[Sequence[Match[/\s*/], Match[/#[^\n]+/]]].optimized
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
92
|
+
|
102
93
|
end
|
@@ -3,33 +3,38 @@ require File.expand_path(File.dirname(__FILE__) + '/shared_parser_examples')
|
|
3
3
|
|
4
4
|
describe Rattler::Runtime::ExtendedPackratParser do
|
5
5
|
include RuntimeParserSpecHelper
|
6
|
-
|
7
|
-
it_behaves_like 'a packrat parser'
|
8
|
-
|
6
|
+
|
7
|
+
it_behaves_like 'a generated packrat parser'
|
8
|
+
|
9
|
+
let :parser_class do
|
10
|
+
Rattler::BackEnd::Compiler.compile_parser described_class, grammar
|
11
|
+
end
|
12
|
+
|
9
13
|
describe '#match' do
|
10
14
|
|
11
|
-
|
12
|
-
|
15
|
+
context 'given a directly left-recursive rule' do
|
16
|
+
let(:grammar) { define_grammar do
|
13
17
|
rule :a do
|
14
18
|
( match(:a) & match(/\d/) \
|
15
19
|
| match(/\d/) )
|
16
20
|
end
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
at(5)
|
21
|
+
end }
|
22
|
+
|
23
|
+
it 'parses correctly' do
|
24
|
+
parsing('12345a').should result_in([[[['1', '2'], '3'], '4'], '5']).at(5)
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
context 'given indirectly left-recursive rules' do
|
29
|
+
let(:grammar) { define_grammar do
|
25
30
|
rule(:a) { match(:b) | match(/\d/) }
|
26
31
|
rule(:b) { match(:a) & match(/\d/) }
|
27
|
-
end
|
28
|
-
parsing('12345a').as(:a).
|
29
|
-
should result_in([[[['1', '2'], '3'], '4'], '5']).
|
30
|
-
at(5)
|
31
|
-
end
|
32
|
+
end }
|
32
33
|
|
34
|
+
it 'parses correctly' do
|
35
|
+
parsing('12345a').should result_in([[[['1', '2'], '3'], '4'], '5']).at(5)
|
36
|
+
end
|
37
|
+
end
|
33
38
|
end
|
34
|
-
|
39
|
+
|
35
40
|
end
|
@@ -2,5 +2,5 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/shared_parser_examples')
|
3
3
|
|
4
4
|
describe Rattler::Runtime::PackratParser do
|
5
|
-
it_behaves_like 'a packrat parser'
|
5
|
+
it_behaves_like 'a generated packrat parser'
|
6
6
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
3
|
describe Rattler::Runtime::ParseNode do
|
4
|
-
|
4
|
+
|
5
|
+
let(:children) { ['foo', 'bar'] }
|
6
|
+
|
5
7
|
describe '#labeled' do
|
6
|
-
|
7
|
-
let(:children) { ['foo', 'bar'] }
|
8
|
-
|
8
|
+
|
9
9
|
context 'when the node has a :labeled attribute' do
|
10
10
|
subject do
|
11
11
|
Rattler::Runtime::ParseNode.parsed(children,
|
@@ -15,8 +15,8 @@ describe Rattler::Runtime::ParseNode do
|
|
15
15
|
subject.labeled.should == subject.attrs[:labeled]
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
19
|
-
context 'when the node
|
18
|
+
|
19
|
+
context 'when the node has no :labeled attribute' do
|
20
20
|
subject do
|
21
21
|
Rattler::Runtime::ParseNode.parsed(children)
|
22
22
|
end
|
@@ -25,54 +25,50 @@ describe Rattler::Runtime::ParseNode do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
describe '#[]' do
|
30
|
-
|
31
|
-
let(:children) { ['foo', 'bar'] }
|
32
|
-
|
30
|
+
|
33
31
|
context 'when the node has a :labeled attribute' do
|
34
32
|
subject do
|
35
33
|
Rattler::Runtime::ParseNode.parsed(children,
|
36
34
|
:labeled => {:left => children.first, :right => children.last })
|
37
35
|
end
|
38
|
-
|
36
|
+
|
39
37
|
context 'given one of the labels' do
|
40
38
|
it 'returns the child labeled by the symbol' do
|
41
39
|
subject[:left].should == children.first
|
42
40
|
subject[:right].should == children.last
|
43
41
|
end
|
44
42
|
end
|
45
|
-
|
43
|
+
|
46
44
|
context 'given a symbol that is not one of the labels' do
|
47
45
|
it 'returns nil' do
|
48
46
|
subject[:foo].should be_nil
|
49
47
|
end
|
50
48
|
end
|
51
49
|
end
|
52
|
-
|
50
|
+
|
53
51
|
context 'when the node as no :labeled attribute' do
|
54
52
|
subject do
|
55
53
|
Rattler::Runtime::ParseNode.parsed(children)
|
56
54
|
end
|
57
|
-
|
55
|
+
|
58
56
|
it 'returns nil' do
|
59
57
|
subject[:foo].should be_nil
|
60
58
|
end
|
61
59
|
end
|
62
60
|
end
|
63
|
-
|
61
|
+
|
64
62
|
describe '#method_missing' do
|
65
63
|
subject do
|
66
64
|
Rattler::Runtime::ParseNode.parsed(children,
|
67
65
|
:labeled => {:left => children.first, :right => children.last })
|
68
66
|
end
|
69
|
-
|
70
|
-
let(:children) { ['foo', 'bar'] }
|
71
|
-
|
67
|
+
|
72
68
|
it 'provides accessor methods for labeled children' do
|
73
69
|
subject.left.should == children.first
|
74
70
|
subject.right.should == children.last
|
75
71
|
end
|
76
72
|
end
|
77
|
-
|
73
|
+
|
78
74
|
end
|
@@ -2,5 +2,5 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/shared_parser_examples')
|
3
3
|
|
4
4
|
describe Rattler::Runtime::RecursiveDescentParser do
|
5
|
-
it_behaves_like 'a recursive descent parser'
|
5
|
+
it_behaves_like 'a generated recursive descent parser'
|
6
6
|
end
|