rattler 0.4.2 → 0.5.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 (347) hide show
  1. data/README.rdoc +9 -3
  2. data/features/command_line/dest_option.feature +1 -1
  3. data/features/command_line/lib_option.feature +2 -2
  4. data/features/command_line/output_option.feature +2 -2
  5. data/features/command_line/parser_generator.feature +3 -3
  6. data/features/grammar/any_character.feature +0 -4
  7. data/features/grammar/back_reference.feature +0 -4
  8. data/features/grammar/character_class.feature +0 -4
  9. data/features/grammar/comments.feature +0 -4
  10. data/features/grammar/e_symbol.feature +18 -0
  11. data/features/grammar/eof.feature +0 -4
  12. data/features/grammar/fail.feature +0 -4
  13. data/features/grammar/list_matching.feature +52 -3
  14. data/features/grammar/literal.feature +0 -4
  15. data/features/grammar/negative_lookahead.feature +0 -4
  16. data/features/grammar/negative_semantic_predicate.feature +99 -0
  17. data/features/grammar/node_action.feature +17 -4
  18. data/features/grammar/nonterminal.feature +3 -7
  19. data/features/grammar/one_or_more.feature +0 -4
  20. data/features/grammar/optional.feature +0 -4
  21. data/features/grammar/ordered_choice.feature +0 -4
  22. data/features/grammar/positive_lookahead.feature +0 -4
  23. data/features/grammar/positive_semantic_predicate.feature +99 -0
  24. data/features/grammar/posix_class.feature +3 -6
  25. data/features/grammar/repeat.feature +50 -0
  26. data/features/grammar/sequence.feature +0 -4
  27. data/features/grammar/side_effect.feature +81 -0
  28. data/features/grammar/skip_operator.feature +2 -5
  29. data/features/grammar/start_rule.feature +1 -5
  30. data/features/grammar/symantic_action.feature +9 -4
  31. data/features/grammar/token.feature +0 -4
  32. data/features/grammar/whitespace.feature +0 -4
  33. data/features/grammar/word_literal.feature +0 -4
  34. data/features/grammar/zero_or_more.feature +0 -4
  35. data/features/step_definitions/grammar_steps.rb +5 -1
  36. data/lib/rattler/back_end/optimizer.rb +1 -0
  37. data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +20 -8
  38. data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +10 -7
  39. data/lib/rattler/back_end/optimizer/specialize_repeat.rb +40 -0
  40. data/lib/rattler/back_end/parser_generator.rb +11 -6
  41. data/lib/rattler/back_end/parser_generator/delegating_generator.rb +20 -0
  42. data/lib/rattler/back_end/parser_generator/e_symbol_generator.rb +52 -0
  43. data/lib/rattler/back_end/parser_generator/eof_generator.rb +58 -0
  44. data/lib/rattler/back_end/parser_generator/expr_generator.rb +6 -2
  45. data/lib/rattler/back_end/parser_generator/gen_method_names.rb +15 -5
  46. data/lib/rattler/back_end/parser_generator/general_list_generator.rb +194 -0
  47. data/lib/rattler/back_end/parser_generator/general_repeat_generator.rb +177 -0
  48. data/lib/rattler/back_end/parser_generator/label_generator.rb +4 -1
  49. data/lib/rattler/back_end/parser_generator/list0_generating.rb +36 -0
  50. data/lib/rattler/back_end/parser_generator/list1_generating.rb +30 -0
  51. data/lib/rattler/back_end/parser_generator/list_generator.rb +16 -20
  52. data/lib/rattler/back_end/parser_generator/one_or_more_generating.rb +25 -0
  53. data/lib/rattler/back_end/parser_generator/{optional_generator.rb → optional_generating.rb} +66 -81
  54. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +4 -4
  55. data/lib/rattler/back_end/parser_generator/repeat_generator.rb +53 -0
  56. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +2 -2
  57. data/lib/rattler/back_end/parser_generator/sub_generating.rb +16 -18
  58. data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
  59. data/lib/rattler/back_end/parser_generator/zero_or_more_generating.rb +31 -0
  60. data/lib/rattler/grammar/grammar_parser.rb +20 -0
  61. data/lib/rattler/grammar/metagrammar.rb +131 -13
  62. data/lib/rattler/grammar/rattler.rtlr +25 -12
  63. data/lib/rattler/parsers.rb +9 -5
  64. data/lib/rattler/parsers/assert_code.rb +31 -0
  65. data/lib/rattler/parsers/atomic.rb +19 -0
  66. data/lib/rattler/parsers/direct_action.rb +12 -4
  67. data/lib/rattler/parsers/disallow_code.rb +31 -0
  68. data/lib/rattler/parsers/dispatch_action.rb +3 -2
  69. data/lib/rattler/parsers/e_symbol.rb +47 -0
  70. data/lib/rattler/parsers/effect_code.rb +31 -0
  71. data/lib/rattler/parsers/eof.rb +6 -13
  72. data/lib/rattler/parsers/list_parser.rb +33 -14
  73. data/lib/rattler/parsers/match.rb +1 -6
  74. data/lib/rattler/parsers/parser_dsl.rb +78 -35
  75. data/lib/rattler/parsers/predicate.rb +1 -4
  76. data/lib/rattler/parsers/repeat.rb +76 -0
  77. data/lib/rattler/parsers/semantic_assert.rb +19 -0
  78. data/lib/rattler/parsers/semantic_disallow.rb +19 -0
  79. data/lib/rattler/parsers/side_effect.rb +19 -0
  80. data/lib/rattler/parsers/skip.rb +1 -9
  81. data/lib/rattler/parsers/token.rb +1 -6
  82. data/lib/rattler/util/graphviz/node_builder.rb +6 -3
  83. data/spec/rattler/back_end/assert_compiler_examples.rb +187 -0
  84. data/spec/rattler/back_end/direct_action_compiler_examples.rb +227 -0
  85. data/spec/rattler/back_end/disallow_compiler_examples.rb +187 -0
  86. data/spec/rattler/back_end/dispatch_action_compiler_examples.rb +225 -0
  87. data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +45 -33
  88. data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +32 -172
  89. data/spec/rattler/back_end/parser_generator/e_symbol_generator_spec.rb +149 -0
  90. data/spec/rattler/back_end/parser_generator/eof_generator_spec.rb +152 -0
  91. data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +4 -4
  92. data/spec/rattler/back_end/parser_generator/list0_generator_examples.rb +322 -0
  93. data/spec/rattler/back_end/parser_generator/list1_generator_examples.rb +343 -0
  94. data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +597 -140
  95. data/spec/rattler/back_end/parser_generator/one_or_more_generator_examples.rb +292 -0
  96. data/spec/rattler/back_end/parser_generator/optional_generator_examples.rb +233 -0
  97. data/spec/rattler/back_end/parser_generator/repeat_generator_spec.rb +281 -0
  98. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_examples.rb +277 -0
  99. data/spec/rattler/back_end/semantic_assert_compiler_examples.rb +152 -0
  100. data/spec/rattler/back_end/semantic_disallow_compiler_examples.rb +152 -0
  101. data/spec/rattler/back_end/shared_compiler_examples.rb +106 -651
  102. data/spec/rattler/back_end/side_effect_compiler_examples.rb +227 -0
  103. data/spec/rattler/back_end/skip_compiler_examples.rb +161 -0
  104. data/spec/rattler/back_end/token_compiler_examples.rb +262 -0
  105. data/spec/rattler/grammar/grammar_parser_spec.rb +302 -23
  106. data/spec/rattler/parsers/apply_spec.rb +6 -0
  107. data/spec/rattler/parsers/assert_spec.rb +18 -7
  108. data/spec/rattler/parsers/back_reference_spec.rb +9 -0
  109. data/spec/rattler/parsers/choice_spec.rb +36 -21
  110. data/spec/rattler/parsers/direct_action_spec.rb +76 -36
  111. data/spec/rattler/parsers/disallow_spec.rb +18 -7
  112. data/spec/rattler/parsers/dispatch_action_spec.rb +128 -22
  113. data/spec/rattler/parsers/e_symbol_spec.rb +30 -0
  114. data/spec/rattler/parsers/eof_spec.rb +15 -6
  115. data/spec/rattler/parsers/label_spec.rb +15 -2
  116. data/spec/rattler/parsers/list_parser_spec.rb +187 -0
  117. data/spec/rattler/parsers/match_spec.rb +16 -7
  118. data/spec/rattler/parsers/parser_dsl_spec.rb +82 -23
  119. data/spec/rattler/parsers/repeat_spec.rb +233 -0
  120. data/spec/rattler/parsers/semantic_assert_spec.rb +83 -0
  121. data/spec/rattler/parsers/semantic_disallow_spec.rb +83 -0
  122. data/spec/rattler/parsers/sequence_spec.rb +34 -20
  123. data/spec/rattler/parsers/side_effect_spec.rb +214 -0
  124. data/spec/rattler/parsers/skip_spec.rb +17 -6
  125. data/spec/rattler_spec.rb +2 -0
  126. data/spec/support/compiler_spec_helper.rb +8 -0
  127. metadata +156 -447
  128. data/bin/rtlr.compiled.rbc +0 -201
  129. data/features/step_definitions/cli_steps.rbc +0 -149
  130. data/features/step_definitions/grammar_steps.rbc +0 -1211
  131. data/features/support/env.rbc +0 -389
  132. data/lib/rattler.rbc +0 -1231
  133. data/lib/rattler/back_end.rbc +0 -286
  134. data/lib/rattler/back_end/compiler.rbc +0 -1394
  135. data/lib/rattler/back_end/optimizer.rbc +0 -2000
  136. data/lib/rattler/back_end/optimizer/composite_reducing.rbc +0 -337
  137. data/lib/rattler/back_end/optimizer/flatten_choice.rbc +0 -443
  138. data/lib/rattler/back_end/optimizer/flatten_sequence.rbc +0 -827
  139. data/lib/rattler/back_end/optimizer/flattening.rbc +0 -570
  140. data/lib/rattler/back_end/optimizer/inline_regular_rules.rbc +0 -691
  141. data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rbc +0 -1299
  142. data/lib/rattler/back_end/optimizer/join_match_choice.rbc +0 -523
  143. data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rbc +0 -619
  144. data/lib/rattler/back_end/optimizer/join_match_sequence.rbc +0 -174
  145. data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rbc +0 -1505
  146. data/lib/rattler/back_end/optimizer/join_predicate_match.rbc +0 -174
  147. data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rbc +0 -620
  148. data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rbc +0 -1502
  149. data/lib/rattler/back_end/optimizer/join_predicate_or_match.rbc +0 -174
  150. data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rbc +0 -616
  151. data/lib/rattler/back_end/optimizer/match_joining.rbc +0 -1454
  152. data/lib/rattler/back_end/optimizer/optimization.rbc +0 -1366
  153. data/lib/rattler/back_end/optimizer/optimization_context.rbc +0 -1386
  154. data/lib/rattler/back_end/optimizer/optimization_sequence.rbc +0 -520
  155. data/lib/rattler/back_end/optimizer/optimize_children.rbc +0 -793
  156. data/lib/rattler/back_end/optimizer/reduce_repeat_match.rbc +0 -788
  157. data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rbc +0 -508
  158. data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rbc +0 -807
  159. data/lib/rattler/back_end/optimizer/simplify_token_match.rbc +0 -561
  160. data/lib/rattler/back_end/parser_generator.rbc +0 -1326
  161. data/lib/rattler/back_end/parser_generator/apply_generator.rbc +0 -2148
  162. data/lib/rattler/back_end/parser_generator/assert_generator.rbc +0 -1967
  163. data/lib/rattler/back_end/parser_generator/back_reference_generator.rbc +0 -1665
  164. data/lib/rattler/back_end/parser_generator/choice_generator.rbc +0 -2793
  165. data/lib/rattler/back_end/parser_generator/direct_action_generator.rbc +0 -1071
  166. data/lib/rattler/back_end/parser_generator/disallow_generator.rbc +0 -1967
  167. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rbc +0 -1071
  168. data/lib/rattler/back_end/parser_generator/expr_generator.rbc +0 -2295
  169. data/lib/rattler/back_end/parser_generator/fail_generator.rbc +0 -1216
  170. data/lib/rattler/back_end/parser_generator/gen_method_names.rbc +0 -296
  171. data/lib/rattler/back_end/parser_generator/group_match.rbc +0 -612
  172. data/lib/rattler/back_end/parser_generator/group_match_generator.rbc +0 -1647
  173. data/lib/rattler/back_end/parser_generator/label_generator.rbc +0 -1401
  174. data/lib/rattler/back_end/parser_generator/list1_generator.rb +0 -54
  175. data/lib/rattler/back_end/parser_generator/list1_generator.rbc +0 -1237
  176. data/lib/rattler/back_end/parser_generator/list_generating.rb +0 -71
  177. data/lib/rattler/back_end/parser_generator/list_generating.rbc +0 -1900
  178. data/lib/rattler/back_end/parser_generator/list_generator.rbc +0 -1068
  179. data/lib/rattler/back_end/parser_generator/match_generator.rbc +0 -1743
  180. data/lib/rattler/back_end/parser_generator/nested.rbc +0 -496
  181. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +0 -56
  182. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rbc +0 -1277
  183. data/lib/rattler/back_end/parser_generator/optional_generator.rbc +0 -2025
  184. data/lib/rattler/back_end/parser_generator/predicate_propogating.rbc +0 -648
  185. data/lib/rattler/back_end/parser_generator/repeat_generating.rb +0 -57
  186. data/lib/rattler/back_end/parser_generator/repeat_generating.rbc +0 -1549
  187. data/lib/rattler/back_end/parser_generator/rule_generator.rbc +0 -1239
  188. data/lib/rattler/back_end/parser_generator/rule_set_generator.rbc +0 -2641
  189. data/lib/rattler/back_end/parser_generator/sequence_generator.rbc +0 -4867
  190. data/lib/rattler/back_end/parser_generator/skip_generator.rbc +0 -1278
  191. data/lib/rattler/back_end/parser_generator/skip_propogating.rbc +0 -432
  192. data/lib/rattler/back_end/parser_generator/sub_generating.rbc +0 -2785
  193. data/lib/rattler/back_end/parser_generator/token_generator.rbc +0 -755
  194. data/lib/rattler/back_end/parser_generator/token_propogating.rbc +0 -324
  195. data/lib/rattler/back_end/parser_generator/top_level.rbc +0 -352
  196. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +0 -53
  197. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rbc +0 -1111
  198. data/lib/rattler/back_end/ruby_generator.rbc +0 -1841
  199. data/lib/rattler/grammar.rbc +0 -557
  200. data/lib/rattler/grammar/analysis.rbc +0 -1944
  201. data/lib/rattler/grammar/grammar.rbc +0 -1090
  202. data/lib/rattler/grammar/grammar_dsl.rbc +0 -1401
  203. data/lib/rattler/grammar/grammar_parser.rbc +0 -2096
  204. data/lib/rattler/grammar/metagrammar.rbc +0 -11014
  205. data/lib/rattler/parsers.rbc +0 -1006
  206. data/lib/rattler/parsers/action_code.rbc +0 -1577
  207. data/lib/rattler/parsers/apply.rbc +0 -562
  208. data/lib/rattler/parsers/assert.rbc +0 -378
  209. data/lib/rattler/parsers/back_reference.rbc +0 -871
  210. data/lib/rattler/parsers/choice.rbc +0 -607
  211. data/lib/rattler/parsers/combinator_parser.rbc +0 -612
  212. data/lib/rattler/parsers/combining.rbc +0 -570
  213. data/lib/rattler/parsers/direct_action.rbc +0 -1472
  214. data/lib/rattler/parsers/disallow.rbc +0 -379
  215. data/lib/rattler/parsers/dispatch_action.rbc +0 -2078
  216. data/lib/rattler/parsers/eof.rbc +0 -567
  217. data/lib/rattler/parsers/fail.rbc +0 -745
  218. data/lib/rattler/parsers/label.rbc +0 -749
  219. data/lib/rattler/parsers/list.rbc +0 -292
  220. data/lib/rattler/parsers/list0.rb +0 -26
  221. data/lib/rattler/parsers/list0.rbc +0 -292
  222. data/lib/rattler/parsers/list1.rb +0 -26
  223. data/lib/rattler/parsers/list1.rbc +0 -305
  224. data/lib/rattler/parsers/list_parser.rbc +0 -886
  225. data/lib/rattler/parsers/match.rbc +0 -621
  226. data/lib/rattler/parsers/node_code.rbc +0 -1064
  227. data/lib/rattler/parsers/one_or_more.rb +0 -47
  228. data/lib/rattler/parsers/one_or_more.rbc +0 -475
  229. data/lib/rattler/parsers/optional.rb +0 -42
  230. data/lib/rattler/parsers/optional.rbc +0 -450
  231. data/lib/rattler/parsers/parser.rbc +0 -994
  232. data/lib/rattler/parsers/parser_dsl.rbc +0 -4765
  233. data/lib/rattler/parsers/predicate.rbc +0 -490
  234. data/lib/rattler/parsers/rule.rbc +0 -777
  235. data/lib/rattler/parsers/rule_set.rbc +0 -1438
  236. data/lib/rattler/parsers/sequence.rbc +0 -1040
  237. data/lib/rattler/parsers/skip.rbc +0 -613
  238. data/lib/rattler/parsers/token.rbc +0 -457
  239. data/lib/rattler/parsers/zero_or_more.rb +0 -40
  240. data/lib/rattler/parsers/zero_or_more.rbc +0 -462
  241. data/lib/rattler/runner.rbc +0 -3813
  242. data/lib/rattler/runtime.rbc +0 -370
  243. data/lib/rattler/runtime/extended_packrat_parser.rbc +0 -2351
  244. data/lib/rattler/runtime/packrat_parser.rbc +0 -1390
  245. data/lib/rattler/runtime/parse_failure.rbc +0 -909
  246. data/lib/rattler/runtime/parse_node.rbc +0 -1007
  247. data/lib/rattler/runtime/parser.rbc +0 -2267
  248. data/lib/rattler/runtime/parser_helper.rbc +0 -337
  249. data/lib/rattler/runtime/recursive_descent_parser.rbc +0 -942
  250. data/lib/rattler/util.rbc +0 -286
  251. data/lib/rattler/util/graphviz.rbc +0 -327
  252. data/lib/rattler/util/graphviz/node_builder.rbc +0 -2207
  253. data/lib/rattler/util/line_counter.rbc +0 -988
  254. data/lib/rattler/util/node.rbc +0 -2393
  255. data/lib/rattler/util/parser_spec_helper.rbc +0 -2533
  256. data/spec/rattler/back_end/compiler_spec.rbc +0 -1187
  257. data/spec/rattler/back_end/optimizer/flatten_choice_spec.rbc +0 -2093
  258. data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rbc +0 -4055
  259. data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rbc +0 -2345
  260. data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rbc +0 -7006
  261. data/spec/rattler/back_end/optimizer/join_match_choice_spec.rbc +0 -3252
  262. data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rbc +0 -3681
  263. data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rbc +0 -5603
  264. data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rbc +0 -5232
  265. data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rbc +0 -4272
  266. data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rbc +0 -4342
  267. data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rbc +0 -2960
  268. data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rbc +0 -6929
  269. data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rbc +0 -2327
  270. data/spec/rattler/back_end/optimizer_spec.rbc +0 -372
  271. data/spec/rattler/back_end/parser_generator/apply_generator_spec.rbc +0 -4710
  272. data/spec/rattler/back_end/parser_generator/assert_generator_spec.rbc +0 -4697
  273. data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rbc +0 -4855
  274. data/spec/rattler/back_end/parser_generator/choice_generator_spec.rbc +0 -5350
  275. data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rbc +0 -4737
  276. data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rbc +0 -4697
  277. data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rbc +0 -4731
  278. data/spec/rattler/back_end/parser_generator/fail_generator_spec.rbc +0 -2115
  279. data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rbc +0 -4195
  280. data/spec/rattler/back_end/parser_generator/group_match_spec.rbc +0 -1414
  281. data/spec/rattler/back_end/parser_generator/label_generator_spec.rbc +0 -4696
  282. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +0 -309
  283. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rbc +0 -5213
  284. data/spec/rattler/back_end/parser_generator/list_generator_spec.rbc +0 -5179
  285. data/spec/rattler/back_end/parser_generator/match_generator_spec.rbc +0 -4681
  286. data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +0 -259
  287. data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rbc +0 -4957
  288. data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +0 -190
  289. data/spec/rattler/back_end/parser_generator/optional_generator_spec.rbc +0 -4704
  290. data/spec/rattler/back_end/parser_generator/rule_generator_spec.rbc +0 -545
  291. data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rbc +0 -1110
  292. data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rbc +0 -5453
  293. data/spec/rattler/back_end/parser_generator/skip_generator_spec.rbc +0 -4691
  294. data/spec/rattler/back_end/parser_generator/token_generator_spec.rbc +0 -4691
  295. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +0 -244
  296. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rbc +0 -4924
  297. data/spec/rattler/back_end/ruby_generator_spec.rbc +0 -2460
  298. data/spec/rattler/back_end/shared_compiler_examples.rbc +0 -41886
  299. data/spec/rattler/grammar/analysis_spec.rbc +0 -4365
  300. data/spec/rattler/grammar/grammar_parser_spec.rbc +0 -10344
  301. data/spec/rattler/grammar/grammar_spec.rbc +0 -1701
  302. data/spec/rattler/parsers/action_code_spec.rbc +0 -4674
  303. data/spec/rattler/parsers/apply_spec.rbc +0 -851
  304. data/spec/rattler/parsers/assert_spec.rbc +0 -752
  305. data/spec/rattler/parsers/back_reference_spec.rbc +0 -1002
  306. data/spec/rattler/parsers/choice_spec.rbc +0 -1696
  307. data/spec/rattler/parsers/combinator_parser_spec.rbc +0 -361
  308. data/spec/rattler/parsers/direct_action_spec.rbc +0 -5222
  309. data/spec/rattler/parsers/disallow_spec.rbc +0 -752
  310. data/spec/rattler/parsers/dispatch_action_spec.rbc +0 -3033
  311. data/spec/rattler/parsers/eof_spec.rbc +0 -728
  312. data/spec/rattler/parsers/fail_spec.rbc +0 -548
  313. data/spec/rattler/parsers/label_spec.rbc +0 -1091
  314. data/spec/rattler/parsers/list0_spec.rb +0 -82
  315. data/spec/rattler/parsers/list0_spec.rbc +0 -2308
  316. data/spec/rattler/parsers/list1_spec.rb +0 -82
  317. data/spec/rattler/parsers/list1_spec.rbc +0 -2287
  318. data/spec/rattler/parsers/list_spec.rbc +0 -2308
  319. data/spec/rattler/parsers/match_spec.rbc +0 -780
  320. data/spec/rattler/parsers/node_code_spec.rbc +0 -1754
  321. data/spec/rattler/parsers/one_or_more_spec.rb +0 -64
  322. data/spec/rattler/parsers/one_or_more_spec.rbc +0 -1698
  323. data/spec/rattler/parsers/optional_spec.rb +0 -64
  324. data/spec/rattler/parsers/optional_spec.rbc +0 -1717
  325. data/spec/rattler/parsers/parser_dsl_spec.rbc +0 -10150
  326. data/spec/rattler/parsers/rule_set_spec.rbc +0 -1060
  327. data/spec/rattler/parsers/sequence_spec.rbc +0 -2899
  328. data/spec/rattler/parsers/skip_spec.rbc +0 -753
  329. data/spec/rattler/parsers/token_spec.rbc +0 -1511
  330. data/spec/rattler/parsers/zero_or_more_spec.rb +0 -64
  331. data/spec/rattler/parsers/zero_or_more_spec.rbc +0 -1719
  332. data/spec/rattler/runtime/extended_packrat_parser_spec.rbc +0 -1341
  333. data/spec/rattler/runtime/packrat_parser_spec.rbc +0 -210
  334. data/spec/rattler/runtime/parse_failure_spec.rbc +0 -2244
  335. data/spec/rattler/runtime/parse_node_spec.rbc +0 -2008
  336. data/spec/rattler/runtime/parser_spec.rbc +0 -2757
  337. data/spec/rattler/runtime/recursive_descent_parser_spec.rbc +0 -210
  338. data/spec/rattler/runtime/shared_parser_examples.rbc +0 -2567
  339. data/spec/rattler/util/graphviz/node_builder_spec.rbc +0 -3439
  340. data/spec/rattler/util/line_counter_spec.rbc +0 -2272
  341. data/spec/rattler/util/node_spec.rbc +0 -15023
  342. data/spec/rattler_spec.rbc +0 -1591
  343. data/spec/spec_helper.rbc +0 -336
  344. data/spec/support/combinator_parser_spec_helper.rbc +0 -1284
  345. data/spec/support/compiler_spec_helper.rbc +0 -1941
  346. data/spec/support/parser_generator_spec_helper.rbc +0 -718
  347. data/spec/support/runtime_parser_spec_helper.rbc +0 -313
@@ -1,126 +1,413 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/list0_generator_examples')
3
+ require File.expand_path(File.dirname(__FILE__) + '/list1_generator_examples')
2
4
 
3
- include Rattler::BackEnd::ParserGenerator
4
5
  include Rattler::Parsers
5
6
 
6
- describe ListGenerator do
7
+ describe Rattler::BackEnd::ParserGenerator::ListGenerator do
7
8
 
8
9
  include ParserGeneratorSpecHelper
9
10
 
10
- let(:list) { List0[Match[/w+/], Match[/[,;]/]] }
11
+ let(:list) { ListParser[term_parser, sep_parser, *bounds] }
12
+
13
+ it_behaves_like 'a list0 generator'
14
+ it_behaves_like 'a list1 generator'
15
+
16
+ let(:term_parser) { Match[/w+/] }
17
+ let(:sep_parser) { Match[/[,;]/] }
11
18
 
12
19
  describe '#gen_basic' do
13
20
 
14
- let :list do
15
- List0[Choice[Match[/[[:alpha:]]/], Match[/[[:digit:]]/]], Match[/[,;]/]]
16
- end
21
+ let(:term_parser) { Choice[Match[/[[:alpha:]]/], Match[/[[:digit:]]/]] }
22
+
23
+ context 'given a list with no upper bound' do
24
+
25
+ let(:bounds) { [2, nil] }
17
26
 
18
- context 'when nested' do
19
- it 'generates nested list matching code' do
20
- nested_code {|g| g.gen_basic list }.
21
- should == (<<-CODE).strip
27
+ context 'when nested' do
28
+ it 'generates nested list matching code' do
29
+ nested_code {|g| g.gen_basic list }.
30
+ should == (<<-CODE).strip
22
31
  begin
23
32
  a = []
24
- lp = nil
33
+ sp = @scanner.pos
34
+ ep = nil
25
35
  while r = begin
26
36
  @scanner.scan(/[[:alpha:]]/) ||
27
37
  @scanner.scan(/[[:digit:]]/)
28
38
  end
29
- lp = @scanner.pos
39
+ ep = @scanner.pos
30
40
  a << r
31
41
  break unless @scanner.skip(/[,;]/)
32
42
  end
33
- @scanner.pos = lp unless lp.nil?
34
- a
43
+ if a.size >= 2
44
+ @scanner.pos = ep unless ep.nil?
45
+ a
46
+ else
47
+ @scanner.pos = sp
48
+ false
49
+ end
35
50
  end
36
- CODE
51
+ CODE
52
+ end
37
53
  end
38
- end
39
54
 
40
- context 'when top-level' do
41
- it 'generates top-level list matching code' do
42
- top_level_code {|g| g.gen_basic list }.
43
- should == (<<-CODE).strip
55
+ context 'when top-level' do
56
+ it 'generates top-level list matching code' do
57
+ top_level_code {|g| g.gen_basic list }.
58
+ should == (<<-CODE).strip
44
59
  a = []
45
- lp = nil
60
+ sp = @scanner.pos
61
+ ep = nil
46
62
  while r = begin
47
63
  @scanner.scan(/[[:alpha:]]/) ||
48
64
  @scanner.scan(/[[:digit:]]/)
49
65
  end
50
- lp = @scanner.pos
66
+ ep = @scanner.pos
51
67
  a << r
52
68
  break unless @scanner.skip(/[,;]/)
53
69
  end
54
- @scanner.pos = lp unless lp.nil?
55
- a
56
- CODE
70
+ if a.size >= 2
71
+ @scanner.pos = ep unless ep.nil?
72
+ a
73
+ else
74
+ @scanner.pos = sp
75
+ false
76
+ end
77
+ CODE
78
+ end
57
79
  end
58
80
  end
59
81
 
60
- context 'with a non-capturing parser' do
82
+ context 'given a list with an upper bound' do
61
83
 
62
- let(:list) { List0[Skip[Match[/w+/]], Match[/[,;]/]] }
84
+ let(:bounds) { [2, 4] }
63
85
 
64
86
  context 'when nested' do
65
- it 'generates nested list skipping code' do
87
+ it 'generates nested list matching code' do
66
88
  nested_code {|g| g.gen_basic list }.
67
89
  should == (<<-CODE).strip
68
90
  begin
69
- lp = nil
70
- while @scanner.skip(/w+/)
71
- lp = @scanner.pos
91
+ a = []
92
+ sp = @scanner.pos
93
+ ep = nil
94
+ while r = begin
95
+ @scanner.scan(/[[:alpha:]]/) ||
96
+ @scanner.scan(/[[:digit:]]/)
97
+ end
98
+ ep = @scanner.pos
99
+ a << r
100
+ break unless a.size < 4
72
101
  break unless @scanner.skip(/[,;]/)
73
102
  end
74
- @scanner.pos = lp unless lp.nil?
75
- true
103
+ if a.size >= 2
104
+ @scanner.pos = ep unless ep.nil?
105
+ a
106
+ else
107
+ @scanner.pos = sp
108
+ false
109
+ end
76
110
  end
77
111
  CODE
78
112
  end
79
113
  end
80
114
 
81
115
  context 'when top-level' do
82
- it 'generates nested list skipping code' do
116
+ it 'generates top-level list matching code' do
83
117
  top_level_code {|g| g.gen_basic list }.
84
118
  should == (<<-CODE).strip
85
- lp = nil
86
- while @scanner.skip(/w+/)
87
- lp = @scanner.pos
119
+ a = []
120
+ sp = @scanner.pos
121
+ ep = nil
122
+ while r = begin
123
+ @scanner.scan(/[[:alpha:]]/) ||
124
+ @scanner.scan(/[[:digit:]]/)
125
+ end
126
+ ep = @scanner.pos
127
+ a << r
128
+ break unless a.size < 4
88
129
  break unless @scanner.skip(/[,;]/)
89
130
  end
90
- @scanner.pos = lp unless lp.nil?
91
- true
131
+ if a.size >= 2
132
+ @scanner.pos = ep unless ep.nil?
133
+ a
134
+ else
135
+ @scanner.pos = sp
136
+ false
137
+ end
92
138
  CODE
93
139
  end
94
140
  end
95
141
  end
142
+
143
+ context 'given a non-capturing list' do
144
+
145
+ let(:term_parser) { Skip[Match[/w+/]] }
146
+
147
+ context 'with no upper bound' do
148
+
149
+ let(:bounds) { [2, nil] }
150
+
151
+ context 'when nested' do
152
+ it 'generates nested list skipping code' do
153
+ nested_code {|g| g.gen_basic list }.
154
+ should == (<<-CODE).strip
155
+ begin
156
+ c = 0
157
+ sp = @scanner.pos
158
+ ep = nil
159
+ while @scanner.skip(/w+/)
160
+ c += 1
161
+ ep = @scanner.pos
162
+ break unless @scanner.skip(/[,;]/)
163
+ end
164
+ if c >= 2
165
+ @scanner.pos = ep unless ep.nil?
166
+ true
167
+ else
168
+ @scanner.pos = sp
169
+ false
170
+ end
171
+ end
172
+ CODE
173
+ end
174
+ end
175
+
176
+ context 'when top-level' do
177
+ it 'generates top-level list skipping code' do
178
+ top_level_code {|g| g.gen_basic list }.
179
+ should == (<<-CODE).strip
180
+ c = 0
181
+ sp = @scanner.pos
182
+ ep = nil
183
+ while @scanner.skip(/w+/)
184
+ c += 1
185
+ ep = @scanner.pos
186
+ break unless @scanner.skip(/[,;]/)
187
+ end
188
+ if c >= 2
189
+ @scanner.pos = ep unless ep.nil?
190
+ true
191
+ else
192
+ @scanner.pos = sp
193
+ false
194
+ end
195
+ CODE
196
+ end
197
+ end
198
+ end
199
+
200
+ context 'with an upper bound' do
201
+
202
+ let(:bounds) { [2, 4] }
203
+
204
+ context 'when nested' do
205
+ it 'generates nested list skipping code' do
206
+ nested_code {|g| g.gen_basic list }.
207
+ should == (<<-CODE).strip
208
+ begin
209
+ c = 0
210
+ sp = @scanner.pos
211
+ ep = nil
212
+ while @scanner.skip(/w+/)
213
+ c += 1
214
+ ep = @scanner.pos
215
+ break unless c < 4
216
+ break unless @scanner.skip(/[,;]/)
217
+ end
218
+ if c >= 2
219
+ @scanner.pos = ep unless ep.nil?
220
+ true
221
+ else
222
+ @scanner.pos = sp
223
+ false
224
+ end
225
+ end
226
+ CODE
227
+ end
228
+ end
229
+
230
+ context 'when top-level' do
231
+ it 'generates top-level list skipping code' do
232
+ top_level_code {|g| g.gen_basic list }.
233
+ should == (<<-CODE).strip
234
+ c = 0
235
+ sp = @scanner.pos
236
+ ep = nil
237
+ while @scanner.skip(/w+/)
238
+ c += 1
239
+ ep = @scanner.pos
240
+ break unless c < 4
241
+ break unless @scanner.skip(/[,;]/)
242
+ end
243
+ if c >= 2
244
+ @scanner.pos = ep unless ep.nil?
245
+ true
246
+ else
247
+ @scanner.pos = sp
248
+ false
249
+ end
250
+ CODE
251
+ end
252
+ end
253
+ end
254
+ end
96
255
  end
97
256
 
98
257
  describe '#gen_assert' do
99
258
 
100
- context 'when nested' do
101
- it 'generates "true"' do
102
- nested_code {|g| g.gen_assert list }.should == 'true'
259
+ context 'given a list with no upper bound' do
260
+
261
+ let(:bounds) { [2, nil] }
262
+
263
+ context 'when nested' do
264
+ it 'generates nested positive lookahead code' do
265
+ nested_code {|g| g.gen_assert list }.should == (<<-CODE).strip
266
+ begin
267
+ c = 0
268
+ sp = @scanner.pos
269
+ while @scanner.skip(/w+/)
270
+ c += 1
271
+ break unless @scanner.skip(/[,;]/)
272
+ end
273
+ @scanner.pos = sp
274
+ c >= 2
275
+ end
276
+ CODE
277
+ end
278
+ end
279
+
280
+ context 'when top-level' do
281
+ it 'generates top-level positive lookahead code' do
282
+ top_level_code {|g| g.gen_assert list }.should == (<<-CODE).strip
283
+ c = 0
284
+ sp = @scanner.pos
285
+ while @scanner.skip(/w+/)
286
+ c += 1
287
+ break unless @scanner.skip(/[,;]/)
288
+ end
289
+ @scanner.pos = sp
290
+ c >= 2
291
+ CODE
292
+ end
103
293
  end
104
294
  end
105
295
 
106
- context 'when top-level' do
107
- it 'generates "true"' do
108
- top_level_code {|g| g.gen_assert list }.should == 'true'
296
+ context 'given a list with an upper bound' do
297
+
298
+ let(:bounds) { [2, 4] }
299
+
300
+ context 'when nested' do
301
+ it 'generates nested positive lookahead code' do
302
+ nested_code {|g| g.gen_assert list }.should == (<<-CODE).strip
303
+ begin
304
+ c = 0
305
+ sp = @scanner.pos
306
+ while @scanner.skip(/w+/)
307
+ c += 1
308
+ break unless c < 4
309
+ break unless @scanner.skip(/[,;]/)
310
+ end
311
+ @scanner.pos = sp
312
+ c >= 2
313
+ end
314
+ CODE
315
+ end
316
+ end
317
+
318
+ context 'when top-level' do
319
+ it 'generates top-level positive lookahead code' do
320
+ top_level_code {|g| g.gen_assert list }.should == (<<-CODE).strip
321
+ c = 0
322
+ sp = @scanner.pos
323
+ while @scanner.skip(/w+/)
324
+ c += 1
325
+ break unless c < 4
326
+ break unless @scanner.skip(/[,;]/)
327
+ end
328
+ @scanner.pos = sp
329
+ c >= 2
330
+ CODE
331
+ end
109
332
  end
110
333
  end
111
334
  end
112
335
 
113
336
  describe '#gen_disallow' do
114
337
 
115
- context 'when nested' do
116
- it 'generates "false"' do
117
- nested_code {|g| g.gen_disallow list }.should == 'false'
338
+ context 'given a list with no upper bound' do
339
+
340
+ let(:bounds) { [2, nil] }
341
+
342
+ context 'when nested' do
343
+ it 'generates nested negative lookahead code' do
344
+ nested_code {|g| g.gen_disallow list }.should == (<<-CODE).strip
345
+ begin
346
+ c = 0
347
+ sp = @scanner.pos
348
+ while @scanner.skip(/w+/)
349
+ c += 1
350
+ break unless @scanner.skip(/[,;]/)
351
+ end
352
+ @scanner.pos = sp
353
+ c < 2
354
+ end
355
+ CODE
356
+ end
357
+ end
358
+
359
+ context 'when top-level' do
360
+ it 'generates top-level negative lookahead code' do
361
+ top_level_code {|g| g.gen_disallow list }.should == (<<-CODE).strip
362
+ c = 0
363
+ sp = @scanner.pos
364
+ while @scanner.skip(/w+/)
365
+ c += 1
366
+ break unless @scanner.skip(/[,;]/)
367
+ end
368
+ @scanner.pos = sp
369
+ c < 2
370
+ CODE
371
+ end
118
372
  end
119
373
  end
120
374
 
121
- context 'when top-level' do
122
- it 'generates "false"' do
123
- top_level_code {|g| g.gen_disallow list }.should == 'false'
375
+ context 'given a list with an upper bound' do
376
+
377
+ let(:bounds) { [2, 4] }
378
+
379
+ context 'when nested' do
380
+ it 'generates nested negative lookahead code' do
381
+ nested_code {|g| g.gen_disallow list }.should == (<<-CODE).strip
382
+ begin
383
+ c = 0
384
+ sp = @scanner.pos
385
+ while @scanner.skip(/w+/)
386
+ c += 1
387
+ break unless c < 4
388
+ break unless @scanner.skip(/[,;]/)
389
+ end
390
+ @scanner.pos = sp
391
+ c < 2
392
+ end
393
+ CODE
394
+ end
395
+ end
396
+
397
+ context 'when top-level' do
398
+ it 'generates top-level negative lookahead code' do
399
+ top_level_code {|g| g.gen_disallow list }.should == (<<-CODE).strip
400
+ c = 0
401
+ sp = @scanner.pos
402
+ while @scanner.skip(/w+/)
403
+ c += 1
404
+ break unless c < 4
405
+ break unless @scanner.skip(/[,;]/)
406
+ end
407
+ @scanner.pos = sp
408
+ c < 2
409
+ CODE
410
+ end
124
411
  end
125
412
  end
126
413
  end
@@ -129,164 +416,334 @@ true
129
416
 
130
417
  let(:code) { NodeCode.new('Word', 'parsed') }
131
418
 
132
- context 'when nested' do
133
- it 'generates nested list matching code with a dispatch action' do
134
- nested_code {|g| g.gen_dispatch_action list, code }.
135
- should == (<<-CODE).strip
419
+ context 'given a list with an upper bound' do
420
+
421
+ let(:bounds) { [2, 4] }
422
+
423
+ context 'when nested' do
424
+ it 'generates nested list matching code with a dispatch action' do
425
+ nested_code {|g| g.gen_dispatch_action list, code }.
426
+ should == (<<-CODE).strip
136
427
  begin
137
428
  a = []
138
- lp = nil
429
+ sp = @scanner.pos
430
+ ep = nil
139
431
  while r = @scanner.scan(/w+/)
140
- lp = @scanner.pos
432
+ ep = @scanner.pos
141
433
  a << r
434
+ break unless a.size < 4
142
435
  break unless @scanner.skip(/[,;]/)
143
436
  end
144
- @scanner.pos = lp unless lp.nil?
145
- Word.parsed(select_captures(a))
437
+ if a.size >= 2
438
+ @scanner.pos = ep unless ep.nil?
439
+ Word.parsed(select_captures(a))
440
+ else
441
+ @scanner.pos = sp
442
+ false
443
+ end
146
444
  end
147
- CODE
445
+ CODE
446
+ end
148
447
  end
149
- end
150
448
 
151
- context 'when top-level' do
152
- it 'generates top level list matching code with a dispatch action' do
153
- top_level_code {|g| g.gen_dispatch_action list, code }.
154
- should == (<<-CODE).strip
449
+ context 'when top-level' do
450
+ it 'generates top level list matching code with a dispatch action' do
451
+ top_level_code {|g| g.gen_dispatch_action list, code }.
452
+ should == (<<-CODE).strip
155
453
  a = []
156
- lp = nil
454
+ sp = @scanner.pos
455
+ ep = nil
157
456
  while r = @scanner.scan(/w+/)
158
- lp = @scanner.pos
457
+ ep = @scanner.pos
159
458
  a << r
459
+ break unless a.size < 4
160
460
  break unless @scanner.skip(/[,;]/)
161
461
  end
162
- @scanner.pos = lp unless lp.nil?
163
- Word.parsed(select_captures(a))
164
- CODE
462
+ if a.size >= 2
463
+ @scanner.pos = ep unless ep.nil?
464
+ Word.parsed(select_captures(a))
465
+ else
466
+ @scanner.pos = sp
467
+ false
468
+ end
469
+ CODE
470
+ end
165
471
  end
166
472
  end
167
- end
168
473
 
169
- describe '#gen_direct_action' do
474
+ context 'given a list with no upper bound' do
170
475
 
171
- let(:code) { ActionCode.new('|_| _.size') }
476
+ let(:bounds) { [2, nil] }
172
477
 
173
- context 'when nested' do
174
- it 'generates nested list matching code with a dispatch action' do
175
- nested_code {|g| g.gen_direct_action list, code }.
176
- should == (<<-CODE).strip
478
+ context 'when nested' do
479
+ it 'generates nested list matching code with a dispatch action' do
480
+ nested_code {|g| g.gen_dispatch_action list, code }.
481
+ should == (<<-CODE).strip
177
482
  begin
178
483
  a = []
179
- lp = nil
484
+ sp = @scanner.pos
485
+ ep = nil
180
486
  while r = @scanner.scan(/w+/)
181
- lp = @scanner.pos
487
+ ep = @scanner.pos
182
488
  a << r
183
489
  break unless @scanner.skip(/[,;]/)
184
490
  end
185
- @scanner.pos = lp unless lp.nil?
186
- (select_captures(a).size)
491
+ if a.size >= 2
492
+ @scanner.pos = ep unless ep.nil?
493
+ Word.parsed(select_captures(a))
494
+ else
495
+ @scanner.pos = sp
496
+ false
497
+ end
187
498
  end
188
- CODE
499
+ CODE
500
+ end
189
501
  end
190
- end
191
502
 
192
- context 'when top-level' do
193
- it 'generates top level list matching code with a dispatch action' do
194
- top_level_code {|g| g.gen_direct_action list, code }.
195
- should == (<<-CODE).strip
503
+ context 'when top-level' do
504
+ it 'generates top level list matching code with a dispatch action' do
505
+ top_level_code {|g| g.gen_dispatch_action list, code }.
506
+ should == (<<-CODE).strip
196
507
  a = []
197
- lp = nil
508
+ sp = @scanner.pos
509
+ ep = nil
198
510
  while r = @scanner.scan(/w+/)
199
- lp = @scanner.pos
511
+ ep = @scanner.pos
200
512
  a << r
201
513
  break unless @scanner.skip(/[,;]/)
202
514
  end
203
- @scanner.pos = lp unless lp.nil?
204
- (select_captures(a).size)
205
- CODE
515
+ if a.size >= 2
516
+ @scanner.pos = ep unless ep.nil?
517
+ Word.parsed(select_captures(a))
518
+ else
519
+ @scanner.pos = sp
520
+ false
521
+ end
522
+ CODE
523
+ end
206
524
  end
207
525
  end
208
526
  end
209
527
 
210
- describe '#gen_skip' do
528
+ describe '#gen_direct_action' do
529
+
530
+ let(:code) { ActionCode.new('|_| _.size') }
211
531
 
212
- context 'when nested' do
213
- it 'generates nested list skipping code' do
214
- nested_code {|g| g.gen_skip list }.
215
- should == (<<-CODE).strip
532
+ context 'given a list with an upper bound' do
533
+
534
+ let(:bounds) { [2, 4] }
535
+
536
+ context 'when nested' do
537
+ it 'generates nested list matching code with a dispatch action' do
538
+ nested_code {|g| g.gen_direct_action list, code }.
539
+ should == (<<-CODE).strip
216
540
  begin
217
- lp = nil
218
- while @scanner.skip(/w+/)
219
- lp = @scanner.pos
541
+ a = []
542
+ sp = @scanner.pos
543
+ ep = nil
544
+ while r = @scanner.scan(/w+/)
545
+ ep = @scanner.pos
546
+ a << r
547
+ break unless a.size < 4
220
548
  break unless @scanner.skip(/[,;]/)
221
549
  end
222
- @scanner.pos = lp unless lp.nil?
223
- true
550
+ if a.size >= 2
551
+ @scanner.pos = ep unless ep.nil?
552
+ (select_captures(a).size)
553
+ else
554
+ @scanner.pos = sp
555
+ false
556
+ end
224
557
  end
225
- CODE
558
+ CODE
559
+ end
226
560
  end
227
- end
228
561
 
229
- context 'when top-level' do
230
- it 'generates top-level list skipping code' do
231
- top_level_code {|g| g.gen_skip list }.
232
- should == (<<-CODE).strip
233
- lp = nil
234
- while @scanner.skip(/w+/)
235
- lp = @scanner.pos
562
+ context 'when top-level' do
563
+ it 'generates top level list matching code with a dispatch action' do
564
+ top_level_code {|g| g.gen_direct_action list, code }.
565
+ should == (<<-CODE).strip
566
+ a = []
567
+ sp = @scanner.pos
568
+ ep = nil
569
+ while r = @scanner.scan(/w+/)
570
+ ep = @scanner.pos
571
+ a << r
572
+ break unless a.size < 4
236
573
  break unless @scanner.skip(/[,;]/)
237
574
  end
238
- @scanner.pos = lp unless lp.nil?
239
- true
240
- CODE
575
+ if a.size >= 2
576
+ @scanner.pos = ep unless ep.nil?
577
+ (select_captures(a).size)
578
+ else
579
+ @scanner.pos = sp
580
+ false
581
+ end
582
+ CODE
583
+ end
241
584
  end
242
585
  end
243
- end
244
586
 
245
- describe '#gen_intermediate' do
246
- it 'generates nested list matching code' do
247
- nested_code {|g| g.gen_intermediate list }.
248
- should == (<<-CODE).strip
587
+ context 'given a list with no upper bound' do
588
+
589
+ let(:bounds) { [2, nil] }
590
+
591
+ context 'when nested' do
592
+ it 'generates nested list matching code with a dispatch action' do
593
+ nested_code {|g| g.gen_direct_action list, code }.
594
+ should == (<<-CODE).strip
249
595
  begin
250
596
  a = []
251
- lp = nil
597
+ sp = @scanner.pos
598
+ ep = nil
252
599
  while r = @scanner.scan(/w+/)
253
- lp = @scanner.pos
600
+ ep = @scanner.pos
254
601
  a << r
255
602
  break unless @scanner.skip(/[,;]/)
256
603
  end
257
- @scanner.pos = lp unless lp.nil?
258
- a
604
+ if a.size >= 2
605
+ @scanner.pos = ep unless ep.nil?
606
+ (select_captures(a).size)
607
+ else
608
+ @scanner.pos = sp
609
+ false
610
+ end
611
+ end
612
+ CODE
613
+ end
614
+ end
615
+
616
+ context 'when top-level' do
617
+ it 'generates top level list matching code with a dispatch action' do
618
+ top_level_code {|g| g.gen_direct_action list, code }.
619
+ should == (<<-CODE).strip
620
+ a = []
621
+ sp = @scanner.pos
622
+ ep = nil
623
+ while r = @scanner.scan(/w+/)
624
+ ep = @scanner.pos
625
+ a << r
626
+ break unless @scanner.skip(/[,;]/)
259
627
  end
260
- CODE
628
+ if a.size >= 2
629
+ @scanner.pos = ep unless ep.nil?
630
+ (select_captures(a).size)
631
+ else
632
+ @scanner.pos = sp
633
+ false
634
+ end
635
+ CODE
636
+ end
637
+ end
261
638
  end
262
639
  end
263
640
 
264
- describe '#gen_intermediate_assert' do
265
- it 'generates "true"' do
266
- nested_code {|g| g.gen_intermediate_assert list }.should == 'true'
267
- end
641
+ describe '#gen_skip' do
642
+
643
+ context 'given a list with no upper bound' do
644
+
645
+ let(:bounds) { [2, nil] }
646
+
647
+ context 'when nested' do
648
+ it 'generates nested list skipping code' do
649
+ nested_code {|g| g.gen_skip list }.should == (<<-CODE).strip
650
+ begin
651
+ c = 0
652
+ sp = @scanner.pos
653
+ ep = nil
654
+ while @scanner.skip(/w+/)
655
+ c += 1
656
+ ep = @scanner.pos
657
+ break unless @scanner.skip(/[,;]/)
658
+ end
659
+ if c >= 2
660
+ @scanner.pos = ep unless ep.nil?
661
+ true
662
+ else
663
+ @scanner.pos = sp
664
+ false
268
665
  end
666
+ end
667
+ CODE
668
+ end
669
+ end
269
670
 
270
- describe '#gen_intermediate_disallow' do
271
- it 'generates "false"' do
272
- nested_code {|g| g.gen_intermediate_disallow list }.should == 'false'
671
+ context 'when top-level' do
672
+ it 'generates top-level list skipping code' do
673
+ top_level_code {|g| g.gen_skip list }.should == (<<-CODE).strip
674
+ c = 0
675
+ sp = @scanner.pos
676
+ ep = nil
677
+ while @scanner.skip(/w+/)
678
+ c += 1
679
+ ep = @scanner.pos
680
+ break unless @scanner.skip(/[,;]/)
681
+ end
682
+ if c >= 2
683
+ @scanner.pos = ep unless ep.nil?
684
+ true
685
+ else
686
+ @scanner.pos = sp
687
+ false
688
+ end
689
+ CODE
690
+ end
691
+ end
273
692
  end
274
- end
275
693
 
276
- describe '#gen_intermediate_skip' do
277
- it 'generates nested list skipping code' do
278
- nested_code {|g| g.gen_intermediate_skip list }.
279
- should == (<<-CODE).strip
694
+ context 'given a list with an upper bound' do
695
+
696
+ let(:bounds) { [2, 4] }
697
+
698
+ context 'when nested' do
699
+ it 'generates nested list skipping code' do
700
+ nested_code {|g| g.gen_skip list }.
701
+ should == (<<-CODE).strip
280
702
  begin
281
- lp = nil
703
+ c = 0
704
+ sp = @scanner.pos
705
+ ep = nil
282
706
  while @scanner.skip(/w+/)
283
- lp = @scanner.pos
707
+ c += 1
708
+ ep = @scanner.pos
709
+ break unless c < 4
284
710
  break unless @scanner.skip(/[,;]/)
285
711
  end
286
- @scanner.pos = lp unless lp.nil?
712
+ if c >= 2
713
+ @scanner.pos = ep unless ep.nil?
714
+ true
715
+ else
716
+ @scanner.pos = sp
717
+ false
718
+ end
719
+ end
720
+ CODE
721
+ end
722
+ end
723
+
724
+ context 'when top-level' do
725
+ it 'generates top-level list skipping code' do
726
+ top_level_code {|g| g.gen_skip list }.
727
+ should == (<<-CODE).strip
728
+ c = 0
729
+ sp = @scanner.pos
730
+ ep = nil
731
+ while @scanner.skip(/w+/)
732
+ c += 1
733
+ ep = @scanner.pos
734
+ break unless c < 4
735
+ break unless @scanner.skip(/[,;]/)
736
+ end
737
+ if c >= 2
738
+ @scanner.pos = ep unless ep.nil?
287
739
  true
740
+ else
741
+ @scanner.pos = sp
742
+ false
288
743
  end
289
- CODE
744
+ CODE
745
+ end
746
+ end
290
747
  end
291
748
  end
292
749