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
@@ -10,6 +10,7 @@ require 'rattler/parsers'
10
10
  module Rattler::Parsers
11
11
  # @private
12
12
  class Predicate < Parser #:nodoc:
13
+ include Combining
13
14
 
14
15
  def self.parsed(results, *_)
15
16
  self[results.first]
@@ -19,9 +20,5 @@ module Rattler::Parsers
19
20
  false
20
21
  end
21
22
 
22
- def with_ws(ws)
23
- self.class.new(child.with_ws(ws), attrs)
24
- end
25
-
26
23
  end
27
24
  end
@@ -0,0 +1,76 @@
1
+ require 'rattler/parsers'
2
+
3
+ module Rattler::Parsers
4
+ #
5
+ # +Repeat+ decorates a parser with repeat counts to match repeatedly (up to
6
+ # the upper bound, if given) and succeed if the decorated parser succeeds at
7
+ # least as many times as specified by the lower bound.
8
+ #
9
+ # @author Jason Arhart
10
+ #
11
+ class Repeat < Parser
12
+ include Combining
13
+
14
+ def self.[](parser, lower_bound, upper_bound)
15
+ self.new(parser, :lower_bound => lower_bound, :upper_bound => upper_bound)
16
+ end
17
+
18
+ # @private
19
+ def self.parsed(results, *_) #:nodoc
20
+ parser, bounds = results
21
+ self[parser, *bounds]
22
+ end
23
+
24
+ # Parse using the wrapped parser repeatedly until it fails or the upper
25
+ # bound is reached. If the wrapped parser succeeds at least as many times
26
+ # as specified by the lower bound, return the results in an array, or
27
+ # +true+ if the wrapped parser is not <tt>capturing?</tt>. Return +false+
28
+ # if the lower bound is not reached.
29
+ #
30
+ # @param (see Parser#parse_labeled)
31
+ #
32
+ # @return [Array, Boolean] an array containing the decorated parser's parse
33
+ # results, or +true+ if the decorated parser is not <tt>capturing?</tt>,
34
+ # or +false+ if the decorated parser does not succeed up to the lower
35
+ # bound.
36
+ def parse(scanner, rules, scope = {})
37
+ a = []
38
+ start_pos = scanner.pos
39
+ while result = child.parse(scanner, rules, scope)
40
+ a << result
41
+ break if upper_bound? and a.size >= upper_bound
42
+ end
43
+ if a.size >= lower_bound
44
+ capturing? ? a : true
45
+ else
46
+ scanner.pos = start_pos
47
+ false
48
+ end
49
+ end
50
+
51
+ def zero_or_more?
52
+ lower_bound == 0 and not upper_bound?
53
+ end
54
+
55
+ def one_or_more?
56
+ lower_bound == 1 and not upper_bound?
57
+ end
58
+
59
+ def optional?
60
+ lower_bound == 0 and upper_bound == 1
61
+ end
62
+
63
+ def lower_bound?
64
+ lower_bound > 0
65
+ end
66
+
67
+ def upper_bound?
68
+ not upper_bound.nil?
69
+ end
70
+
71
+ def variable_capture_count?
72
+ true
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,19 @@
1
+ require 'rattler/parsers'
2
+
3
+ module Rattler::Parsers
4
+ #
5
+ # +SemanticAssert+ decorates a parser to peform a symantic action on success
6
+ # by evaluating ruby code and succeed if the result is a true value.
7
+ #
8
+ # @author Jason Arhart
9
+ #
10
+ class SemanticAssert < DirectAction
11
+
12
+ protected
13
+
14
+ def create_bindable_code
15
+ AssertCode.new(code)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'rattler/parsers'
2
+
3
+ module Rattler::Parsers
4
+ #
5
+ # +SemanticDisallow+ decorates a parser to peform a symantic action on success
6
+ # by evaluating ruby code and succeed if the result is a false value.
7
+ #
8
+ # @author Jason Arhart
9
+ #
10
+ class SemanticDisallow < DirectAction
11
+
12
+ protected
13
+
14
+ def create_bindable_code
15
+ DisallowCode.new(code)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'rattler/parsers'
2
+
3
+ module Rattler::Parsers
4
+ #
5
+ # +SideEffect+ decorates a parser to peform a symantic action on success by
6
+ # evaluating ruby code for effect and discarding the result.
7
+ #
8
+ # @author Jason Arhart
9
+ #
10
+ class SideEffect < DirectAction
11
+
12
+ protected
13
+
14
+ def create_bindable_code
15
+ EffectCode.new(code)
16
+ end
17
+
18
+ end
19
+ end
@@ -13,6 +13,7 @@ module Rattler::Parsers
13
13
  # the results
14
14
  #
15
15
  class Skip < Parser
16
+ include Combining
16
17
 
17
18
  # @private
18
19
  def self.parsed(results, *_) #:nodoc:
@@ -36,15 +37,6 @@ module Rattler::Parsers
36
37
  false
37
38
  end
38
39
 
39
- # Return a new parser that uses +ws+ to skip whitespace before matching
40
- # tokens.
41
- #
42
- # @param (see Parser#with_ws)
43
- # @return (see Parser#with_ws)
44
- def with_ws(ws)
45
- child.with_ws(ws).skip
46
- end
47
-
48
40
  # @return (see Parser#skip)
49
41
  def skip
50
42
  self
@@ -14,6 +14,7 @@ module Rattler::Parsers
14
14
  # @author Jason Arhart
15
15
  #
16
16
  class Token < Parser
17
+ include Atomic
17
18
 
18
19
  # If the decorated parser matches return the entire matched string,
19
20
  # otherwise return a false value.
@@ -26,11 +27,5 @@ module Rattler::Parsers
26
27
  child.parse(scanner, rules, scope) && scanner.string[p...(scanner.pos)]
27
28
  end
28
29
 
29
- # @param (see Parser#with_ws)
30
- # @return (see Parser#with_ws)
31
- def with_ws(ws)
32
- ws.skip & self
33
- end
34
-
35
30
  end
36
31
  end
@@ -50,7 +50,7 @@ module Rattler::Util::GraphViz
50
50
  # @return the label option for a node representing +o+.
51
51
  def node_label(o)
52
52
  if o.is_a? ::Rattler::Util::Node
53
- record_label(o, o.attrs)
53
+ record_label(o, parse_node_fields(o.attrs))
54
54
  elsif record_like? o
55
55
  record_label(o, o)
56
56
  elsif array_like? o
@@ -81,8 +81,7 @@ module Rattler::Util::GraphViz
81
81
  o.none? {|k, v| array_like? v or record_like? v }
82
82
  end
83
83
 
84
- def record_label(o, h)
85
- fields = h.reject {|k,v| k == :name }
84
+ def record_label(o, fields)
86
85
  '{' + ([type_label(o)] + hash_content_labels(fields)).join('|') + '}'
87
86
  end
88
87
 
@@ -90,6 +89,10 @@ module Rattler::Util::GraphViz
90
89
  h.map {|pair| '{' + pair.map {|_| _.inspect }.join('|') + '}' }
91
90
  end
92
91
 
92
+ def parse_node_fields(attrs)
93
+ attrs.reject {|k,| k == :name || k == :labeled }
94
+ end
95
+
93
96
  # @private
94
97
  class Mapping #:nodoc:
95
98
  def initialize(key, value)
@@ -0,0 +1,187 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ shared_examples_for 'a compiled parser with an assert' do
4
+ include CompilerSpecHelper
5
+
6
+ subject { compiled_parser }
7
+
8
+ let(:reference_parser) { combinator_parser grammar }
9
+
10
+ context 'with a nested match rule' do
11
+ let(:grammar) { define_grammar do
12
+ rule(:word) { assert /\w+/ }
13
+ end }
14
+ it { should parse('abc123 ').succeeding.like reference_parser }
15
+ it { should parse(' ').failing.like reference_parser }
16
+ end
17
+
18
+ context 'with a nested eof rule' do
19
+ let(:grammar) { define_grammar do
20
+ rule(:foo) { assert(eof) }
21
+ end }
22
+ it { should parse('').succeeding.like reference_parser }
23
+ it { should parse('foo').from(3).succeeding.like reference_parser }
24
+ it { should parse('foo').failing.like reference_parser }
25
+ end
26
+
27
+ context 'with a nested "E" symbol rule' do
28
+ let(:grammar) { define_grammar do
29
+ rule(:foo) { assert(e) }
30
+ end }
31
+ it { should parse('').succeeding.like reference_parser }
32
+ it { should parse('foo').succeeding.like reference_parser }
33
+ end
34
+
35
+ context 'with a nested choice rule' do
36
+ let(:grammar) { define_grammar do
37
+ rule(:word) { assert(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/)) }
38
+ end }
39
+ it { should parse('abc123 ').succeeding.like reference_parser }
40
+ it { should parse(' ').failing.like reference_parser }
41
+ end
42
+
43
+ context 'with a nested sequence rule' do
44
+ let(:grammar) { define_grammar do
45
+ rule(:word) { assert(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)) }
46
+ end }
47
+ it { should parse('abc123 ').succeeding.like reference_parser }
48
+ it { should parse(' ').failing.like reference_parser }
49
+ end
50
+
51
+ context 'with a nested optional rule' do
52
+ let(:grammar) { define_grammar do
53
+ rule(:word) { assert(optional(/\w+/)) }
54
+ end }
55
+ it { should parse('abc123 ').succeeding.like reference_parser }
56
+ it { should parse(' ').succeeding.like reference_parser }
57
+ end
58
+
59
+ context 'with a nested zero-or-more rule' do
60
+ let(:grammar) { define_grammar do
61
+ rule(:word) { assert(zero_or_more(/\w/)) }
62
+ end }
63
+ it { should parse('abc123 ').succeeding.like reference_parser }
64
+ it { should parse(' ').succeeding.like reference_parser }
65
+ end
66
+
67
+ context 'with a nested one-or-more rule' do
68
+ let(:grammar) { define_grammar do
69
+ rule(:word) { assert(one_or_more(/\w/)) }
70
+ end }
71
+ it { should parse('abc123 ').succeeding.like reference_parser }
72
+ it { should parse(' ').failing.like reference_parser }
73
+ end
74
+
75
+ context 'with a nested repeat rule' do
76
+ let(:grammar) { define_grammar do
77
+ rule(:word) { assert(repeat(/\w/, 2, nil)) }
78
+ end }
79
+ it { should parse('abc123 ').succeeding.like reference_parser }
80
+ it { should parse('a ').failing.like reference_parser }
81
+
82
+ context 'with zero-or-more bounds' do
83
+ let(:grammar) { define_grammar do
84
+ rule(:word) { assert(repeat(/\w/, 0, nil)) }
85
+ end }
86
+ it { should parse('abc123 ').succeeding.like reference_parser }
87
+ it { should parse(' ').succeeding.like reference_parser }
88
+
89
+ context 'with an upper bound' do
90
+ let(:grammar) { define_grammar do
91
+ rule(:word) { assert(repeat(/\w/, 0, 2)) }
92
+ end }
93
+ it { should parse('abc123 ').succeeding.like reference_parser }
94
+ it { should parse(' ').succeeding.like reference_parser }
95
+ end
96
+ end
97
+
98
+ context 'with one-or-more bounds' do
99
+ let(:grammar) { define_grammar do
100
+ rule(:word) { assert(repeat(/\w/, 1, nil)) }
101
+ end }
102
+ it { should parse('abc123 ').succeeding.like reference_parser }
103
+ it { should parse(' ').failing.like reference_parser }
104
+
105
+ context 'with an upper bound' do
106
+ let(:grammar) { define_grammar do
107
+ rule(:word) { assert(repeat(/\w/, 1, 2)) }
108
+ end }
109
+ it { should parse('abc123 ').succeeding.like reference_parser }
110
+ it { should parse(' ').failing.like reference_parser }
111
+ end
112
+ end
113
+ end
114
+
115
+ context 'with a nested list rule' do
116
+ let(:grammar) { define_grammar do
117
+ rule :foo do
118
+ assert list(/\w+/, /[,;]/, 2, nil)
119
+ end
120
+ end }
121
+ it { should parse('foo ').failing.like reference_parser }
122
+ it { should parse('foo,bar;baz ').succeeding.like reference_parser }
123
+
124
+ context 'with an upper bound' do
125
+ let(:grammar) { define_grammar do
126
+ rule :foo do
127
+ assert list(/\w+/, /[,;]/, 2, 4)
128
+ end
129
+ end }
130
+ it { should parse('foo ').failing.like reference_parser }
131
+ it { should parse('foo,bar;baz ').succeeding.like reference_parser }
132
+ end
133
+
134
+ context 'with a non-capturing parser' do
135
+ let(:grammar) { define_grammar do
136
+ rule :foo do
137
+ assert list(skip(/\w+/), /[,;]/, 2, nil)
138
+ end
139
+ end }
140
+ it { should parse('foo ').failing.like reference_parser }
141
+ it { should parse('foo,bar;baz ').succeeding.like reference_parser }
142
+
143
+ context 'with an upper bound' do
144
+ let(:grammar) { define_grammar do
145
+ rule :foo do
146
+ assert list(skip(/\w+/), /[,;]/, 2, 4)
147
+ end
148
+ end }
149
+ it { should parse('foo ').failing.like reference_parser }
150
+ it { should parse('foo,bar;baz ').succeeding.like reference_parser }
151
+ end
152
+ end
153
+ end
154
+
155
+ context 'with a nested apply rule' do
156
+ let(:grammar) { define_grammar do
157
+ rule(:foo) { match :word }
158
+ rule(:word) { assert /\w+/ }
159
+ end }
160
+ it { should parse('abc123 ').succeeding.like reference_parser }
161
+ it { should parse(' ').failing.like reference_parser }
162
+ end
163
+
164
+ context 'with a nested dispatch-action rule' do
165
+ let(:grammar) { define_grammar do
166
+ rule(:word) { assert(dispatch_action(/\w+/)) }
167
+ end }
168
+ it { should parse('abc123 ').succeeding.like reference_parser }
169
+ it { should parse(' ').failing.like reference_parser }
170
+ end
171
+
172
+ context 'with a nested token rule' do
173
+ let(:grammar) { define_grammar do
174
+ rule(:word) { assert(token(match(/\w+/))) }
175
+ end }
176
+ it { should parse('abc123 ').succeeding.like reference_parser }
177
+ it { should parse(' ').failing.like reference_parser }
178
+ end
179
+
180
+ context 'with a nested skip rule' do
181
+ let(:grammar) { define_grammar do
182
+ rule(:word) { assert(skip(/\w+/)) }
183
+ end }
184
+ it { should parse('abc123 ').succeeding.like reference_parser }
185
+ it { should parse(' ').failing.like reference_parser }
186
+ end
187
+ end
@@ -0,0 +1,227 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ shared_examples_for 'a compiled parser with a direct action' do
4
+ include CompilerSpecHelper
5
+
6
+ subject { compiled_parser }
7
+
8
+ let(:reference_parser) { combinator_parser grammar }
9
+
10
+ context 'with a nested match rule' do
11
+ let(:grammar) { define_grammar do
12
+ rule(:num) { direct_action(/\d+/, '|_| _.to_i') }
13
+ end }
14
+ it { should parse('451a').succeeding.like reference_parser }
15
+ it { should parse(' ').failing.like reference_parser }
16
+
17
+ context 'with a label' do
18
+ let(:grammar) { define_grammar do
19
+ rule(:digits) { direct_action(label(:num, /\d+/), 'num.to_i') }
20
+ end }
21
+ it { should parse('451a').succeeding.like reference_parser }
22
+ it { should parse(' ').failing.like reference_parser }
23
+ end
24
+ end
25
+
26
+ context 'with a nested apply rule' do
27
+ let(:grammar) { define_grammar do
28
+ rule(:foo) { direct_action :digit, '|_| _.to_i' }
29
+ rule(:digit) { match(/\d/) }
30
+ end }
31
+ it { should parse('451 ').twice.succeeding.like reference_parser }
32
+ it { should parse('hi').failing.like reference_parser }
33
+
34
+ context 'with a label' do
35
+ let(:grammar) { define_grammar do
36
+ rule(:num) { direct_action(label(:num, :digits), 'num.to_i') }
37
+ rule(:digits) { match(/\d+/) }
38
+ end }
39
+ it { should parse('451a').succeeding.like reference_parser }
40
+ it { should parse(' ').failing.like reference_parser }
41
+ end
42
+ end
43
+
44
+ context 'with a nested assert rule' do
45
+ let(:grammar) { define_grammar do
46
+ rule(:foo) { direct_action(assert(/\d/), ':digit') }
47
+ end }
48
+ it { should parse('451a').succeeding.like reference_parser }
49
+ it { should parse(' ').failing.like reference_parser }
50
+ end
51
+
52
+ context 'with a nested disallow rule' do
53
+ let(:grammar) { define_grammar do
54
+ rule(:foo) { direct_action(disallow(/\d/), ':nondigit') }
55
+ end }
56
+ it { should parse(' ').succeeding.like reference_parser }
57
+ it { should parse('451a').failing.like reference_parser }
58
+ end
59
+
60
+ context 'with a nested EOF rule' do
61
+ let(:grammar) { define_grammar do
62
+ rule(:foo) { direct_action(eof, ':eof') }
63
+ end }
64
+ it { should parse('foo').failing.like reference_parser }
65
+ it { should parse('').succeeding.like reference_parser }
66
+ it { should parse('foo').from(3).succeeding.like reference_parser }
67
+ end
68
+
69
+ context 'with a nested "E" symbol rule' do
70
+ let(:grammar) { define_grammar do
71
+ rule(:foo) { direct_action(e, ':e') }
72
+ end }
73
+ it { should parse('').succeeding.like reference_parser }
74
+ it { should parse('foo').succeeding.like reference_parser }
75
+ end
76
+
77
+ context 'with a nested choice rule' do
78
+ let(:grammar) { define_grammar do
79
+ rule :foo do
80
+ direct_action(
81
+ match(/[[:alpha:]]+/) | match(/[[:digit:]]+/),
82
+ '|_| _.size'
83
+ )
84
+ end
85
+ end }
86
+
87
+ it { should parse('abc123').succeeding.like reference_parser }
88
+ it { should parse('451a').succeeding.like reference_parser }
89
+ it { should parse(' ').failing.like reference_parser }
90
+ end
91
+
92
+ context 'with a nested sequence rule' do
93
+ let(:grammar) { define_grammar do
94
+ rule :assignment do
95
+ direct_action(
96
+ match(/[[:alpha:]]+/) & match('=') & match(/[[:digit:]]+/),
97
+ '|l,_,r| "#{r} -> #{l}"'
98
+ )
99
+ end
100
+ end }
101
+
102
+ it { should parse('val=42 ').succeeding.like reference_parser }
103
+ it { should parse('val=x').failing.like reference_parser }
104
+
105
+ context 'with labels' do
106
+ let(:grammar) { define_grammar do
107
+ rule :assignment do
108
+ direct_action(
109
+ label(:name, /[[:alpha:]]+/) & match('=') & label(:value, /[[:digit:]]+/),
110
+ '"#{value} -> #{name}"'
111
+ )
112
+ end
113
+ end }
114
+ it { should parse('val=42 ').succeeding.like reference_parser }
115
+ end
116
+ end
117
+
118
+ context 'with a nested optional rule' do
119
+ let(:grammar) { define_grammar do
120
+ rule :foo do
121
+ direct_action(optional(/\w+/), '|_| _.size')
122
+ end
123
+ end }
124
+ it { should parse('foo ').succeeding.like reference_parser }
125
+ it { should parse(' ').succeeding.like reference_parser }
126
+ end
127
+
128
+ context 'with a nested zero-or-more rule' do
129
+ let(:grammar) { define_grammar do
130
+ rule :foo do
131
+ direct_action(zero_or_more(/\w/), '|_| _.size')
132
+ end
133
+ end }
134
+ it { should parse('foo ').succeeding.like reference_parser }
135
+ it { should parse(' ').succeeding.like reference_parser }
136
+ end
137
+
138
+ context 'with a nested one-or-more rule' do
139
+ let(:grammar) { define_grammar do
140
+ rule :foo do
141
+ direct_action(one_or_more(/\w/), '|_| _.size')
142
+ end
143
+ end }
144
+ it { should parse('foo ').succeeding.like reference_parser }
145
+ it { should parse(' ').failing.like reference_parser }
146
+ end
147
+
148
+ context 'with a nested repeat rule' do
149
+ let(:grammar) { define_grammar do
150
+ rule :foo do
151
+ direct_action(repeat(/\w/, 2, 4), '|_| _.size')
152
+ end
153
+ end }
154
+ it { should parse('foo ').succeeding.like reference_parser }
155
+ it { should parse('abcde ').succeeding.like reference_parser }
156
+ it { should parse('a ').failing.like reference_parser }
157
+
158
+ context 'with optional bounds' do
159
+ let(:grammar) { define_grammar do
160
+ rule :foo do
161
+ direct_action(repeat(/\w+/, 0, 1), '|_| _.size')
162
+ end
163
+ end }
164
+ it { should parse('foo ').succeeding.like reference_parser }
165
+ it { should parse(' ').succeeding.like reference_parser }
166
+ end
167
+
168
+ context 'with zero-or-more bounds' do
169
+ let(:grammar) { define_grammar do
170
+ rule :foo do
171
+ direct_action(repeat(/\w/, 0, nil), '|_| _.size')
172
+ end
173
+ end }
174
+ it { should parse('foo ').succeeding.like reference_parser }
175
+ it { should parse(' ').succeeding.like reference_parser }
176
+ end
177
+
178
+ context 'with one-or-more bounds' do
179
+ let(:grammar) { define_grammar do
180
+ rule :foo do
181
+ direct_action(repeat(/\w/, 1, nil), '|_| _.size')
182
+ end
183
+ end }
184
+ it { should parse('foo ').succeeding.like reference_parser }
185
+ it { should parse(' ').failing.like reference_parser }
186
+ end
187
+ end
188
+
189
+ context 'with a nested list rule' do
190
+ let(:grammar) { define_grammar do
191
+ rule :foo do
192
+ direct_action(list(/\w+/, /,/, 1, nil), '|_| _.reduce(:+)')
193
+ end
194
+ end }
195
+ it { should parse('a,bc,d ').succeeding.like reference_parser }
196
+ it { should parse(' ').failing.like reference_parser }
197
+ end
198
+
199
+ context 'with a nested apply rule' do
200
+ let(:grammar) { define_grammar do
201
+ rule(:foo) { direct_action :digit, '|_| _.to_i' }
202
+ rule(:digit) { match /\d/ }
203
+ end }
204
+ it { should parse('451a').succeeding.twice.like reference_parser }
205
+ it { should parse(' ').failing.like reference_parser }
206
+ end
207
+
208
+ context 'with a nested token rule' do
209
+ let(:grammar) { define_grammar do
210
+ rule :foo do
211
+ direct_action(token(/\w+/), '|_| _.size')
212
+ end
213
+ end }
214
+ it { should parse('abc123').succeeding.like reference_parser }
215
+ it { should parse(' ').failing.like reference_parser }
216
+ end
217
+
218
+ context 'with a nested skip rule' do
219
+ let(:grammar) { define_grammar do
220
+ rule :foo do
221
+ direct_action(skip(/\w+/), '42' )
222
+ end
223
+ end }
224
+ it { should parse('abc123').succeeding.like reference_parser }
225
+ it { should parse(' ').failing.like reference_parser }
226
+ end
227
+ end