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.
Files changed (182) hide show
  1. data/README.rdoc +57 -37
  2. data/features/command_line/dest_option.feature +8 -21
  3. data/features/command_line/lib_option.feature +37 -0
  4. data/features/command_line/parser_generator.feature +7 -4
  5. data/features/grammar/back_reference.feature +37 -0
  6. data/features/grammar/fail.feature +3 -3
  7. data/features/grammar/labels.feature +11 -3
  8. data/features/grammar/list_matching.feature +14 -5
  9. data/features/grammar/literal.feature +30 -4
  10. data/features/grammar/nonterminal.feature +1 -1
  11. data/features/grammar/ordered_choice.feature +2 -2
  12. data/features/grammar/skip_operator.feature +1 -1
  13. data/features/grammar/symantic_action.feature +7 -7
  14. data/features/grammar/whitespace.feature +2 -2
  15. data/features/step_definitions/grammar_steps.rb +2 -2
  16. data/lib/rattler/back_end.rb +1 -0
  17. data/lib/rattler/back_end/compiler.rb +19 -20
  18. data/lib/rattler/back_end/optimizer.rb +100 -0
  19. data/lib/rattler/back_end/optimizer/composite_reducing.rb +18 -0
  20. data/lib/rattler/back_end/optimizer/flatten_choice.rb +31 -0
  21. data/lib/rattler/back_end/optimizer/flatten_sequence.rb +59 -0
  22. data/lib/rattler/back_end/optimizer/flattening.rb +17 -0
  23. data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +46 -0
  24. data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rb +71 -0
  25. data/lib/rattler/back_end/optimizer/join_match_choice.rb +37 -0
  26. data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rb +38 -0
  27. data/lib/rattler/back_end/optimizer/join_match_sequence.rb +17 -0
  28. data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rb +68 -0
  29. data/lib/rattler/back_end/optimizer/join_predicate_match.rb +17 -0
  30. data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rb +37 -0
  31. data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rb +68 -0
  32. data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +17 -0
  33. data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rb +36 -0
  34. data/lib/rattler/back_end/optimizer/match_joining.rb +60 -0
  35. data/lib/rattler/back_end/optimizer/optimization.rb +94 -0
  36. data/lib/rattler/back_end/optimizer/optimization_context.rb +72 -0
  37. data/lib/rattler/back_end/optimizer/optimization_sequence.rb +37 -0
  38. data/lib/rattler/back_end/optimizer/optimize_children.rb +46 -0
  39. data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +44 -0
  40. data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +32 -0
  41. data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +43 -0
  42. data/lib/rattler/back_end/optimizer/simplify_token_match.rb +38 -0
  43. data/lib/rattler/back_end/parser_generator.rb +21 -14
  44. data/lib/rattler/back_end/parser_generator/apply_generator.rb +35 -35
  45. data/lib/rattler/back_end/parser_generator/assert_generator.rb +29 -30
  46. data/lib/rattler/back_end/parser_generator/back_reference_generator.rb +93 -0
  47. data/lib/rattler/back_end/parser_generator/choice_generator.rb +33 -49
  48. data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +14 -14
  49. data/lib/rattler/back_end/parser_generator/disallow_generator.rb +29 -30
  50. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +11 -13
  51. data/lib/rattler/back_end/parser_generator/expr_generator.rb +36 -56
  52. data/lib/rattler/back_end/parser_generator/fail_generator.rb +18 -18
  53. data/lib/rattler/back_end/parser_generator/group_match.rb +18 -0
  54. data/lib/rattler/back_end/parser_generator/group_match_generator.rb +76 -0
  55. data/lib/rattler/back_end/parser_generator/label_generator.rb +25 -6
  56. data/lib/rattler/back_end/parser_generator/list1_generator.rb +7 -7
  57. data/lib/rattler/back_end/parser_generator/list_generating.rb +19 -20
  58. data/lib/rattler/back_end/parser_generator/list_generator.rb +5 -5
  59. data/lib/rattler/back_end/parser_generator/match_generator.rb +52 -52
  60. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +6 -6
  61. data/lib/rattler/back_end/parser_generator/optional_generator.rb +30 -29
  62. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +8 -8
  63. data/lib/rattler/back_end/parser_generator/repeat_generating.rb +23 -25
  64. data/lib/rattler/back_end/parser_generator/rule_generator.rb +27 -79
  65. data/lib/rattler/back_end/parser_generator/rule_set_generator.rb +102 -0
  66. data/lib/rattler/back_end/parser_generator/sequence_generator.rb +49 -41
  67. data/lib/rattler/back_end/parser_generator/skip_generator.rb +14 -20
  68. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +4 -4
  69. data/lib/rattler/back_end/parser_generator/sub_generating.rb +6 -0
  70. data/lib/rattler/back_end/parser_generator/token_generator.rb +12 -12
  71. data/lib/rattler/back_end/parser_generator/token_propogating.rb +2 -2
  72. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +4 -4
  73. data/lib/rattler/grammar.rb +4 -3
  74. data/lib/rattler/grammar/analysis.rb +91 -0
  75. data/lib/rattler/grammar/grammar.rb +37 -25
  76. data/lib/rattler/grammar/grammar_parser.rb +19 -11
  77. data/lib/rattler/grammar/metagrammar.rb +569 -800
  78. data/lib/rattler/grammar/rattler.rtlr +162 -144
  79. data/lib/rattler/parsers.rb +5 -1
  80. data/lib/rattler/parsers/action_code.rb +29 -15
  81. data/lib/rattler/parsers/apply.rb +5 -5
  82. data/lib/rattler/parsers/assert.rb +4 -18
  83. data/lib/rattler/parsers/back_reference.rb +46 -0
  84. data/lib/rattler/parsers/choice.rb +6 -39
  85. data/lib/rattler/parsers/combinator_parser.rb +32 -0
  86. data/lib/rattler/parsers/combining.rb +3 -29
  87. data/lib/rattler/parsers/direct_action.rb +27 -30
  88. data/lib/rattler/parsers/disallow.rb +4 -18
  89. data/lib/rattler/parsers/dispatch_action.rb +30 -25
  90. data/lib/rattler/parsers/label.rb +9 -18
  91. data/lib/rattler/parsers/list.rb +3 -34
  92. data/lib/rattler/parsers/list1.rb +4 -36
  93. data/lib/rattler/parsers/list_parser.rb +64 -0
  94. data/lib/rattler/parsers/match.rb +7 -42
  95. data/lib/rattler/parsers/node_code.rb +44 -0
  96. data/lib/rattler/parsers/one_or_more.rb +7 -27
  97. data/lib/rattler/parsers/optional.rb +5 -25
  98. data/lib/rattler/parsers/parser.rb +16 -44
  99. data/lib/rattler/parsers/parser_dsl.rb +13 -3
  100. data/lib/rattler/parsers/predicate.rb +4 -12
  101. data/lib/rattler/parsers/rule.rb +18 -19
  102. data/lib/rattler/parsers/rule_set.rb +63 -0
  103. data/lib/rattler/parsers/sequence.rb +12 -46
  104. data/lib/rattler/parsers/skip.rb +12 -26
  105. data/lib/rattler/parsers/token.rb +6 -21
  106. data/lib/rattler/parsers/zero_or_more.rb +6 -26
  107. data/lib/rattler/runner.rb +66 -28
  108. data/lib/rattler/runtime/extended_packrat_parser.rb +26 -20
  109. data/lib/rattler/runtime/packrat_parser.rb +17 -21
  110. data/lib/rattler/runtime/parser.rb +12 -2
  111. data/lib/rattler/runtime/recursive_descent_parser.rb +3 -11
  112. data/lib/rattler/util.rb +2 -1
  113. data/lib/rattler/util/graphviz.rb +29 -0
  114. data/lib/rattler/util/graphviz/digraph_builder.rb +71 -0
  115. data/lib/rattler/util/graphviz/node_builder.rb +84 -0
  116. data/lib/rattler/util/node.rb +37 -19
  117. data/lib/rattler/util/parser_spec_helper.rb +61 -35
  118. data/spec/rattler/back_end/compiler_spec.rb +6 -860
  119. data/spec/rattler/back_end/optimizer/flatten_choice_spec.rb +70 -0
  120. data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rb +130 -0
  121. data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +80 -0
  122. data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rb +241 -0
  123. data/spec/rattler/back_end/optimizer/join_match_choice_spec.rb +100 -0
  124. data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rb +112 -0
  125. data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rb +194 -0
  126. data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rb +180 -0
  127. data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rb +153 -0
  128. data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rb +153 -0
  129. data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +98 -0
  130. data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +226 -0
  131. data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rb +85 -0
  132. data/spec/rattler/back_end/parser_generator/apply_generator_spec.rb +38 -33
  133. data/spec/rattler/back_end/parser_generator/assert_generator_spec.rb +38 -33
  134. data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rb +181 -0
  135. data/spec/rattler/back_end/parser_generator/choice_generator_spec.rb +38 -33
  136. data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +38 -33
  137. data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rb +38 -33
  138. data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +38 -33
  139. data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +185 -0
  140. data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +38 -33
  141. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +10 -5
  142. data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +10 -5
  143. data/spec/rattler/back_end/parser_generator/match_generator_spec.rb +38 -33
  144. data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +38 -33
  145. data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +38 -33
  146. data/spec/rattler/back_end/parser_generator/rule_generator_spec.rb +13 -46
  147. data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rb +97 -0
  148. data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rb +38 -33
  149. data/spec/rattler/back_end/parser_generator/skip_generator_spec.rb +38 -33
  150. data/spec/rattler/back_end/parser_generator/token_generator_spec.rb +38 -33
  151. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +39 -34
  152. data/spec/rattler/back_end/shared_compiler_examples.rb +885 -0
  153. data/spec/rattler/grammar/analysis_spec.rb +167 -0
  154. data/spec/rattler/grammar/grammar_parser_spec.rb +169 -179
  155. data/spec/rattler/grammar/grammar_spec.rb +24 -21
  156. data/spec/rattler/parsers/action_code_spec.rb +64 -19
  157. data/spec/rattler/parsers/apply_spec.rb +9 -9
  158. data/spec/rattler/parsers/back_reference_spec.rb +38 -0
  159. data/spec/rattler/parsers/combinator_parser_spec.rb +14 -0
  160. data/spec/rattler/parsers/direct_action_spec.rb +16 -2
  161. data/spec/rattler/parsers/dispatch_action_spec.rb +15 -32
  162. data/spec/rattler/parsers/fail_spec.rb +6 -4
  163. data/spec/rattler/parsers/label_spec.rb +10 -28
  164. data/spec/rattler/parsers/node_code_spec.rb +48 -0
  165. data/spec/rattler/parsers/parser_dsl_spec.rb +1 -1
  166. data/spec/rattler/parsers/rule_set_spec.rb +35 -0
  167. data/spec/rattler/parsers/sequence_spec.rb +15 -24
  168. data/spec/rattler/runtime/extended_packrat_parser_spec.rb +22 -17
  169. data/spec/rattler/runtime/packrat_parser_spec.rb +1 -1
  170. data/spec/rattler/runtime/parse_node_spec.rb +15 -19
  171. data/spec/rattler/runtime/recursive_descent_parser_spec.rb +1 -1
  172. data/spec/rattler/runtime/shared_parser_examples.rb +61 -28
  173. data/spec/rattler/util/graphviz/node_builder_spec.rb +84 -0
  174. data/spec/rattler/util/node_spec.rb +92 -65
  175. data/spec/rattler_spec.rb +16 -16
  176. data/spec/support/combinator_parser_spec_helper.rb +19 -18
  177. data/spec/support/compiler_spec_helper.rb +56 -87
  178. data/spec/support/runtime_parser_spec_helper.rb +6 -14
  179. metadata +117 -22
  180. data/features/grammar/regex.feature +0 -24
  181. data/lib/rattler/parsers/match_joining.rb +0 -67
  182. 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
- describe Assert do
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
- end
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
- l = {}
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
@@ -264,7 +264,7 @@ describe ParserDSL do
264
264
  rule(:word) { match(/\w+/) }
265
265
  rule(:number) { match(/\d+/) }
266
266
  end.
267
- should == Rules[
267
+ should == RuleSet[
268
268
  Rule[:word, Match[/\w+/]],
269
269
  Rule[:number, Match[/\d+/]]
270
270
  ]
@@ -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) { Rules[Rule[:ws, Skip[Match[/\s+/]]]] }
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
- it 'supports directly left-recursive rules' do
12
- given_rules do
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
- parsing('12345a').as(:a).
19
- should result_in([[[['1', '2'], '3'], '4'], '5']).
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
- it 'supports indirectly left-recursive rules' do
24
- given_rules do
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 as no :labeled attribute' do
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