rattler 0.5.0 → 0.6.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 (329) hide show
  1. data/README.rdoc +3 -175
  2. data/features/README.markdown +27 -0
  3. data/features/Tutorial.md +224 -0
  4. data/features/command_line/output_option.feature +2 -1
  5. data/features/command_line/{parser_generator.feature → rtlr.feature} +43 -15
  6. data/features/error_reporting/automatic_error_messages.feature +40 -0
  7. data/features/error_reporting/custom_error_messages.feature +28 -0
  8. data/features/examples/json_parser.markdown +88 -0
  9. data/features/{grammar → extended_matching_syntax}/back_reference.feature +5 -3
  10. data/features/{grammar → extended_matching_syntax}/e_symbol.feature +2 -2
  11. data/features/{grammar → extended_matching_syntax}/eof.feature +4 -3
  12. data/features/{grammar → extended_matching_syntax}/fail.feature +8 -6
  13. data/features/extended_matching_syntax/fragments.feature +29 -0
  14. data/features/extended_matching_syntax/include.feature +42 -0
  15. data/features/{grammar → extended_matching_syntax}/list_matching.feature +7 -6
  16. data/features/extended_matching_syntax/posix_class.feature +127 -0
  17. data/features/{grammar → extended_matching_syntax}/repeat.feature +29 -3
  18. data/features/{grammar → extended_matching_syntax}/skip_operator.feature +2 -1
  19. data/features/extended_matching_syntax/super.feature +24 -0
  20. data/features/{grammar → extended_matching_syntax}/token.feature +6 -5
  21. data/features/{grammar → extended_matching_syntax}/whitespace.feature +7 -6
  22. data/features/{grammar → extended_matching_syntax}/word_literal.feature +10 -6
  23. data/features/grammar_heading/explicit_start_rule.feature +20 -0
  24. data/features/grammar_heading/grammar_declaration.feature +60 -0
  25. data/features/grammar_heading/include.feature +19 -0
  26. data/features/grammar_heading/require.feature +27 -0
  27. data/features/{grammar → peg_syntax}/any_character.feature +1 -1
  28. data/features/peg_syntax/character_class.feature +25 -0
  29. data/features/{grammar → peg_syntax}/comments.feature +1 -1
  30. data/features/{grammar → peg_syntax}/literal.feature +5 -3
  31. data/features/{grammar → peg_syntax}/negative_lookahead.feature +5 -3
  32. data/features/peg_syntax/nonterminal.feature +46 -0
  33. data/features/peg_syntax/one_or_more.feature +59 -0
  34. data/features/{grammar → peg_syntax}/optional.feature +2 -2
  35. data/features/peg_syntax/ordered_choice.feature +24 -0
  36. data/features/{grammar → peg_syntax}/positive_lookahead.feature +6 -4
  37. data/features/peg_syntax/sequence.feature +23 -0
  38. data/features/{grammar → peg_syntax}/start_rule.feature +1 -1
  39. data/features/peg_syntax/zero_or_more.feature +59 -0
  40. data/features/{grammar → semantics}/labels.feature +0 -0
  41. data/features/{grammar → semantics}/negative_semantic_predicate.feature +30 -9
  42. data/features/{grammar → semantics}/node_action.feature +0 -0
  43. data/features/{grammar → semantics}/positive_semantic_predicate.feature +29 -8
  44. data/features/{grammar/symantic_action.feature → semantics/semantic_action.feature} +2 -2
  45. data/features/semantics/semantic_result.feature +86 -0
  46. data/features/{grammar → semantics}/side_effect.feature +33 -21
  47. data/features/step_definitions/cli_steps.rb +1 -1
  48. data/features/step_definitions/grammar_steps.rb +19 -5
  49. data/features/support/env.rb +5 -0
  50. data/lib/rattler.rb +21 -44
  51. data/lib/rattler/compiler.rb +69 -0
  52. data/lib/rattler/{grammar → compiler}/grammar_parser.rb +58 -24
  53. data/lib/rattler/compiler/metagrammar.rb +1570 -0
  54. data/lib/rattler/compiler/optimizer.rb +77 -0
  55. data/lib/rattler/{back_end → compiler}/optimizer/composite_reducing.rb +2 -2
  56. data/lib/rattler/{back_end → compiler}/optimizer/flatten_choice.rb +3 -12
  57. data/lib/rattler/{back_end → compiler}/optimizer/flatten_sequence.rb +4 -16
  58. data/lib/rattler/{back_end → compiler}/optimizer/flattening.rb +2 -2
  59. data/lib/rattler/compiler/optimizer/inline_regular_rules.rb +24 -0
  60. data/lib/rattler/{back_end → compiler}/optimizer/join_match_capturing_sequence.rb +16 -14
  61. data/lib/rattler/{back_end → compiler}/optimizer/join_match_choice.rb +4 -13
  62. data/lib/rattler/{back_end → compiler}/optimizer/join_match_matching_sequence.rb +4 -13
  63. data/lib/rattler/compiler/optimizer/join_match_sequence.rb +7 -0
  64. data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_bare_match.rb +3 -12
  65. data/lib/rattler/compiler/optimizer/join_predicate_match.rb +7 -0
  66. data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_nested_match.rb +4 -13
  67. data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_or_bare_match.rb +3 -12
  68. data/lib/rattler/compiler/optimizer/join_predicate_or_match.rb +7 -0
  69. data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_or_nested_match.rb +4 -13
  70. data/lib/rattler/{back_end → compiler}/optimizer/match_joining.rb +2 -2
  71. data/lib/rattler/{back_end → compiler}/optimizer/optimization.rb +12 -34
  72. data/lib/rattler/compiler/optimizer/optimization_context.rb +83 -0
  73. data/lib/rattler/{back_end → compiler}/optimizer/optimization_sequence.rb +3 -11
  74. data/lib/rattler/compiler/optimizer/optimizations.rb +27 -0
  75. data/lib/rattler/{back_end → compiler}/optimizer/optimize_children.rb +6 -14
  76. data/lib/rattler/{back_end → compiler}/optimizer/reduce_repeat_match.rb +4 -13
  77. data/lib/rattler/compiler/optimizer/remove_meaningless_wrapper.rb +22 -0
  78. data/lib/rattler/{back_end → compiler}/optimizer/simplify_redundant_repeat.rb +4 -13
  79. data/lib/rattler/{back_end → compiler}/optimizer/simplify_token_match.rb +4 -13
  80. data/lib/rattler/compiler/parser_generator.rb +108 -0
  81. data/lib/rattler/{back_end → compiler}/parser_generator/apply_generator.rb +7 -21
  82. data/lib/rattler/{back_end → compiler}/parser_generator/assert_generator.rb +11 -19
  83. data/lib/rattler/compiler/parser_generator/attributed_sequence_generator.rb +37 -0
  84. data/lib/rattler/{back_end → compiler}/parser_generator/back_reference_generator.rb +10 -10
  85. data/lib/rattler/{back_end → compiler}/parser_generator/choice_generator.rb +10 -22
  86. data/lib/rattler/{back_end → compiler}/parser_generator/delegating_generator.rb +2 -2
  87. data/lib/rattler/{back_end → compiler}/parser_generator/disallow_generator.rb +11 -19
  88. data/lib/rattler/{back_end → compiler}/parser_generator/e_symbol_generator.rb +2 -10
  89. data/lib/rattler/{back_end → compiler}/parser_generator/eof_generator.rb +2 -10
  90. data/lib/rattler/{back_end → compiler}/parser_generator/expr_generator.rb +9 -35
  91. data/lib/rattler/{back_end → compiler}/parser_generator/fail_generator.rb +7 -3
  92. data/lib/rattler/{back_end → compiler}/parser_generator/gen_method_names.rb +3 -5
  93. data/lib/rattler/{back_end → compiler}/parser_generator/general_list_generator.rb +6 -18
  94. data/lib/rattler/{back_end → compiler}/parser_generator/general_repeat_generator.rb +16 -22
  95. data/lib/rattler/{back_end/parser_generator/rule_set_generator.rb → compiler/parser_generator/grammar_generator.rb} +24 -33
  96. data/lib/rattler/compiler/parser_generator/group_match.rb +33 -0
  97. data/lib/rattler/{back_end → compiler}/parser_generator/group_match_generator.rb +4 -17
  98. data/lib/rattler/compiler/parser_generator/label_generator.rb +37 -0
  99. data/lib/rattler/{back_end → compiler}/parser_generator/list0_generating.rb +5 -5
  100. data/lib/rattler/{back_end → compiler}/parser_generator/list1_generating.rb +3 -3
  101. data/lib/rattler/{back_end → compiler}/parser_generator/list_generator.rb +2 -2
  102. data/lib/rattler/{back_end → compiler}/parser_generator/match_generator.rb +10 -10
  103. data/lib/rattler/{back_end → compiler}/parser_generator/nested.rb +2 -2
  104. data/lib/rattler/compiler/parser_generator/node_action_generator.rb +49 -0
  105. data/lib/rattler/{back_end → compiler}/parser_generator/one_or_more_generating.rb +3 -3
  106. data/lib/rattler/{back_end → compiler}/parser_generator/optional_generating.rb +6 -22
  107. data/lib/rattler/compiler/parser_generator/predicate_propogating.rb +24 -0
  108. data/lib/rattler/{back_end → compiler}/parser_generator/repeat_generator.rb +2 -2
  109. data/lib/rattler/compiler/parser_generator/rule_generator.rb +66 -0
  110. data/lib/rattler/compiler/parser_generator/rule_set_generator.rb +33 -0
  111. data/lib/rattler/compiler/parser_generator/semantic_action_generator.rb +58 -0
  112. data/lib/rattler/compiler/parser_generator/sequence_generating.rb +138 -0
  113. data/lib/rattler/compiler/parser_generator/sequence_generator.rb +57 -0
  114. data/lib/rattler/{back_end → compiler}/parser_generator/skip_generator.rb +4 -18
  115. data/lib/rattler/compiler/parser_generator/skip_propogating.rb +16 -0
  116. data/lib/rattler/{back_end → compiler}/parser_generator/sub_generating.rb +19 -11
  117. data/lib/rattler/compiler/parser_generator/super_generator.rb +54 -0
  118. data/lib/rattler/{back_end → compiler}/parser_generator/token_generator.rb +3 -3
  119. data/lib/rattler/compiler/parser_generator/token_propogating.rb +10 -0
  120. data/lib/rattler/{back_end → compiler}/parser_generator/top_level.rb +2 -2
  121. data/lib/rattler/{back_end → compiler}/parser_generator/zero_or_more_generating.rb +5 -5
  122. data/lib/rattler/compiler/rattler.rtlr +201 -0
  123. data/lib/rattler/{back_end → compiler}/ruby_generator.rb +16 -25
  124. data/lib/rattler/parsers.rb +12 -33
  125. data/lib/rattler/parsers/action_code.rb +25 -16
  126. data/lib/rattler/{grammar → parsers}/analysis.rb +32 -11
  127. data/lib/rattler/parsers/apply.rb +10 -19
  128. data/lib/rattler/parsers/assert.rb +4 -14
  129. data/lib/rattler/parsers/atomic.rb +3 -10
  130. data/lib/rattler/parsers/attributed_sequence.rb +50 -0
  131. data/lib/rattler/parsers/back_reference.rb +19 -14
  132. data/lib/rattler/parsers/choice.rb +11 -12
  133. data/lib/rattler/parsers/combinator_parser.rb +15 -7
  134. data/lib/rattler/parsers/combining.rb +15 -9
  135. data/lib/rattler/parsers/disallow.rb +5 -12
  136. data/lib/rattler/parsers/e_symbol.rb +5 -14
  137. data/lib/rattler/parsers/eof.rb +10 -15
  138. data/lib/rattler/parsers/fail.rb +16 -26
  139. data/lib/rattler/{grammar → parsers}/grammar.rb +15 -20
  140. data/lib/rattler/parsers/label.rb +10 -16
  141. data/lib/rattler/parsers/list_parser.rb +14 -14
  142. data/lib/rattler/parsers/match.rb +5 -17
  143. data/lib/rattler/parsers/node_action.rb +72 -0
  144. data/lib/rattler/parsers/node_code.rb +47 -30
  145. data/lib/rattler/parsers/parser.rb +63 -32
  146. data/lib/rattler/parsers/parser_scope.rb +88 -0
  147. data/lib/rattler/parsers/predicate.rb +12 -10
  148. data/lib/rattler/parsers/repeat.rb +15 -8
  149. data/lib/rattler/parsers/rule.rb +8 -23
  150. data/lib/rattler/parsers/rule_set.rb +67 -12
  151. data/lib/rattler/parsers/semantic.rb +36 -0
  152. data/lib/rattler/parsers/semantic_action.rb +39 -0
  153. data/lib/rattler/parsers/sequence.rb +25 -40
  154. data/lib/rattler/parsers/sequencing.rb +40 -0
  155. data/lib/rattler/parsers/skip.rb +11 -12
  156. data/lib/rattler/parsers/super.rb +33 -0
  157. data/lib/rattler/parsers/token.rb +3 -13
  158. data/lib/rattler/rake_task.rb +50 -0
  159. data/lib/rattler/runner.rb +19 -22
  160. data/lib/rattler/runtime.rb +0 -10
  161. data/lib/rattler/runtime/extended_packrat_parser.rb +40 -45
  162. data/lib/rattler/runtime/packrat_parser.rb +17 -31
  163. data/lib/rattler/runtime/parse_failure.rb +16 -26
  164. data/lib/rattler/runtime/parse_node.rb +8 -18
  165. data/lib/rattler/runtime/parser.rb +6 -18
  166. data/lib/rattler/runtime/parser_helper.rb +3 -10
  167. data/lib/rattler/runtime/recursive_descent_parser.rb +26 -23
  168. data/lib/rattler/runtime/syntax_error.rb +0 -10
  169. data/lib/rattler/util.rb +2 -6
  170. data/lib/rattler/util/grammar_cli.rb +19 -0
  171. data/lib/rattler/util/graphviz.rb +6 -17
  172. data/lib/rattler/util/graphviz/digraph_builder.rb +10 -17
  173. data/lib/rattler/util/graphviz/node_builder.rb +45 -31
  174. data/lib/rattler/util/line_counter.rb +11 -20
  175. data/lib/rattler/util/node.rb +52 -30
  176. data/lib/rattler/util/parser_cli.rb +84 -0
  177. data/lib/rattler/util/parser_spec_helper.rb +8 -12
  178. data/spec/rattler/compiler/assert_compiler_examples.rb +284 -0
  179. data/spec/rattler/compiler/attributed_sequence_compiler_examples.rb +154 -0
  180. data/spec/rattler/compiler/disallow_compiler_examples.rb +293 -0
  181. data/spec/rattler/compiler/grammar_parser_spec.rb +700 -0
  182. data/spec/rattler/{back_end → compiler}/optimizer/flatten_choice_spec.rb +1 -1
  183. data/spec/rattler/{back_end → compiler}/optimizer/flatten_sequence_spec.rb +1 -1
  184. data/spec/rattler/compiler/optimizer/inline_regular_rules_spec.rb +50 -0
  185. data/spec/rattler/{back_end → compiler}/optimizer/join_match_capturing_sequence_spec.rb +106 -22
  186. data/spec/rattler/{back_end → compiler}/optimizer/join_match_choice_spec.rb +1 -1
  187. data/spec/rattler/{back_end → compiler}/optimizer/join_match_matching_sequence_spec.rb +1 -1
  188. data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_bare_match_spec.rb +1 -1
  189. data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_nested_match_spec.rb +1 -1
  190. data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_or_bare_match_spec.rb +1 -1
  191. data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_or_nested_match_spec.rb +1 -1
  192. data/spec/rattler/{back_end → compiler}/optimizer/reduce_repeat_match_spec.rb +1 -1
  193. data/spec/rattler/compiler/optimizer/remove_meaningless_wrapper_spec.rb +82 -0
  194. data/spec/rattler/{back_end → compiler}/optimizer/simplify_redundant_repeat_spec.rb +1 -1
  195. data/spec/rattler/{back_end → compiler}/optimizer/simplify_token_match_spec.rb +1 -1
  196. data/spec/rattler/{back_end → compiler}/optimizer_spec.rb +1 -1
  197. data/spec/rattler/{back_end → compiler}/parser_generator/apply_generator_spec.rb +1 -39
  198. data/spec/rattler/{back_end → compiler}/parser_generator/assert_generator_spec.rb +1 -55
  199. data/spec/rattler/compiler/parser_generator/attributed_sequence_generator_spec.rb +699 -0
  200. data/spec/rattler/{back_end → compiler}/parser_generator/back_reference_generator_spec.rb +3 -56
  201. data/spec/rattler/{back_end → compiler}/parser_generator/choice_generator_spec.rb +1 -63
  202. data/spec/rattler/{back_end → compiler}/parser_generator/disallow_generator_spec.rb +1 -55
  203. data/spec/rattler/{back_end → compiler}/parser_generator/e_symbol_generator_spec.rb +1 -39
  204. data/spec/rattler/{back_end → compiler}/parser_generator/eof_generator_spec.rb +1 -39
  205. data/spec/rattler/{back_end → compiler}/parser_generator/fail_generator_spec.rb +94 -23
  206. data/spec/rattler/compiler/parser_generator/grammar_generator_spec.rb +98 -0
  207. data/spec/rattler/compiler/parser_generator/group_match_generator_spec.rb +67 -0
  208. data/spec/rattler/{back_end → compiler}/parser_generator/group_match_spec.rb +1 -1
  209. data/spec/rattler/{back_end → compiler}/parser_generator/label_generator_spec.rb +1 -55
  210. data/spec/rattler/{back_end → compiler}/parser_generator/list0_generator_examples.rb +0 -88
  211. data/spec/rattler/{back_end → compiler}/parser_generator/list1_generator_examples.rb +0 -88
  212. data/spec/rattler/{back_end → compiler}/parser_generator/list_generator_spec.rb +1 -227
  213. data/spec/rattler/{back_end → compiler}/parser_generator/match_generator_spec.rb +1 -55
  214. data/spec/rattler/compiler/parser_generator/node_action_generator_spec.rb +135 -0
  215. data/spec/rattler/{back_end → compiler}/parser_generator/one_or_more_generator_examples.rb +0 -74
  216. data/spec/rattler/{back_end → compiler}/parser_generator/optional_generator_examples.rb +0 -62
  217. data/spec/rattler/{back_end → compiler}/parser_generator/repeat_generator_spec.rb +66 -1
  218. data/spec/rattler/{back_end → compiler}/parser_generator/rule_generator_spec.rb +3 -2
  219. data/spec/rattler/{back_end → compiler}/parser_generator/rule_set_generator_spec.rb +9 -27
  220. data/spec/rattler/compiler/parser_generator/semantic_action_generator_spec.rb +437 -0
  221. data/spec/rattler/{back_end → compiler}/parser_generator/sequence_generator_spec.rb +234 -68
  222. data/spec/rattler/{back_end → compiler}/parser_generator/skip_generator_spec.rb +1 -55
  223. data/spec/rattler/compiler/parser_generator/super_generator_spec.rb +93 -0
  224. data/spec/rattler/{back_end → compiler}/parser_generator/token_generator_spec.rb +1 -55
  225. data/spec/rattler/{back_end → compiler}/parser_generator/zero_or_more_generator_examples.rb +0 -74
  226. data/spec/rattler/{back_end → compiler}/ruby_generator_spec.rb +13 -13
  227. data/spec/rattler/compiler/semantic_action_compiler_examples.rb +57 -0
  228. data/spec/rattler/{back_end → compiler}/shared_compiler_examples.rb +111 -140
  229. data/spec/rattler/{back_end → compiler}/skip_compiler_examples.rb +60 -57
  230. data/spec/rattler/{back_end → compiler}/token_compiler_examples.rb +99 -104
  231. data/spec/rattler/compiler_spec.rb +67 -0
  232. data/spec/rattler/parsers/action_code_spec.rb +34 -18
  233. data/spec/rattler/{grammar → parsers}/analysis_spec.rb +13 -67
  234. data/spec/rattler/parsers/apply_spec.rb +6 -0
  235. data/spec/rattler/parsers/assert_spec.rb +38 -2
  236. data/spec/rattler/parsers/attributed_sequence_spec.rb +204 -0
  237. data/spec/rattler/parsers/back_reference_spec.rb +6 -0
  238. data/spec/rattler/parsers/choice_spec.rb +38 -1
  239. data/spec/rattler/parsers/combinator_parser_spec.rb +2 -1
  240. data/spec/rattler/parsers/disallow_spec.rb +38 -2
  241. data/spec/rattler/parsers/e_symbol_spec.rb +6 -0
  242. data/spec/rattler/parsers/eof_spec.rb +6 -0
  243. data/spec/rattler/parsers/fail_spec.rb +6 -0
  244. data/spec/rattler/{grammar → parsers}/grammar_spec.rb +10 -15
  245. data/spec/rattler/parsers/label_spec.rb +30 -0
  246. data/spec/rattler/parsers/list_parser_spec.rb +31 -2
  247. data/spec/rattler/parsers/match_spec.rb +6 -0
  248. data/spec/rattler/parsers/node_action_spec.rb +121 -0
  249. data/spec/rattler/parsers/parser_scope_spec.rb +105 -0
  250. data/spec/rattler/parsers/repeat_spec.rb +56 -0
  251. data/spec/rattler/parsers/rule_set_spec.rb +42 -0
  252. data/spec/rattler/parsers/semantic_action_spec.rb +89 -0
  253. data/spec/rattler/parsers/sequence_spec.rb +156 -12
  254. data/spec/rattler/parsers/skip_spec.rb +21 -0
  255. data/spec/rattler/parsers/super_spec.rb +45 -0
  256. data/spec/rattler/parsers/token_spec.rb +33 -14
  257. data/spec/rattler/runtime/extended_packrat_parser_spec.rb +10 -8
  258. data/spec/rattler/runtime/recursive_descent_parser_spec.rb +26 -0
  259. data/spec/rattler/runtime/shared_parser_examples.rb +22 -16
  260. data/spec/rattler/util/graphviz/node_builder_spec.rb +33 -17
  261. data/spec/rattler/util/line_counter_spec.rb +21 -21
  262. data/spec/rattler/util/node_spec.rb +62 -0
  263. data/spec/rattler_spec.rb +7 -41
  264. data/spec/spec_helper.rb +1 -2
  265. data/spec/support/combinator_parser_spec_helper.rb +1 -1
  266. data/spec/support/compiler_spec_helper.rb +0 -4
  267. data/spec/support/parser_generator_spec_helper.rb +7 -7
  268. data/spec/support/runtime_parser_spec_helper.rb +57 -3
  269. metadata +447 -303
  270. data/features/grammar/character_class.feature +0 -20
  271. data/features/grammar/nonterminal.feature +0 -24
  272. data/features/grammar/one_or_more.feature +0 -34
  273. data/features/grammar/ordered_choice.feature +0 -21
  274. data/features/grammar/posix_class.feature +0 -70
  275. data/features/grammar/sequence.feature +0 -20
  276. data/features/grammar/zero_or_more.feature +0 -34
  277. data/lib/rattler/back_end.rb +0 -22
  278. data/lib/rattler/back_end/compiler.rb +0 -128
  279. data/lib/rattler/back_end/optimizer.rb +0 -101
  280. data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +0 -46
  281. data/lib/rattler/back_end/optimizer/join_match_sequence.rb +0 -17
  282. data/lib/rattler/back_end/optimizer/join_predicate_match.rb +0 -17
  283. data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +0 -17
  284. data/lib/rattler/back_end/optimizer/optimization_context.rb +0 -72
  285. data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +0 -32
  286. data/lib/rattler/back_end/optimizer/specialize_repeat.rb +0 -40
  287. data/lib/rattler/back_end/parser_generator.rb +0 -113
  288. data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +0 -45
  289. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +0 -45
  290. data/lib/rattler/back_end/parser_generator/group_match.rb +0 -26
  291. data/lib/rattler/back_end/parser_generator/label_generator.rb +0 -64
  292. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +0 -24
  293. data/lib/rattler/back_end/parser_generator/rule_generator.rb +0 -53
  294. data/lib/rattler/back_end/parser_generator/sequence_generator.rb +0 -190
  295. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +0 -16
  296. data/lib/rattler/back_end/parser_generator/token_propogating.rb +0 -10
  297. data/lib/rattler/grammar.rb +0 -43
  298. data/lib/rattler/grammar/grammar_dsl.rb +0 -51
  299. data/lib/rattler/grammar/metagrammar.rb +0 -990
  300. data/lib/rattler/grammar/rattler.rtlr +0 -183
  301. data/lib/rattler/parsers/assert_code.rb +0 -31
  302. data/lib/rattler/parsers/direct_action.rb +0 -85
  303. data/lib/rattler/parsers/disallow_code.rb +0 -31
  304. data/lib/rattler/parsers/dispatch_action.rb +0 -121
  305. data/lib/rattler/parsers/effect_code.rb +0 -31
  306. data/lib/rattler/parsers/parser_dsl.rb +0 -414
  307. data/lib/rattler/parsers/semantic_assert.rb +0 -19
  308. data/lib/rattler/parsers/semantic_disallow.rb +0 -19
  309. data/lib/rattler/parsers/side_effect.rb +0 -19
  310. data/spec/rattler/back_end/assert_compiler_examples.rb +0 -187
  311. data/spec/rattler/back_end/compiler_spec.rb +0 -43
  312. data/spec/rattler/back_end/direct_action_compiler_examples.rb +0 -227
  313. data/spec/rattler/back_end/disallow_compiler_examples.rb +0 -187
  314. data/spec/rattler/back_end/dispatch_action_compiler_examples.rb +0 -225
  315. data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +0 -80
  316. data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +0 -204
  317. data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +0 -204
  318. data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +0 -185
  319. data/spec/rattler/back_end/semantic_assert_compiler_examples.rb +0 -152
  320. data/spec/rattler/back_end/semantic_disallow_compiler_examples.rb +0 -152
  321. data/spec/rattler/back_end/side_effect_compiler_examples.rb +0 -227
  322. data/spec/rattler/grammar/grammar_parser_spec.rb +0 -626
  323. data/spec/rattler/parsers/direct_action_spec.rb +0 -224
  324. data/spec/rattler/parsers/dispatch_action_spec.rb +0 -209
  325. data/spec/rattler/parsers/node_code_spec.rb +0 -59
  326. data/spec/rattler/parsers/parser_dsl_spec.rb +0 -334
  327. data/spec/rattler/parsers/semantic_assert_spec.rb +0 -83
  328. data/spec/rattler/parsers/semantic_disallow_spec.rb +0 -83
  329. data/spec/rattler/parsers/side_effect_spec.rb +0 -214
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ include Rattler::Compiler::ParserGenerator
4
+ include Rattler::Parsers
5
+
6
+ describe SuperGenerator do
7
+
8
+ include ParserGeneratorSpecHelper
9
+
10
+ let(:parser) { Super[:foo] }
11
+
12
+ describe '#gen_basic' do
13
+ it 'generates "super"' do
14
+ nested_code {|g| g.gen_basic parser }.should == 'super'
15
+ end
16
+ end
17
+
18
+ describe '#gen_assert' do
19
+
20
+ context 'when nested' do
21
+ it 'generates nested "assert super" code' do
22
+ nested_code {|g| g.gen_assert parser }.should == (<<-CODE).strip
23
+ begin
24
+ p = @scanner.pos
25
+ r = (super && true)
26
+ @scanner.pos = p
27
+ r
28
+ end
29
+ CODE
30
+ end
31
+ end
32
+
33
+ context 'when top level' do
34
+ it 'generates top-level "assert super" code' do
35
+ top_level_code {|g| g.gen_assert parser }.should == (<<-CODE).strip
36
+ p = @scanner.pos
37
+ r = (super && true)
38
+ @scanner.pos = p
39
+ r
40
+ CODE
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#gen_disallow' do
46
+
47
+ context 'when nested' do
48
+ it 'generates nested "disallow super" code' do
49
+ nested_code {|g| g.gen_disallow parser }.should == (<<-CODE).strip
50
+ begin
51
+ p = @scanner.pos
52
+ r = !super
53
+ @scanner.pos = p
54
+ r
55
+ end
56
+ CODE
57
+ end
58
+ end
59
+
60
+ context 'when top level' do
61
+ it 'generates top-level "disallow super" code' do
62
+ top_level_code {|g| g.gen_disallow parser }.should == (<<-CODE).strip
63
+ p = @scanner.pos
64
+ r = !super
65
+ @scanner.pos = p
66
+ r
67
+ CODE
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#gen_token' do
73
+ it 'generates "super.to_s"' do
74
+ nested_code {|g| g.gen_token parser }.should == 'super.to_s'
75
+ end
76
+ end
77
+
78
+ describe '#gen_skip' do
79
+
80
+ context 'when nested' do
81
+ it 'generates "(super && true)"' do
82
+ nested_code {|g| g.gen_skip parser }.should == '(super && true)'
83
+ end
84
+ end
85
+
86
+ context 'when top level' do
87
+ it 'generates "super && true"' do
88
+ top_level_code {|g| g.gen_skip parser }.should == 'super && true'
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
- include Rattler::BackEnd::ParserGenerator
3
+ include Rattler::Compiler::ParserGenerator
4
4
  include Rattler::Parsers
5
5
 
6
6
  describe TokenGenerator do
@@ -60,60 +60,6 @@ describe TokenGenerator do
60
60
  end
61
61
  end
62
62
 
63
- describe '#gen_dispatch_action' do
64
-
65
- let(:code) { NodeCode.new('Word', 'parsed') }
66
-
67
- context 'when nested' do
68
- it 'generates nested matching code with a dispatch action' do
69
- nested_code {|g| g.gen_dispatch_action token, code }.
70
- should == (<<-CODE).strip
71
- begin
72
- (r = @scanner.scan(/\\w+/)) &&
73
- Word.parsed([r])
74
- end
75
- CODE
76
- end
77
- end
78
-
79
- context 'when top-level' do
80
- it 'generates top level matching code with a dispatch action' do
81
- top_level_code {|g| g.gen_dispatch_action token, code }.
82
- should == (<<-CODE).strip
83
- (r = @scanner.scan(/\\w+/)) &&
84
- Word.parsed([r])
85
- CODE
86
- end
87
- end
88
- end
89
-
90
- describe '#gen_direct_action' do
91
-
92
- let(:code) { ActionCode.new('|_| _.to_sym') }
93
-
94
- context 'when nested' do
95
- it 'generates nested matching code with a direct action' do
96
- nested_code {|g| g.gen_direct_action token, code }.
97
- should == (<<-CODE).strip
98
- begin
99
- (r = @scanner.scan(/\\w+/)) &&
100
- (r.to_sym)
101
- end
102
- CODE
103
- end
104
- end
105
-
106
- context 'when top-level' do
107
- it 'generates top level matching code with a direct action' do
108
- top_level_code {|g| g.gen_direct_action token, code }.
109
- should == (<<-CODE).strip
110
- (r = @scanner.scan(/\\w+/)) &&
111
- (r.to_sym)
112
- CODE
113
- end
114
- end
115
- end
116
-
117
63
  describe '#gen_token' do
118
64
 
119
65
  context 'when nested' do
@@ -83,80 +83,6 @@ a
83
83
  end
84
84
  end
85
85
 
86
- describe '#gen_dispatch_action' do
87
-
88
- let(:nested) { Match[/w+/] }
89
- let(:code) { NodeCode.new('Word', 'parsed') }
90
-
91
- context 'given a repeat with zero-or-more bounds' do
92
-
93
- context 'when nested' do
94
- it 'generates nested zero-or-more matching code with a dispatch action' do
95
- nested_code {|g| g.gen_dispatch_action repeat, code }.
96
- should == (<<-CODE).strip
97
- begin
98
- a = []
99
- while r = @scanner.scan(/w+/)
100
- a << r
101
- end
102
- Word.parsed(select_captures(a))
103
- end
104
- CODE
105
- end
106
- end
107
-
108
- context 'when top-level' do
109
- it 'generates top level zero-or-more matching code with a dispatch action' do
110
- top_level_code {|g| g.gen_dispatch_action repeat, code }.
111
- should == (<<-CODE).strip
112
- a = []
113
- while r = @scanner.scan(/w+/)
114
- a << r
115
- end
116
- Word.parsed(select_captures(a))
117
- CODE
118
- end
119
- end
120
- end
121
- end
122
-
123
- describe '#gen_direct_action' do
124
-
125
- let(:nested) { Match[/w+/] }
126
- let(:code) { ActionCode.new('|_| _.size') }
127
-
128
- context 'given a repeat with zero-or-more bounds' do
129
-
130
- context 'when nested' do
131
- it 'generates nested zero-or-more matching code with a direct action' do
132
- nested_code {|g| g.gen_direct_action repeat, code }.
133
- should == (<<-CODE).strip
134
- begin
135
- a = []
136
- while r = @scanner.scan(/w+/)
137
- a << r
138
- end
139
- (select_captures(a).size)
140
- end
141
- CODE
142
- end
143
- end
144
-
145
- context 'when top-level' do
146
- it 'generates top level zero-or-more matching code with a direct action' do
147
- top_level_code {|g| g.gen_direct_action repeat, code }.
148
- should == (<<-CODE).strip
149
- a = []
150
- while r = @scanner.scan(/w+/)
151
- a << r
152
- end
153
- (select_captures(a).size)
154
- CODE
155
- end
156
- end
157
- end
158
- end
159
-
160
86
  describe '#gen_token' do
161
87
 
162
88
  let(:nested) { Match[/w+/] }
@@ -1,41 +1,41 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
- describe Rattler::BackEnd::RubyGenerator do
4
-
5
- subject { Rattler::BackEnd::RubyGenerator.new }
6
-
3
+ describe Rattler::Compiler::RubyGenerator do
4
+
5
+ subject { Rattler::Compiler::RubyGenerator.new }
6
+
7
7
  describe '<<' do
8
8
  it 'concatenates code' do
9
9
  (subject << 'foo' << '(:bar)').code.should == 'foo(:bar)'
10
10
  end
11
11
  end
12
-
12
+
13
13
  describe '#newline' do
14
14
  it 'starts new lines' do
15
15
  ((subject << 'foo').newline << 'bar').code.should == "foo\nbar"
16
16
  end
17
17
  end
18
-
18
+
19
19
  describe '#indent' do
20
20
  it 'indents lines' do
21
21
  subject.indent { (subject << 'foo').newline << 'bar' }.code.
22
22
  should == "\n foo\n bar"
23
23
  end
24
24
  end
25
-
25
+
26
26
  describe '#surround' do
27
27
  it 'surrounds code with the given prefix and suffix' do
28
28
  subject.surround('(', ')') { subject << 'foo' }.code.should == '(foo)'
29
29
  end
30
30
  end
31
-
31
+
32
32
  describe '#block' do
33
33
  it 'generates blocks' do
34
34
  subject.block('for n in names') { subject << 'puts n' }.code.
35
35
  should == "for n in names\n puts n\nend"
36
36
  end
37
37
  end
38
-
38
+
39
39
  describe '#intersperse' do
40
40
  context 'given the :sep option by itself' do
41
41
  it 'intersperses the separator without newlines' do
@@ -44,7 +44,7 @@ describe Rattler::BackEnd::RubyGenerator do
44
44
  end.code.should == "aa + bb + cc"
45
45
  end
46
46
  end
47
-
47
+
48
48
  context 'given :newline => true' do
49
49
  it 'intersperses the separator with single newlines' do
50
50
  subject.intersperse(['a', 'b', 'c'], :sep => ' +', :newline => true) do |_|
@@ -52,7 +52,7 @@ describe Rattler::BackEnd::RubyGenerator do
52
52
  end.code.should == "aa +\nbb +\ncc"
53
53
  end
54
54
  end
55
-
55
+
56
56
  context 'given :newlines => n' do
57
57
  it 'intersperses separators with multiple newlines' do
58
58
  subject.intersperse(['a', 'b', 'c'], :sep => ' +', :newlines => 2) do |_|
@@ -60,7 +60,7 @@ describe Rattler::BackEnd::RubyGenerator do
60
60
  end.code.should == "aa +\n\nbb +\n\ncc"
61
61
  end
62
62
  end
63
-
63
+
64
64
  context 'given :newlines => n and no :sep option' do
65
65
  it 'intersperses the newlines without any other separator' do
66
66
  subject.intersperse(['a', 'b', 'c'], :newline => true) do |_|
@@ -69,5 +69,5 @@ describe Rattler::BackEnd::RubyGenerator do
69
69
  end
70
70
  end
71
71
  end
72
-
72
+
73
73
  end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ shared_examples_for 'a compiled parser with a semantic action' do
4
+ include CompilerSpecHelper
5
+ include RuntimeParserSpecHelper
6
+
7
+ subject { compiled_parser }
8
+
9
+ let(:reference_parser) { combinator_parser grammar }
10
+
11
+ let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
12
+
13
+ context 'when the expression has no parameters' do
14
+ let(:rules) { [
15
+ rule(:a) { semantic_action('42') }
16
+ ] }
17
+ it { should parse('anything').succeeding.like reference_parser }
18
+ end
19
+
20
+ context 'when the expression has parameters' do
21
+ let(:rules) { [
22
+ rule(:a) { match(/\d+/) >> semantic_action('|a| a.to_i * 2') }
23
+ ] }
24
+ it { should parse('451a').succeeding.like reference_parser }
25
+ it { should parse(' ').failing.like reference_parser }
26
+ end
27
+
28
+ context 'when the expression uses "_"' do
29
+
30
+ context 'given a single capture' do
31
+ let(:rules) { [
32
+ rule(:a) { match(/\d+/) >> semantic_action('_ * 2') }
33
+ ] }
34
+ it { should parse('451a').succeeding.like reference_parser }
35
+ it { should parse(' ').failing.like reference_parser }
36
+ end
37
+
38
+ context 'given multiple captures' do
39
+ let(:rules) { [
40
+ rule(:a) {
41
+ (match(/\d+/) & skip(/\s+/) & match(/\d+/)) >> semantic_action('_')
42
+ }
43
+ ] }
44
+ it { should parse('23 42').succeeding.like reference_parser }
45
+ it { should parse(' ').failing.like reference_parser }
46
+ end
47
+ end
48
+
49
+ context 'when the expression uses labels' do
50
+ let(:rules) { [
51
+ rule(:a) { label(:a, /\d+/) & semantic_action('a.to_i * 2') }
52
+ ] }
53
+ it { should parse('451a').succeeding.like reference_parser }
54
+ it { should parse(' ').failing.like reference_parser }
55
+ end
56
+
57
+ end
@@ -1,24 +1,19 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
  require File.expand_path('assert_compiler_examples', File.dirname(__FILE__))
3
3
  require File.expand_path('disallow_compiler_examples', File.dirname(__FILE__))
4
- require File.expand_path('dispatch_action_compiler_examples', File.dirname(__FILE__))
5
- require File.expand_path('direct_action_compiler_examples', File.dirname(__FILE__))
6
- require File.expand_path('side_effect_compiler_examples', File.dirname(__FILE__))
7
- require File.expand_path('semantic_assert_compiler_examples', File.dirname(__FILE__))
8
- require File.expand_path('semantic_disallow_compiler_examples', File.dirname(__FILE__))
4
+ require File.expand_path('semantic_action_compiler_examples', File.dirname(__FILE__))
5
+ require File.expand_path('attributed_sequence_compiler_examples', File.dirname(__FILE__))
9
6
  require File.expand_path('token_compiler_examples', File.dirname(__FILE__))
10
7
  require File.expand_path('skip_compiler_examples', File.dirname(__FILE__))
11
8
 
12
9
  shared_examples_for 'a compiled parser' do
13
10
  include CompilerSpecHelper
11
+ include RuntimeParserSpecHelper
14
12
 
15
13
  it_behaves_like 'a compiled parser with an assert'
16
14
  it_behaves_like 'a compiled parser with a disallow'
17
- it_behaves_like 'a compiled parser with a dispatch action'
18
- it_behaves_like 'a compiled parser with a direct action'
19
- it_behaves_like 'a compiled parser with a side effect'
20
- it_behaves_like 'a compiled parser with a positive semantic predicate'
21
- it_behaves_like 'a compiled parser with a negative semantic predicate'
15
+ it_behaves_like 'a compiled parser with a semantic action'
16
+ it_behaves_like 'a compiled parser with an attributed sequence'
22
17
  it_behaves_like 'a compiled parser with a token'
23
18
  it_behaves_like 'a compiled parser with a skip'
24
19
 
@@ -26,11 +21,13 @@ shared_examples_for 'a compiled parser' do
26
21
 
27
22
  let(:reference_parser) { combinator_parser grammar }
28
23
 
24
+ let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
25
+
29
26
  ########## match ##########
30
27
  context 'with a match rule' do
31
- let(:grammar) { define_grammar do
32
- rule(:digit) { match /\d/ }
33
- end }
28
+ let(:rules) { [
29
+ rule(:digit) { match(/\d/) }
30
+ ] }
34
31
  it { should parse('451').succeeding.twice.like reference_parser }
35
32
  it { should parse(' 4').failing.like reference_parser }
36
33
  it { should parse('foo').failing.like reference_parser }
@@ -38,50 +35,46 @@ shared_examples_for 'a compiled parser' do
38
35
 
39
36
  ########## choice ##########
40
37
  context 'with a choice rule' do
41
- let(:grammar) { define_grammar do
38
+ let(:rules) { [
42
39
  rule(:atom) { match(/[[:alpha:]]+/) | match(/[[:digit:]]+/) }
43
- end }
40
+ ] }
44
41
  it { should parse('abc123').succeeding.twice.like reference_parser }
45
42
  it { should parse('==').failing.like reference_parser }
46
43
 
47
44
  context 'with non-capturing parsers' do
48
- let(:grammar) { define_grammar do
49
- rule :foo do
50
- skip(/\s+/) | skip(/\{[^\}]*\}/)
51
- end
52
- end }
45
+ let(:rules) { [
46
+ rule(:foo) { skip(/\s+/) | skip(/\{[^\}]*\}/) }
47
+ ] }
53
48
  it { should parse(' foo').succeeding.like reference_parser }
54
49
  it { should parse('{foo}').succeeding.like reference_parser }
55
50
  end
56
51
 
57
52
  context 'with nested choices' do
58
- let(:grammar) { define_grammar do
59
- rule(:foo) do
53
+ let(:rules) { [
54
+ rule(:foo) {
60
55
  ( (match('a') | match('b')) \
61
56
  | (match('c') | match('d')) )
62
- end
63
- end }
57
+ }
58
+ ] }
64
59
  it { should parse('abcd').succeeding(4).times.like reference_parser }
65
60
  it { should parse('123').failing.like reference_parser }
66
61
  end
67
62
 
68
63
  context 'with nested sequences' do
69
- let(:grammar) { define_grammar do
70
- rule(:foo) do
64
+ let(:rules) { [
65
+ rule(:foo) {
71
66
  ( match('a') & match('b') \
72
67
  | match('c') & match('d') )
73
- end
74
- end }
68
+ }
69
+ ] }
75
70
  it { should parse('abcd').succeeding.twice.like reference_parser }
76
71
  it { should parse('123').failing.like reference_parser }
77
72
  end
78
73
 
79
74
  context 'with nested optional parsers' do
80
- let(:grammar) { define_grammar do
81
- rule(:foo) do
82
- optional('a') | optional('b')
83
- end
84
- end }
75
+ let(:rules) { [
76
+ rule(:foo) { match('a').optional | match('b').optional }
77
+ ] }
85
78
  it { should parse('abcd').succeeding(3).times.like reference_parser }
86
79
  it { should parse('123').succeeding.like reference_parser }
87
80
  end
@@ -89,70 +82,60 @@ shared_examples_for 'a compiled parser' do
89
82
 
90
83
  ########## sequence ##########
91
84
  context 'with a sequence rule' do
92
- let(:grammar) { define_grammar do
93
- rule :assignment do
85
+ let(:rules) { [
86
+ rule(:assignment) {
94
87
  match(/[[:alpha:]]+/) & match('=') & match(/[[:digit:]]+/)
95
- end
96
- end }
88
+ }
89
+ ] }
97
90
  it { should parse('val=42 ').succeeding.like reference_parser }
98
91
  it { should parse('val=x ').failing.like reference_parser }
99
92
 
100
93
  context 'with non-capturing parsers' do
101
- let(:grammar) { define_grammar do
102
- rule :foo do
94
+ let(:rules) { [
95
+ rule(:foo) {
103
96
  match(/[[:alpha:]]+/) & skip(/\s+/) & match(/[[:digit:]]+/)
104
- end
105
- end }
97
+ }
98
+ ] }
106
99
  it { should parse('foo 42').succeeding.like reference_parser }
107
100
  end
108
101
 
109
102
  context 'with only one capturing parser' do
110
- let(:grammar) { define_grammar do
111
- rule :foo do
112
- skip(/\s+/) & match(/\w+/)
113
- end
114
- end }
103
+ let(:rules) { [
104
+ rule(:foo) { skip(/\s+/) & match(/\w+/) }
105
+ ] }
115
106
  it { should parse(' abc123').succeeding.like reference_parser }
116
107
  end
117
108
 
118
109
  context 'with no capturing parsers' do
119
- let(:grammar) { define_grammar do
120
- rule :foo do
121
- skip(/\s*/) & skip(/#[^\n]+/)
122
- end
123
- end }
110
+ let(:rules) { [
111
+ rule(:foo) { skip(/\s*/) & skip(/#[^\n]+/) }
112
+ ] }
124
113
  it { should parse(' # foo').succeeding.like reference_parser }
125
114
  end
126
115
 
127
116
  context 'with an apply referencing a non-capturing rule' do
128
- let(:grammar) { define_grammar do
129
- rule :foo do
117
+ let(:rules) { [
118
+ rule(:foo) {
130
119
  match(/[[:alpha:]]+/) & match(:ws) & match(/[[:digit:]]+/)
131
- end
132
- rule :ws do
133
- skip(/\s+/)
134
- end
135
- end }
120
+ },
121
+ rule(:ws) { skip(/\s+/) }
122
+ ] }
136
123
  it { should parse('foo 42').succeeding.like reference_parser }
137
124
  end
138
125
  end
139
126
 
140
127
  ########## optional ##########
141
128
  context 'with an optional rule' do
142
- let(:grammar) { define_grammar do
143
- rule :foo do
144
- optional(/\w+/)
145
- end
146
- end }
129
+ let(:rules) { [
130
+ rule(:foo) { match(/\w+/).optional }
131
+ ] }
147
132
  it { should parse('foo ').succeeding.like reference_parser }
148
133
  it { should parse(' ').succeeding.like reference_parser }
149
134
 
150
135
  context 'with a non-capturing parser' do
151
- let(:grammar) { define_grammar do
152
- rule :foo do
153
- optional(skip(/\w+/))
154
- end
155
- end }
136
+ let(:rules) { [
137
+ rule(:foo) { skip(/\w+/).optional }
138
+ ] }
156
139
  it { should parse('foo ').succeeding.like reference_parser }
157
140
  it { should parse(' ').succeeding.like reference_parser }
158
141
  end
@@ -160,20 +143,16 @@ shared_examples_for 'a compiled parser' do
160
143
 
161
144
  ########## zero-or-more ##########
162
145
  context 'with an zero-or-more rule' do
163
- let(:grammar) { define_grammar do
164
- rule :foo do
165
- zero_or_more(/\w/)
166
- end
167
- end }
146
+ let(:rules) { [
147
+ rule(:foo) { match(/\w/).zero_or_more }
148
+ ] }
168
149
  it { should parse('foo ').succeeding.like reference_parser }
169
150
  it { should parse(' ').succeeding.like reference_parser }
170
151
 
171
152
  context 'with a non-capturing parser' do
172
- let(:grammar) { define_grammar do
173
- rule :foo do
174
- zero_or_more(skip(/\w/))
175
- end
176
- end }
153
+ let(:rules) { [
154
+ rule(:foo) { skip(/\w/).zero_or_more }
155
+ ] }
177
156
  it { should parse('foo ').succeeding.like reference_parser }
178
157
  it { should parse(' ').succeeding.like reference_parser }
179
158
  end
@@ -181,20 +160,16 @@ shared_examples_for 'a compiled parser' do
181
160
 
182
161
  ########## one-or-more ##########
183
162
  context 'with an one-or-more rule' do
184
- let(:grammar) { define_grammar do
185
- rule :foo do
186
- one_or_more(/\w/)
187
- end
188
- end }
163
+ let(:rules) { [
164
+ rule(:foo) { match(/\w/).one_or_more }
165
+ ] }
189
166
  it { should parse('foo ').succeeding.like reference_parser }
190
167
  it { should parse(' ').failing.like reference_parser }
191
168
 
192
169
  context 'with a non-capturing parser' do
193
- let(:grammar) { define_grammar do
194
- rule :foo do
195
- one_or_more(skip(/\w/))
196
- end
197
- end }
170
+ let(:rules) { [
171
+ rule(:foo) { skip(/\w/).one_or_more }
172
+ ] }
198
173
  it { should parse('foo ').succeeding.like reference_parser }
199
174
  it { should parse(' ').failing.like reference_parser }
200
175
  end
@@ -202,55 +177,59 @@ shared_examples_for 'a compiled parser' do
202
177
 
203
178
  ########## repeat ##########
204
179
  context 'with a repeat rule' do
205
- let(:grammar) { define_grammar do
206
- rule :foo do
207
- repeat(/\w/, 2, 4)
208
- end
209
- end }
180
+ let(:rules) { [
181
+ rule(:foo) { match(/\w/).repeat(2, 4) }
182
+ ] }
210
183
  it { should parse('foo ').succeeding.like reference_parser }
211
184
  it { should parse('abcde ').succeeding.like reference_parser }
212
185
  it { should parse('a ').failing.like reference_parser }
213
186
 
214
187
  context 'with no upper bound' do
215
- let(:grammar) { define_grammar do
216
- rule :foo do
217
- repeat(/\w/, 2, nil)
218
- end
219
- end }
188
+ let(:rules) { [
189
+ rule(:foo) { match(/\w/).repeat(2, nil) }
190
+ ] }
220
191
  it { should parse('foo ').succeeding.like reference_parser }
221
192
  it { should parse('abcde ').succeeding.like reference_parser }
222
193
  it { should parse('a ').failing.like reference_parser }
223
194
  end
224
195
 
225
196
  context 'with a non-capturing parser' do
226
- let(:grammar) { define_grammar do
227
- rule :foo do
228
- repeat(skip(/\w/), 2, 4)
229
- end
230
- end }
197
+ let(:rules) { [
198
+ rule(:foo) { skip(/\w/).repeat(2, 4) }
199
+ ] }
231
200
  it { should parse('foo ').succeeding.like reference_parser }
232
201
  it { should parse('abcde ').succeeding.like reference_parser }
233
202
  it { should parse('a ').failing.like reference_parser }
234
203
  end
204
+
205
+ context 'with a choice of capturing or non-capturing parsers' do
206
+ let(:rules) { [
207
+ rule(:foo) { (match(/a/) | skip(/b/)).repeat(2, 4) }
208
+ ] }
209
+ it { should parse('abac').succeeding.like reference_parser }
210
+ end
211
+
212
+ context 'with an attributed sequence with an action returning true' do
213
+ let(:rules) { [
214
+ rule(:foo) { (match(/\w/) >> semantic_action('true')).repeat(2, 4) }
215
+ ] }
216
+ it { should parse('abc ').succeeding.like reference_parser }
217
+ end
235
218
  end
236
219
 
237
220
  ########## list ##########
238
221
  context 'given a list rule' do
239
- let(:grammar) { define_grammar do
240
- rule :foo do
241
- list(/\w+/, /[,;]/, 2, nil)
242
- end
243
- end }
222
+ let(:rules) { [
223
+ rule(:foo) { match(/\w+/).list(match(/[,;]/), 2, nil) }
224
+ ] }
244
225
  it { should parse('foo ').failing.like reference_parser }
245
226
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
246
227
  it { should parse('foo,bar, ').succeeding.like reference_parser }
247
228
 
248
229
  context 'with an upper bound' do
249
- let(:grammar) { define_grammar do
250
- rule :foo do
251
- list(/\w+/, /[,;]/, 2, 4)
252
- end
253
- end }
230
+ let(:rules) { [
231
+ rule(:foo) { match(/\w+/).list(match(/[,;]/), 2, 4) }
232
+ ] }
254
233
  it { should parse('foo ').failing.like reference_parser }
255
234
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
256
235
  it { should parse('a,b,c,d,e ').succeeding.like reference_parser }
@@ -258,21 +237,17 @@ shared_examples_for 'a compiled parser' do
258
237
  end
259
238
 
260
239
  context 'with a non-capturing parser' do
261
- let(:grammar) { define_grammar do
262
- rule :foo do
263
- list(skip(/\w+/), /[,;]/, 2, nil)
264
- end
265
- end }
240
+ let(:rules) { [
241
+ rule(:foo) { skip(/\w+/).list(match(/[,;]/), 2, nil) }
242
+ ] }
266
243
  it { should parse('foo ').failing.like reference_parser }
267
244
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
268
245
  it { should parse('foo,bar, ').succeeding.like reference_parser }
269
246
 
270
247
  context 'with an upper bound' do
271
- let(:grammar) { define_grammar do
272
- rule :foo do
273
- list(skip(/\w+/), /[,;]/, 2, 4)
274
- end
275
- end }
248
+ let(:rules) { [
249
+ rule(:foo) { skip(/\w+/).list(match(/[,;]/), 2, 4) }
250
+ ] }
276
251
  it { should parse('foo ').failing.like reference_parser }
277
252
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
278
253
  it { should parse('a,b,c,d,e ').succeeding.like reference_parser }
@@ -280,22 +255,18 @@ shared_examples_for 'a compiled parser' do
280
255
  end
281
256
 
282
257
  context 'with "zero-or-more" bounds' do
283
- let(:grammar) { define_grammar do
284
- rule :foo do
285
- list(skip(/\w+/), /[,;]/, 0, nil)
286
- end
287
- end }
258
+ let(:rules) { [
259
+ rule(:foo) { skip(/\w+/).list(match(/[,;]/), 0, nil) }
260
+ ] }
288
261
  it { should parse(' ').succeeding.like reference_parser }
289
262
  it { should parse('foo ').succeeding.like reference_parser }
290
263
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
291
264
  end
292
265
 
293
266
  context 'with "one-or-more" bounds' do
294
- let(:grammar) { define_grammar do
295
- rule :foo do
296
- list(skip(/\w+/), /[,;]/, 1, nil)
297
- end
298
- end }
267
+ let(:rules) { [
268
+ rule(:foo) { skip(/\w+/).list(match(/[,;]/), 1, nil) }
269
+ ] }
299
270
  it { should parse(' ').failing.like reference_parser }
300
271
  it { should parse('foo ').succeeding.like reference_parser }
301
272
  it { should parse('foo,bar;baz ').succeeding.like reference_parser }
@@ -305,19 +276,19 @@ shared_examples_for 'a compiled parser' do
305
276
 
306
277
  ########## apply ##########
307
278
  context 'given an apply rule' do
308
- let(:grammar) { define_grammar do
309
- rule(:digit) { match /\d/ }
279
+ let(:rules) { [
280
+ rule(:digit) { match /\d/ },
310
281
  rule(:foo) { match :digit }
311
- end }
282
+ ] }
312
283
  it { should parse('451 ').twice.succeeding.like reference_parser }
313
284
  it { should parse('hi').failing.like reference_parser }
314
285
  end
315
286
 
316
287
  ########## eof ##########
317
288
  context 'given eof' do
318
- let(:grammar) { define_grammar do
289
+ let(:rules) { [
319
290
  rule(:foo) { eof }
320
- end }
291
+ ] }
321
292
  it { should parse('').succeeding.like reference_parser }
322
293
  it { should parse('foo').from(3).succeeding.like reference_parser }
323
294
  it { should parse('foo').failing.like reference_parser }
@@ -325,9 +296,9 @@ shared_examples_for 'a compiled parser' do
325
296
 
326
297
  ########## E ##########
327
298
  context 'given "E" symbol' do
328
- let(:grammar) { define_grammar do
299
+ let(:rules) { [
329
300
  rule(:foo) { e }
330
- end }
301
+ ] }
331
302
  it { should parse('').succeeding.like reference_parser }
332
303
  it { should parse('foo').succeeding.like reference_parser }
333
304
  end