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
@@ -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 AssertGenerator do
@@ -58,60 +58,6 @@ describe AssertGenerator do
58
58
  end
59
59
  end
60
60
 
61
- describe '#gen_dispatch_action' do
62
-
63
- let(:code) { NodeCode.new('Word', 'parsed') }
64
-
65
- context 'when nested' do
66
- it 'generates nested positive lookahead code with a dispatch action' do
67
- nested_code {|g| g.gen_dispatch_action assert, code }.
68
- should == (<<-CODE).strip
69
- begin
70
- @scanner.skip(/(?=\\d)/) &&
71
- Word.parsed([])
72
- end
73
- CODE
74
- end
75
- end
76
-
77
- context 'when top-level' do
78
- it 'generates top level positive lookahead code with a dispatch action' do
79
- top_level_code {|g| g.gen_dispatch_action assert, code }.
80
- should == (<<-CODE).strip
81
- @scanner.skip(/(?=\\d)/) &&
82
- Word.parsed([])
83
- CODE
84
- end
85
- end
86
- end
87
-
88
- describe '#gen_direct_action' do
89
-
90
- let(:code) { ActionCode.new(':t') }
91
-
92
- context 'when nested' do
93
- it 'generates nested positive lookahead code with a direct action' do
94
- nested_code {|g| g.gen_direct_action assert, code }.
95
- should == (<<-CODE).strip
96
- begin
97
- @scanner.skip(/(?=\\d)/) &&
98
- (:t)
99
- end
100
- CODE
101
- end
102
- end
103
-
104
- context 'when top-level' do
105
- it 'generates top level positive lookahead code with a direct action' do
106
- top_level_code {|g| g.gen_direct_action assert, code }.
107
- should == (<<-CODE).strip
108
- @scanner.skip(/(?=\\d)/) &&
109
- (:t)
110
- CODE
111
- end
112
- end
113
- end
114
-
115
61
  describe '#gen_token' do
116
62
 
117
63
  context 'when nested' do
@@ -0,0 +1,699 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ include Rattler::Compiler::ParserGenerator
4
+ include Rattler::Parsers
5
+
6
+ describe AttributedSequenceGenerator do
7
+
8
+ include ParserGeneratorSpecHelper
9
+ include Rattler::Runtime
10
+
11
+ let(:sequence) { AttributedSequence[*children] }
12
+
13
+ describe '#gen_basic' do
14
+
15
+ context 'given a sequence with a single capture and a semantic action' do
16
+
17
+ let(:children) { [Match[/\w+/], action] }
18
+
19
+ context 'when the action uses a paramter' do
20
+
21
+ let(:action) { SemanticAction['|s| "<#{s}>"'] }
22
+
23
+ it 'generates code that binds the capture to the parameter and returns the result' do
24
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
25
+ should == (<<-'CODE').strip
26
+ p0 = @scanner.pos
27
+ begin
28
+ (r0_0 = @scanner.scan(/\w+/)) &&
29
+ ("<#{r0_0}>")
30
+ end || begin
31
+ @scanner.pos = p0
32
+ false
33
+ end
34
+ CODE
35
+ end
36
+ end
37
+
38
+ context 'when the action uses a "_"' do
39
+
40
+ let(:action) { SemanticAction['"<#{_}>"'] }
41
+
42
+ it 'generates code that binds the capture to "_" and returns the result' do
43
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
44
+ should == (<<-'CODE').strip
45
+ p0 = @scanner.pos
46
+ begin
47
+ (r0_0 = @scanner.scan(/\w+/)) &&
48
+ ("<#{r0_0}>")
49
+ end || begin
50
+ @scanner.pos = p0
51
+ false
52
+ end
53
+ CODE
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'given a sequence with a single capture and a node action' do
59
+
60
+ let(:children) { [Match[/\w+/], NodeAction['Expr']] }
61
+
62
+ it 'generates code that returns a new node with the capture' do
63
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
64
+ should == (<<-'CODE').strip
65
+ p0 = @scanner.pos
66
+ begin
67
+ (r0_0 = @scanner.scan(/\w+/)) &&
68
+ Expr.parsed([r0_0])
69
+ end || begin
70
+ @scanner.pos = p0
71
+ false
72
+ end
73
+ CODE
74
+ end
75
+ end
76
+
77
+ context 'given a sequence with an undecidable capture and a node action' do
78
+
79
+ let(:children) { [Apply[:a], NodeAction['Expr']] }
80
+
81
+ it 'generates code that returns a new node using select_captures' do
82
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
83
+ should == (<<-'CODE').strip
84
+ p0 = @scanner.pos
85
+ begin
86
+ (r0_0 = match(:a)) &&
87
+ Expr.parsed(select_captures([r0_0]))
88
+ end || begin
89
+ @scanner.pos = p0
90
+ false
91
+ end
92
+ CODE
93
+ end
94
+ end
95
+
96
+ context 'given a sequence with multiple captures and a semantic action' do
97
+
98
+ let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
99
+
100
+ context 'when the action uses parameters' do
101
+
102
+ let(:action) { SemanticAction['|a,b| b + a'] }
103
+
104
+ it 'generates code that binds the captures to the parameter and returns the result' do
105
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
106
+ should == (<<-'CODE').strip
107
+ p0 = @scanner.pos
108
+ begin
109
+ (r0_0 = @scanner.scan(/\d+/)) &&
110
+ @scanner.skip(/\s+/) &&
111
+ (r0_1 = @scanner.scan(/\d+/)) &&
112
+ (r0_1 + r0_0)
113
+ end || begin
114
+ @scanner.pos = p0
115
+ false
116
+ end
117
+ CODE
118
+ end
119
+ end
120
+
121
+ context 'when the action uses "_"' do
122
+
123
+ let(:action) { SemanticAction['_ * 2'] }
124
+
125
+ it 'generates code that binds the array of captures to the parameter and returns the result' do
126
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
127
+ should == (<<-'CODE').strip
128
+ p0 = @scanner.pos
129
+ begin
130
+ (r0_0 = @scanner.scan(/\d+/)) &&
131
+ @scanner.skip(/\s+/) &&
132
+ (r0_1 = @scanner.scan(/\d+/)) &&
133
+ ([r0_0, r0_1] * 2)
134
+ end || begin
135
+ @scanner.pos = p0
136
+ false
137
+ end
138
+ CODE
139
+ end
140
+ end
141
+ end
142
+
143
+ context 'given a sequence with multiple captures and a node action' do
144
+
145
+ let :children do
146
+ [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], NodeAction['Nums']]
147
+ end
148
+
149
+ it 'generates code that returns a new node with the captures' do
150
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
151
+ should == (<<-'CODE').strip
152
+ p0 = @scanner.pos
153
+ begin
154
+ (r0_0 = @scanner.scan(/\d+/)) &&
155
+ @scanner.skip(/\s+/) &&
156
+ (r0_1 = @scanner.scan(/\d+/)) &&
157
+ Nums.parsed([r0_0, r0_1])
158
+ end || begin
159
+ @scanner.pos = p0
160
+ false
161
+ end
162
+ CODE
163
+ end
164
+ end
165
+
166
+ context 'given a sequence with labeled captures and a semantic action' do
167
+
168
+ let(:children) { [
169
+ Label[:x, Match[/\d+/]],
170
+ Skip[Match[/\s+/]],
171
+ Label[:y, Match[/\d+/]],
172
+ SemanticAction['y + x']
173
+ ] }
174
+
175
+ it 'generates code that binds the labeled captures to the parameter and returns the result' do
176
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
177
+ should == (<<-'CODE').strip
178
+ p0 = @scanner.pos
179
+ begin
180
+ (r0_0 = @scanner.scan(/\d+/)) &&
181
+ @scanner.skip(/\s+/) &&
182
+ (r0_1 = @scanner.scan(/\d+/)) &&
183
+ (r0_1 + r0_0)
184
+ end || begin
185
+ @scanner.pos = p0
186
+ false
187
+ end
188
+ CODE
189
+ end
190
+ end
191
+
192
+ context 'given a sequence with labeled captures and a node action' do
193
+
194
+ let(:children) { [
195
+ Label[:x, Match[/\d+/]],
196
+ Skip[Match[/\s+/]],
197
+ Match[/\d+/],
198
+ NodeAction['Nums']
199
+ ] }
200
+
201
+ it 'generates code that returns a new node with the bindings as the :labeled attribute' do
202
+ top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
203
+ should == (<<-'CODE').strip
204
+ p0 = @scanner.pos
205
+ begin
206
+ (r0_0 = @scanner.scan(/\d+/)) &&
207
+ @scanner.skip(/\s+/) &&
208
+ (r0_1 = @scanner.scan(/\d+/)) &&
209
+ Nums.parsed([r0_0, r0_1], :labeled => {:x => r0_0})
210
+ end || begin
211
+ @scanner.pos = p0
212
+ false
213
+ end
214
+ CODE
215
+ end
216
+ end
217
+ end
218
+
219
+ describe '#gen_assert' do
220
+
221
+ context 'given a sequence with a single capture and a semantic action' do
222
+
223
+ let(:children) { [Match[/\w+/], action] }
224
+
225
+ context 'when the action uses a paramter' do
226
+
227
+ let(:action) { SemanticAction['|s| "<#{s}>"'] }
228
+
229
+ it 'generates code that binds the capture to the parameter and asserts the result' do
230
+ top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
231
+ should == (<<-'CODE').strip
232
+ p0 = @scanner.pos
233
+ r = begin
234
+ (r0_0 = @scanner.scan(/\w+/)) &&
235
+ ("<#{r0_0}>") &&
236
+ true
237
+ end
238
+ @scanner.pos = p0
239
+ r
240
+ CODE
241
+ end
242
+ end
243
+
244
+ context 'when the action uses a "_"' do
245
+
246
+ let(:action) { SemanticAction['"<#{_}>"'] }
247
+
248
+ it 'generates code that binds the capture to "_" and asserts the result' do
249
+ top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
250
+ should == (<<-'CODE').strip
251
+ p0 = @scanner.pos
252
+ r = begin
253
+ (r0_0 = @scanner.scan(/\w+/)) &&
254
+ ("<#{r0_0}>") &&
255
+ true
256
+ end
257
+ @scanner.pos = p0
258
+ r
259
+ CODE
260
+ end
261
+ end
262
+ end
263
+
264
+ context 'given a sequence with multiple captures and a semantic action' do
265
+
266
+ let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
267
+
268
+ context 'when the action uses parameters' do
269
+
270
+ let(:action) { SemanticAction['|a,b| b + a'] }
271
+
272
+ it 'generates code that binds the captures to the parameter and asserts the result' do
273
+ top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
274
+ should == (<<-'CODE').strip
275
+ p0 = @scanner.pos
276
+ r = begin
277
+ (r0_0 = @scanner.scan(/\d+/)) &&
278
+ @scanner.skip(/\s+/) &&
279
+ (r0_1 = @scanner.scan(/\d+/)) &&
280
+ (r0_1 + r0_0) &&
281
+ true
282
+ end
283
+ @scanner.pos = p0
284
+ r
285
+ CODE
286
+ end
287
+ end
288
+
289
+ context 'when the action uses "_"' do
290
+
291
+ let(:action) { SemanticAction['_ * 2'] }
292
+
293
+ it 'generates code that binds the array of captures to the parameter and asserts the result' do
294
+ top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
295
+ should == (<<-'CODE').strip
296
+ p0 = @scanner.pos
297
+ r = begin
298
+ (r0_0 = @scanner.scan(/\d+/)) &&
299
+ @scanner.skip(/\s+/) &&
300
+ (r0_1 = @scanner.scan(/\d+/)) &&
301
+ ([r0_0, r0_1] * 2) &&
302
+ true
303
+ end
304
+ @scanner.pos = p0
305
+ r
306
+ CODE
307
+ end
308
+ end
309
+ end
310
+
311
+ context 'given a sequence with labeled captures and a semantic action' do
312
+
313
+ let(:children) { [
314
+ Label[:x, Match[/\d+/]],
315
+ Skip[Match[/\s+/]],
316
+ Label[:y, Match[/\d+/]],
317
+ SemanticAction['y + x']
318
+ ] }
319
+
320
+ it 'generates code that binds the labeled captures to the parameter and asserts the result' do
321
+ top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
322
+ should == (<<-'CODE').strip
323
+ p0 = @scanner.pos
324
+ r = begin
325
+ (r0_0 = @scanner.scan(/\d+/)) &&
326
+ @scanner.skip(/\s+/) &&
327
+ (r0_1 = @scanner.scan(/\d+/)) &&
328
+ (r0_1 + r0_0) &&
329
+ true
330
+ end
331
+ @scanner.pos = p0
332
+ r
333
+ CODE
334
+ end
335
+ end
336
+ end
337
+
338
+ describe '#gen_disallow' do
339
+
340
+ context 'given a sequence with a single capture and a semantic action' do
341
+
342
+ let(:children) { [Match[/\w+/], action] }
343
+
344
+ context 'when the action uses a paramter' do
345
+
346
+ let(:action) { SemanticAction['|s| "<#{s}>"'] }
347
+
348
+ it 'generates code that binds the capture to the parameter and disallows the result' do
349
+ top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
350
+ should == (<<-'CODE').strip
351
+ p0 = @scanner.pos
352
+ r = !begin
353
+ (r0_0 = @scanner.scan(/\w+/)) &&
354
+ ("<#{r0_0}>")
355
+ end
356
+ @scanner.pos = p0
357
+ r
358
+ CODE
359
+ end
360
+ end
361
+
362
+ context 'when the action uses a "_"' do
363
+
364
+ let(:action) { SemanticAction['"<#{_}>"'] }
365
+
366
+ it 'generates code that binds the capture to "_" and disallows the result' do
367
+ top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
368
+ should == (<<-'CODE').strip
369
+ p0 = @scanner.pos
370
+ r = !begin
371
+ (r0_0 = @scanner.scan(/\w+/)) &&
372
+ ("<#{r0_0}>")
373
+ end
374
+ @scanner.pos = p0
375
+ r
376
+ CODE
377
+ end
378
+ end
379
+ end
380
+
381
+ context 'given a sequence with multiple captures and a semantic action' do
382
+
383
+ let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
384
+
385
+ context 'when the action uses parameters' do
386
+
387
+ let(:action) { SemanticAction['|a,b| b + a'] }
388
+
389
+ it 'generates code that binds the captures to the parameter and disallows the result' do
390
+ top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
391
+ should == (<<-'CODE').strip
392
+ p0 = @scanner.pos
393
+ r = !begin
394
+ (r0_0 = @scanner.scan(/\d+/)) &&
395
+ @scanner.skip(/\s+/) &&
396
+ (r0_1 = @scanner.scan(/\d+/)) &&
397
+ (r0_1 + r0_0)
398
+ end
399
+ @scanner.pos = p0
400
+ r
401
+ CODE
402
+ end
403
+ end
404
+
405
+ context 'when the action uses "_"' do
406
+
407
+ let(:action) { SemanticAction['_ * 2'] }
408
+
409
+ it 'generates code that binds the array of captures to the parameter and disallows the result' do
410
+ top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
411
+ should == (<<-'CODE').strip
412
+ p0 = @scanner.pos
413
+ r = !begin
414
+ (r0_0 = @scanner.scan(/\d+/)) &&
415
+ @scanner.skip(/\s+/) &&
416
+ (r0_1 = @scanner.scan(/\d+/)) &&
417
+ ([r0_0, r0_1] * 2)
418
+ end
419
+ @scanner.pos = p0
420
+ r
421
+ CODE
422
+ end
423
+ end
424
+ end
425
+
426
+ context 'given a sequence with labeled captures and a semantic action' do
427
+
428
+ let(:children) { [
429
+ Label[:x, Match[/\d+/]],
430
+ Skip[Match[/\s+/]],
431
+ Label[:y, Match[/\d+/]],
432
+ SemanticAction['y + x']
433
+ ] }
434
+
435
+ it 'generates code that binds the labeled captures to the parameter and disallows the result' do
436
+ top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
437
+ should == (<<-'CODE').strip
438
+ p0 = @scanner.pos
439
+ r = !begin
440
+ (r0_0 = @scanner.scan(/\d+/)) &&
441
+ @scanner.skip(/\s+/) &&
442
+ (r0_1 = @scanner.scan(/\d+/)) &&
443
+ (r0_1 + r0_0)
444
+ end
445
+ @scanner.pos = p0
446
+ r
447
+ CODE
448
+ end
449
+ end
450
+ end
451
+
452
+ describe '#gen_token' do
453
+
454
+ context 'given a sequence with a single capture and a semantic action' do
455
+
456
+ let(:children) { [Match[/\w+/], action] }
457
+
458
+ context 'when the action uses a paramter' do
459
+
460
+ let(:action) { SemanticAction['|s| "<#{s}>"'] }
461
+
462
+ it 'generates code that binds the capture to the parameter and returns the matched string' do
463
+ top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
464
+ should == (<<-'CODE').strip
465
+ p0 = @scanner.pos
466
+ begin
467
+ (r0_0 = @scanner.scan(/\w+/)) &&
468
+ ("<#{r0_0}>") &&
469
+ @scanner.string[p0...(@scanner.pos)]
470
+ end || begin
471
+ @scanner.pos = p0
472
+ false
473
+ end
474
+ CODE
475
+ end
476
+ end
477
+
478
+ context 'when the action uses a "_"' do
479
+
480
+ let(:action) { SemanticAction['"<#{_}>"'] }
481
+
482
+ it 'generates code that binds the capture to "_" and returns the matched string' do
483
+ top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
484
+ should == (<<-'CODE').strip
485
+ p0 = @scanner.pos
486
+ begin
487
+ (r0_0 = @scanner.scan(/\w+/)) &&
488
+ ("<#{r0_0}>") &&
489
+ @scanner.string[p0...(@scanner.pos)]
490
+ end || begin
491
+ @scanner.pos = p0
492
+ false
493
+ end
494
+ CODE
495
+ end
496
+ end
497
+ end
498
+
499
+ context 'given a sequence with multiple captures and a semantic action' do
500
+
501
+ let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
502
+
503
+ context 'when the action uses parameters' do
504
+
505
+ let(:action) { SemanticAction['|a,b| b + a'] }
506
+
507
+ it 'generates code that binds the captures to the parameter and returns the matched string' do
508
+ top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
509
+ should == (<<-'CODE').strip
510
+ p0 = @scanner.pos
511
+ begin
512
+ (r0_0 = @scanner.scan(/\d+/)) &&
513
+ @scanner.skip(/\s+/) &&
514
+ (r0_1 = @scanner.scan(/\d+/)) &&
515
+ (r0_1 + r0_0) &&
516
+ @scanner.string[p0...(@scanner.pos)]
517
+ end || begin
518
+ @scanner.pos = p0
519
+ false
520
+ end
521
+ CODE
522
+ end
523
+ end
524
+
525
+ context 'when the action uses "_"' do
526
+
527
+ let(:action) { SemanticAction['_ * 2'] }
528
+
529
+ it 'generates code that binds the array of captures to the parameter and returns the matched string' do
530
+ top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
531
+ should == (<<-'CODE').strip
532
+ p0 = @scanner.pos
533
+ begin
534
+ (r0_0 = @scanner.scan(/\d+/)) &&
535
+ @scanner.skip(/\s+/) &&
536
+ (r0_1 = @scanner.scan(/\d+/)) &&
537
+ ([r0_0, r0_1] * 2) &&
538
+ @scanner.string[p0...(@scanner.pos)]
539
+ end || begin
540
+ @scanner.pos = p0
541
+ false
542
+ end
543
+ CODE
544
+ end
545
+ end
546
+ end
547
+
548
+ context 'given a sequence with labeled captures and a semantic action' do
549
+
550
+ let(:children) { [
551
+ Label[:x, Match[/\d+/]],
552
+ Skip[Match[/\s+/]],
553
+ Label[:y, Match[/\d+/]],
554
+ SemanticAction['y + x']
555
+ ] }
556
+
557
+ it 'generates code that binds the labeled captures to the parameter and returns the matched string' do
558
+ top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
559
+ should == (<<-'CODE').strip
560
+ p0 = @scanner.pos
561
+ begin
562
+ (r0_0 = @scanner.scan(/\d+/)) &&
563
+ @scanner.skip(/\s+/) &&
564
+ (r0_1 = @scanner.scan(/\d+/)) &&
565
+ (r0_1 + r0_0) &&
566
+ @scanner.string[p0...(@scanner.pos)]
567
+ end || begin
568
+ @scanner.pos = p0
569
+ false
570
+ end
571
+ CODE
572
+ end
573
+ end
574
+ end
575
+
576
+ describe '#gen_skip' do
577
+
578
+ context 'given a sequence with a single capture and a semantic action' do
579
+
580
+ let(:children) { [Match[/\w+/], action] }
581
+
582
+ context 'when the action uses a paramter' do
583
+
584
+ let(:action) { SemanticAction['|s| "<#{s}>"'] }
585
+
586
+ it 'generates code that binds the capture to the parameter and skips the result' do
587
+ top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
588
+ should == (<<-'CODE').strip
589
+ p0 = @scanner.pos
590
+ begin
591
+ (r0_0 = @scanner.scan(/\w+/)) &&
592
+ ("<#{r0_0}>") &&
593
+ true
594
+ end || begin
595
+ @scanner.pos = p0
596
+ false
597
+ end
598
+ CODE
599
+ end
600
+ end
601
+
602
+ context 'when the action uses a "_"' do
603
+
604
+ let(:action) { SemanticAction['"<#{_}>"'] }
605
+
606
+ it 'generates code that binds the capture to "_" and skips the result' do
607
+ top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
608
+ should == (<<-'CODE').strip
609
+ p0 = @scanner.pos
610
+ begin
611
+ (r0_0 = @scanner.scan(/\w+/)) &&
612
+ ("<#{r0_0}>") &&
613
+ true
614
+ end || begin
615
+ @scanner.pos = p0
616
+ false
617
+ end
618
+ CODE
619
+ end
620
+ end
621
+ end
622
+
623
+ context 'given a sequence with multiple captures and a semantic action' do
624
+
625
+ let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
626
+
627
+ context 'when the action uses parameters' do
628
+
629
+ let(:action) { SemanticAction['|a,b| b + a'] }
630
+
631
+ it 'generates code that binds the captures to the parameter and skips the result' do
632
+ top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
633
+ should == (<<-'CODE').strip
634
+ p0 = @scanner.pos
635
+ begin
636
+ (r0_0 = @scanner.scan(/\d+/)) &&
637
+ @scanner.skip(/\s+/) &&
638
+ (r0_1 = @scanner.scan(/\d+/)) &&
639
+ (r0_1 + r0_0) &&
640
+ true
641
+ end || begin
642
+ @scanner.pos = p0
643
+ false
644
+ end
645
+ CODE
646
+ end
647
+ end
648
+
649
+ context 'when the action uses "_"' do
650
+
651
+ let(:action) { SemanticAction['_ * 2'] }
652
+
653
+ it 'generates code that binds the array of captures to the parameter and skips the result' do
654
+ top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
655
+ should == (<<-'CODE').strip
656
+ p0 = @scanner.pos
657
+ begin
658
+ (r0_0 = @scanner.scan(/\d+/)) &&
659
+ @scanner.skip(/\s+/) &&
660
+ (r0_1 = @scanner.scan(/\d+/)) &&
661
+ ([r0_0, r0_1] * 2) &&
662
+ true
663
+ end || begin
664
+ @scanner.pos = p0
665
+ false
666
+ end
667
+ CODE
668
+ end
669
+ end
670
+ end
671
+
672
+ context 'given a sequence with labeled captures and a semantic action' do
673
+
674
+ let(:children) { [
675
+ Label[:x, Match[/\d+/]],
676
+ Skip[Match[/\s+/]],
677
+ Label[:y, Match[/\d+/]],
678
+ SemanticAction['y + x']
679
+ ] }
680
+
681
+ it 'generates code that binds the labeled captures to the parameter and skips the result' do
682
+ top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
683
+ should == (<<-'CODE').strip
684
+ p0 = @scanner.pos
685
+ begin
686
+ (r0_0 = @scanner.scan(/\d+/)) &&
687
+ @scanner.skip(/\s+/) &&
688
+ (r0_1 = @scanner.scan(/\d+/)) &&
689
+ (r0_1 + r0_0) &&
690
+ true
691
+ end || begin
692
+ @scanner.pos = p0
693
+ false
694
+ end
695
+ CODE
696
+ end
697
+ end
698
+ end
699
+ end