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
@@ -0,0 +1,181 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ include Rattler::BackEnd::ParserGenerator
4
+ include Rattler::Parsers
5
+
6
+ describe BackReferenceGenerator do
7
+
8
+ include ParserGeneratorSpecHelper
9
+
10
+ let(:ref) { BackReference[:a] }
11
+
12
+ let(:scope) { {:a => 'r0_2'} }
13
+
14
+ describe '#gen_basic' do
15
+
16
+ context 'when nested' do
17
+ it 'generates nested regex matching code' do
18
+ nested_code {|g| g.gen_basic ref, scope }.
19
+ should == '@scanner.scan(/#{r0_2}/)'
20
+ end
21
+ end
22
+
23
+ context 'when top-level' do
24
+ it 'generates top level regex matching code' do
25
+ top_level_code {|g| g.gen_basic ref, scope }.
26
+ should == '@scanner.scan(/#{r0_2}/)'
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#gen_assert' do
32
+
33
+ context 'when nested' do
34
+ it 'generates nested regex positive lookahead code' do
35
+ nested_code {|g| g.gen_assert ref, scope }.
36
+ should == '(@scanner.skip(/(?=#{r0_2})/) && true)'
37
+ end
38
+ end
39
+
40
+ context 'when top-level' do
41
+ it 'generates top level regex positive lookahead code' do
42
+ top_level_code {|g| g.gen_assert ref, scope }.
43
+ should == '@scanner.skip(/(?=#{r0_2})/) && true'
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#gen_disallow' do
49
+
50
+ context 'when nested' do
51
+ it 'generates nested regex negative lookahead code' do
52
+ nested_code {|g| g.gen_disallow ref, scope }.
53
+ should == '(@scanner.skip(/(?!#{r0_2})/) && true)'
54
+ end
55
+ end
56
+
57
+ context 'when top-level' do
58
+ it 'generates top level regex negative lookahead code' do
59
+ top_level_code {|g| g.gen_disallow ref, scope }.
60
+ should == '@scanner.skip(/(?!#{r0_2})/) && true'
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#gen_dispatch_action' do
66
+
67
+ let(:code) { NodeCode.new('Word', 'parsed') }
68
+
69
+ context 'when nested' do
70
+ it 'generates nested regex matching code with a dispatch action' do
71
+ nested_code {|g| g.gen_dispatch_action ref, code, scope }.
72
+ should == (<<-CODE).strip
73
+ begin
74
+ (r = @scanner.scan(/\#{r0_2}/)) &&
75
+ Word.parsed([r], :labeled => {:a => r0_2})
76
+ end
77
+ CODE
78
+ end
79
+ end
80
+
81
+ context 'when top-level' do
82
+ it 'generates top level regex matching code with a dispatch action' do
83
+ top_level_code {|g| g.gen_dispatch_action ref, code, scope }.
84
+ should == (<<-CODE).strip
85
+ (r = @scanner.scan(/\#{r0_2}/)) &&
86
+ Word.parsed([r], :labeled => {:a => r0_2})
87
+ CODE
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '#gen_direct_action' do
93
+
94
+ let(:code) { ActionCode.new('|_| _.to_sym') }
95
+
96
+ context 'when nested' do
97
+ it 'generates nested regex matching code with a direct action' do
98
+ nested_code {|g| g.gen_direct_action ref, code, scope }.
99
+ should == (<<-CODE).strip
100
+ begin
101
+ (r = @scanner.scan(/\#{r0_2}/)) &&
102
+ (r.to_sym)
103
+ end
104
+ CODE
105
+ end
106
+ end
107
+
108
+ context 'when top-level' do
109
+ it 'generates top level regex matching code with a direct action' do
110
+ top_level_code {|g| g.gen_direct_action ref, code, scope }.
111
+ should == (<<-CODE).strip
112
+ (r = @scanner.scan(/\#{r0_2}/)) &&
113
+ (r.to_sym)
114
+ CODE
115
+ end
116
+ end
117
+ end
118
+
119
+ describe '#gen_token' do
120
+
121
+ context 'when nested' do
122
+ it 'generates nested regex matching code' do
123
+ nested_code {|g| g.gen_token ref, scope }.
124
+ should == '@scanner.scan(/#{r0_2}/)'
125
+ end
126
+ end
127
+
128
+ context 'when top-level' do
129
+ it 'generates top level regex matching code' do
130
+ top_level_code {|g| g.gen_token ref, scope }.
131
+ should == '@scanner.scan(/#{r0_2}/)'
132
+ end
133
+ end
134
+ end
135
+
136
+ describe '#gen_skip' do
137
+
138
+ context 'when nested' do
139
+ it 'generates nested regex skipping code' do
140
+ nested_code {|g| g.gen_skip ref, scope }.
141
+ should == '(@scanner.skip(/#{r0_2}/) && true)'
142
+ end
143
+ end
144
+
145
+ context 'when top-level' do
146
+ it 'generates top level regex skipping code' do
147
+ top_level_code {|g| g.gen_skip ref, scope }.
148
+ should == '@scanner.skip(/#{r0_2}/) && true'
149
+ end
150
+ end
151
+ end
152
+
153
+ describe '#gen_intermediate' do
154
+ it 'generates basic regex matching code' do
155
+ nested_code {|g| g.gen_intermediate ref, scope }.
156
+ should == '@scanner.scan(/#{r0_2}/)'
157
+ end
158
+ end
159
+
160
+ describe '#gen_intermediate_assert' do
161
+ it 'generates intermediate regex positive lookahead code' do
162
+ nested_code {|g| g.gen_intermediate_assert ref, scope }.
163
+ should == '@scanner.skip(/(?=#{r0_2})/)'
164
+ end
165
+ end
166
+
167
+ describe '#gen_intermediate_disallow' do
168
+ it 'generates intermediate regex negative lookahead code' do
169
+ nested_code {|g| g.gen_intermediate_disallow ref, scope }.
170
+ should == '@scanner.skip(/(?!#{r0_2})/)'
171
+ end
172
+ end
173
+
174
+ describe '#gen_intermediate_skip' do
175
+ it 'generates intermediate regex skipping code' do
176
+ nested_code {|g| g.gen_intermediate_skip ref, scope }.
177
+ should == '@scanner.skip(/#{r0_2}/)'
178
+ end
179
+ end
180
+
181
+ end
@@ -1,15 +1,16 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
+ include Rattler::BackEnd::ParserGenerator
3
4
  include Rattler::Parsers
4
5
 
5
- describe Rattler::BackEnd::ParserGenerator::ChoiceGenerator do
6
-
6
+ describe ChoiceGenerator do
7
+
7
8
  include ParserGeneratorSpecHelper
8
-
9
+
9
10
  let(:choice) { Choice[Match[/[[:alpha:]]+/], Match[/[[:digit:]]+/]] }
10
-
11
+
11
12
  describe '#gen_basic' do
12
-
13
+
13
14
  context 'when nested' do
14
15
  it 'generates nested choice matching code' do
15
16
  nested_code(:choice_level => 2) {|g| g.gen_basic choice }.
@@ -21,7 +22,7 @@ end
21
22
  CODE
22
23
  end
23
24
  end
24
-
25
+
25
26
  context 'when top-level' do
26
27
  it 'generates top-level choice matching code' do
27
28
  top_level_code(:choice_level => 0) {|g| g.gen_basic choice }.
@@ -32,9 +33,9 @@ end
32
33
  end
33
34
  end
34
35
  end
35
-
36
+
36
37
  describe '#gen_assert' do
37
-
38
+
38
39
  context 'when nested' do
39
40
  it 'generates nested choice positive lookahead code' do
40
41
  nested_code(:choice_level => 2) {|g| g.gen_assert choice }.
@@ -46,7 +47,7 @@ end && true)
46
47
  CODE
47
48
  end
48
49
  end
49
-
50
+
50
51
  context 'when top-level' do
51
52
  it 'generates top-level choice positive lookahead code' do
52
53
  top_level_code(:choice_level => 0) {|g| g.gen_assert choice }.
@@ -59,9 +60,9 @@ end && true
59
60
  end
60
61
  end
61
62
  end
62
-
63
+
63
64
  describe '#gen_disallow' do
64
-
65
+
65
66
  context 'when nested' do
66
67
  it 'generates nested choice negative lookahead code' do
67
68
  nested_code(:choice_level => 2) {|g| g.gen_disallow choice }.
@@ -73,7 +74,7 @@ end
73
74
  CODE
74
75
  end
75
76
  end
76
-
77
+
77
78
  context 'when top-level' do
78
79
  it 'generates top-level choice negative lookahead code' do
79
80
  top_level_code(:choice_level => 0) {|g| g.gen_disallow choice }.
@@ -86,12 +87,14 @@ end
86
87
  end
87
88
  end
88
89
  end
89
-
90
+
90
91
  describe '#gen_dispatch_action' do
91
-
92
+
93
+ let(:code) { NodeCode.new('Atom', 'parsed') }
94
+
92
95
  context 'when nested' do
93
96
  it 'generates nested choice matching code with a dispatch action' do
94
- nested_code(:choice_level => 2) {|g| g.gen_dispatch_action choice, 'Atom', 'parsed' }.
97
+ nested_code(:choice_level => 2) {|g| g.gen_dispatch_action choice, code }.
95
98
  should == (<<-CODE).strip
96
99
  begin
97
100
  (r = begin
@@ -102,10 +105,10 @@ end
102
105
  CODE
103
106
  end
104
107
  end
105
-
108
+
106
109
  context 'when top-level' do
107
110
  it 'generates top-level choice matching code with a dispatch action' do
108
- top_level_code(:choice_level => 0) {|g| g.gen_dispatch_action choice, 'Atom', 'parsed' }.
111
+ top_level_code(:choice_level => 0) {|g| g.gen_dispatch_action choice, code }.
109
112
  should == (<<-CODE).strip
110
113
  (r = begin
111
114
  @scanner.scan(/[[:alpha:]]+/) ||
@@ -115,12 +118,14 @@ end) && Atom.parsed([r])
115
118
  end
116
119
  end
117
120
  end
118
-
121
+
119
122
  describe '#gen_direct_action' do
120
-
123
+
124
+ let(:code) { ActionCode.new('|_| _.size') }
125
+
121
126
  context 'when nested' do
122
127
  it 'generates nested choice matching code with a direct action' do
123
- nested_code(:choice_level => 2) {|g| g.gen_direct_action choice, ActionCode.new('|_| _.size') }.
128
+ nested_code(:choice_level => 2) {|g| g.gen_direct_action choice, code }.
124
129
  should == (<<-CODE).strip
125
130
  begin
126
131
  (r = begin
@@ -131,10 +136,10 @@ end
131
136
  CODE
132
137
  end
133
138
  end
134
-
139
+
135
140
  context 'when top-level' do
136
141
  it 'generates nested choice matching code with a direct action' do
137
- top_level_code(:choice_level => 0) {|g| g.gen_direct_action choice, ActionCode.new('|_| _.size') }.
142
+ top_level_code(:choice_level => 0) {|g| g.gen_direct_action choice, code }.
138
143
  should == (<<-CODE).strip
139
144
  (r = begin
140
145
  @scanner.scan(/[[:alpha:]]+/) ||
@@ -144,9 +149,9 @@ end) && (r.size)
144
149
  end
145
150
  end
146
151
  end
147
-
152
+
148
153
  describe '#gen_token' do
149
-
154
+
150
155
  context 'when nested' do
151
156
  it 'generates nested token choice matching code' do
152
157
  nested_code(:choice_level => 2) {|g| g.gen_token choice }.
@@ -158,7 +163,7 @@ end
158
163
  CODE
159
164
  end
160
165
  end
161
-
166
+
162
167
  context 'when top-level' do
163
168
  it 'generates top-level token choice matching code' do
164
169
  top_level_code(:choice_level => 0) {|g| g.gen_token choice }.
@@ -169,9 +174,9 @@ end
169
174
  end
170
175
  end
171
176
  end
172
-
177
+
173
178
  describe '#gen_skip' do
174
-
179
+
175
180
  context 'when nested' do
176
181
  it 'generates nested choice skipping code' do
177
182
  nested_code(:choice_level => 2) {|g| g.gen_skip choice }.
@@ -183,7 +188,7 @@ end && true)
183
188
  CODE
184
189
  end
185
190
  end
186
-
191
+
187
192
  context 'when top-level' do
188
193
  it 'generates top-level choice skipping code' do
189
194
  top_level_code(:choice_level => 0) {|g| g.gen_skip choice }.
@@ -196,7 +201,7 @@ end && true
196
201
  end
197
202
  end
198
203
  end
199
-
204
+
200
205
  describe '#gen_intermediate' do
201
206
  it 'generates nested choice matching code' do
202
207
  nested_code(:choice_level => 2) {|g| g.gen_intermediate choice }.
@@ -208,7 +213,7 @@ end
208
213
  CODE
209
214
  end
210
215
  end
211
-
216
+
212
217
  describe '#gen_intermediate_assert' do
213
218
  it 'generates intermediate choice positive lookahead code' do
214
219
  nested_code(:choice_level => 2) {|g| g.gen_intermediate_assert choice }.
@@ -220,7 +225,7 @@ end
220
225
  CODE
221
226
  end
222
227
  end
223
-
228
+
224
229
  describe '#gen_intermediate_disallow' do
225
230
  it 'generates intermediate choice negative lookahead code' do
226
231
  nested_code(:choice_level => 2) {|g| g.gen_intermediate_disallow choice }.
@@ -232,7 +237,7 @@ end
232
237
  CODE
233
238
  end
234
239
  end
235
-
240
+
236
241
  describe '#gen_intermediate_skip' do
237
242
  it 'generates intermediate choice skipping code' do
238
243
  nested_code(:choice_level => 2) {|g| g.gen_intermediate_skip choice }.
@@ -244,5 +249,5 @@ end
244
249
  CODE
245
250
  end
246
251
  end
247
-
252
+
248
253
  end
@@ -1,15 +1,16 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
+ include Rattler::BackEnd::ParserGenerator
3
4
  include Rattler::Parsers
4
5
 
5
- describe Rattler::BackEnd::ParserGenerator::DirectActionGenerator do
6
-
6
+ describe DirectActionGenerator do
7
+
7
8
  include ParserGeneratorSpecHelper
8
-
9
+
9
10
  let(:action) { DirectAction[Match[/\w+/], '|_| _.to_sym'] }
10
-
11
+
11
12
  describe '#gen_basic' do
12
-
13
+
13
14
  context 'when nested' do
14
15
  it 'generates nested matching code with a direct action' do
15
16
  nested_code {|g| g.gen_basic action }.
@@ -21,7 +22,7 @@ end
21
22
  CODE
22
23
  end
23
24
  end
24
-
25
+
25
26
  context 'when top-level' do
26
27
  it 'generates top level matching code with a direct action' do
27
28
  top_level_code {|g| g.gen_basic action }.
@@ -32,16 +33,16 @@ end
32
33
  end
33
34
  end
34
35
  end
35
-
36
+
36
37
  describe '#gen_assert' do
37
-
38
+
38
39
  context 'when nested' do
39
40
  it 'generates nested positive lookahead code' do
40
41
  nested_code {|g| g.gen_assert action }.
41
42
  should == '(@scanner.skip(/(?=\w+)/) && true)'
42
43
  end
43
44
  end
44
-
45
+
45
46
  context 'when top-level' do
46
47
  it 'generates top level positive lookahead code' do
47
48
  top_level_code {|g| g.gen_assert action }.
@@ -49,16 +50,16 @@ end
49
50
  end
50
51
  end
51
52
  end
52
-
53
+
53
54
  describe '#gen_disallow' do
54
-
55
+
55
56
  context 'when nested' do
56
57
  it 'generates nested negative lookahead code' do
57
58
  nested_code {|g| g.gen_disallow action }.
58
59
  should == '(@scanner.skip(/(?!\w+)/) && true)'
59
60
  end
60
61
  end
61
-
62
+
62
63
  context 'when top-level' do
63
64
  it 'generates top level negative lookahead code' do
64
65
  top_level_code {|g| g.gen_disallow action }.
@@ -66,12 +67,14 @@ end
66
67
  end
67
68
  end
68
69
  end
69
-
70
+
70
71
  describe '#gen_dispatch_action' do
71
-
72
+
73
+ let(:code) { NodeCode.new('Word', 'parsed') }
74
+
72
75
  context 'when nested' do
73
76
  it 'generates nested matching code with a direct action and a dispatch action' do
74
- nested_code {|g| g.gen_dispatch_action action, 'Word', 'parsed' }.
77
+ nested_code {|g| g.gen_dispatch_action action, code }.
75
78
  should == (<<-CODE).strip
76
79
  begin
77
80
  (r = begin
@@ -83,10 +86,10 @@ end
83
86
  CODE
84
87
  end
85
88
  end
86
-
89
+
87
90
  context 'when top-level' do
88
91
  it 'generates top level matching code with a direct action and a dispatch action' do
89
- top_level_code {|g| g.gen_dispatch_action action, 'Word', 'parsed' }.
92
+ top_level_code {|g| g.gen_dispatch_action action, code }.
90
93
  should == (<<-CODE).strip
91
94
  (r = begin
92
95
  (r = @scanner.scan(/\\w+/)) &&
@@ -97,12 +100,14 @@ Word.parsed([r])
97
100
  end
98
101
  end
99
102
  end
100
-
103
+
101
104
  describe '#gen_direct_action' do
102
-
105
+
106
+ let(:code) { ActionCode.new('|_| _.size') }
107
+
103
108
  context 'when nested' do
104
109
  it 'generates nested matching code with nested direct actions' do
105
- nested_code {|g| g.gen_direct_action action, ActionCode.new('|_| _.size') }.
110
+ nested_code {|g| g.gen_direct_action action, code }.
106
111
  should == (<<-CODE).strip
107
112
  begin
108
113
  (r = begin
@@ -114,10 +119,10 @@ end
114
119
  CODE
115
120
  end
116
121
  end
117
-
122
+
118
123
  context 'when top-level' do
119
124
  it 'generates top level matching code with nested direct actions' do
120
- top_level_code {|g| g.gen_direct_action action, ActionCode.new('|_| _.size') }.
125
+ top_level_code {|g| g.gen_direct_action action, code }.
121
126
  should == (<<-CODE).strip
122
127
  (r = begin
123
128
  (r = @scanner.scan(/\\w+/)) &&
@@ -128,16 +133,16 @@ end) &&
128
133
  end
129
134
  end
130
135
  end
131
-
136
+
132
137
  describe '#gen_token' do
133
-
138
+
134
139
  context 'when nested' do
135
140
  it 'generates nested token matching code' do
136
141
  nested_code {|g| g.gen_token action }.
137
142
  should == '@scanner.scan(/\w+/)'
138
143
  end
139
144
  end
140
-
145
+
141
146
  context 'when top-level' do
142
147
  it 'generates top level token matching code' do
143
148
  top_level_code {|g| g.gen_token action }.
@@ -145,16 +150,16 @@ end) &&
145
150
  end
146
151
  end
147
152
  end
148
-
153
+
149
154
  describe '#gen_skip' do
150
-
155
+
151
156
  context 'when nested' do
152
157
  it 'generates nested skipping code' do
153
158
  nested_code {|g| g.gen_skip action }.
154
159
  should == '(@scanner.skip(/\w+/) && true)'
155
160
  end
156
161
  end
157
-
162
+
158
163
  context 'when top-level' do
159
164
  it 'generates top level skipping code' do
160
165
  top_level_code {|g| g.gen_skip action }.
@@ -162,7 +167,7 @@ end) &&
162
167
  end
163
168
  end
164
169
  end
165
-
170
+
166
171
  describe '#gen_intermediate' do
167
172
  it 'generates nested matching code with a direct action' do
168
173
  nested_code {|g| g.gen_intermediate action }.
@@ -174,26 +179,26 @@ end
174
179
  CODE
175
180
  end
176
181
  end
177
-
182
+
178
183
  describe '#gen_intermediate_assert' do
179
184
  it 'generates intermediate positive lookahead code' do
180
185
  nested_code {|g| g.gen_intermediate_assert action }.
181
186
  should == '@scanner.skip(/(?=\w+)/)'
182
187
  end
183
188
  end
184
-
189
+
185
190
  describe '#gen_intermediate_disallow' do
186
191
  it 'generates intermediate negative lookahead code' do
187
192
  nested_code {|g| g.gen_intermediate_disallow action }.
188
193
  should == '@scanner.skip(/(?!\w+)/)'
189
194
  end
190
195
  end
191
-
196
+
192
197
  describe '#gen_intermediate_skip' do
193
198
  it 'generates intermediate skipping code' do
194
199
  nested_code {|g| g.gen_intermediate_skip action }.
195
200
  should == '@scanner.skip(/\w+/)'
196
201
  end
197
202
  end
198
-
203
+
199
204
  end