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,105 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Rattler::Parsers::ParserScope do
4
+
5
+ describe '.empty' do
6
+
7
+ subject { described_class.empty }
8
+
9
+ it 'has no bindings' do
10
+ subject.bindings.should be_empty
11
+ end
12
+
13
+ it 'has no captures' do
14
+ subject.captures.should be_empty
15
+ end
16
+ end
17
+
18
+ describe '#bind' do
19
+
20
+ subject { described_class.empty }
21
+
22
+ it 'returns a new scope with the given bindings' do
23
+ scope = subject.bind(:a => 'foo', :b => 'bar')
24
+ scope.bindings[:a].should == 'foo'
25
+ scope.bindings[:b].should == 'bar'
26
+ end
27
+
28
+ context 'given a binding with an already bound name' do
29
+
30
+ subject { described_class.new(:a => 'foo') }
31
+
32
+ it 'shadows the existing binding with the new binding' do
33
+ subject.bind(:a => 'bar').bindings[:a].should == 'bar'
34
+ end
35
+ end
36
+
37
+ context 'with existing captures' do
38
+
39
+ subject { described_class.new({}, ['foo', 'bar']) }
40
+
41
+ it 'includes the captures in the new scope' do
42
+ subject.bind(:a => 'foo').captures.should == ['foo', 'bar']
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#capture' do
48
+
49
+ subject { described_class.empty }
50
+
51
+ it 'returns a new scope with the given captures' do
52
+ subject.capture('foo', 'bar').captures.should == ['foo', 'bar']
53
+ end
54
+
55
+ context 'with existing captures' do
56
+
57
+ subject { described_class.new({}, ['foo', 'bar']) }
58
+
59
+ it 'returns a new scope with the given captures appended' do
60
+ subject.capture('baz').captures.should == ['foo', 'bar', 'baz']
61
+ end
62
+ end
63
+
64
+ context 'with existing bindings' do
65
+
66
+ subject { described_class.new(:a => 'foo') }
67
+
68
+ it 'includes the bindings in the new scope' do
69
+ subject.capture('baz').bindings[:a].should == 'foo'
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#nest' do
75
+
76
+ subject { described_class.new({:a => 'baz'}, ['foo', 'bar']) }
77
+
78
+ it 'returns a new scope with the same bindings but no captures' do
79
+ subject.nest.bindings[:a].should == 'baz'
80
+ subject.nest.captures.should be_empty
81
+ end
82
+ end
83
+
84
+ describe '#merge' do
85
+
86
+ subject { described_class.new({:a => 'baz'}, ['foo', 'bar']) }
87
+ let(:other) { described_class.new({:b => 'fez'}, ['boo'] ) }
88
+
89
+ it 'returns a new scope with bindings from the other scope' do
90
+ merged = subject.merge(other)
91
+ merged.bindings[:a].should == 'baz'
92
+ merged.bindings[:b].should == 'fez'
93
+ merged.captures.should == ['foo', 'bar']
94
+ end
95
+ end
96
+
97
+ describe '#[]' do
98
+
99
+ subject { described_class.new(:a => 'foo') }
100
+
101
+ it 'returns bindings' do
102
+ subject[:a].should == 'foo'
103
+ end
104
+ end
105
+ end
@@ -97,6 +97,32 @@ describe Repeat do
97
97
  end
98
98
  end
99
99
 
100
+ context 'with a choice of capturing or non-capturing parsers' do
101
+
102
+ subject { Repeat[child, 0, nil] }
103
+
104
+ let(:child) { Choice[
105
+ Match[/a/],
106
+ Skip[Match[/b/]]
107
+ ] }
108
+
109
+ it 'returns only the capturing results' do
110
+ parsing('aba').should result_in(['a', 'a']).at(3)
111
+ end
112
+ end
113
+
114
+ context 'with an attributed sequence with a semantic action returning true' do
115
+
116
+ subject { Repeat[child, 0, nil] }
117
+
118
+ let(:child) do
119
+ AttributedSequence[Match[/\w/], SemanticAction['true']]
120
+ end
121
+
122
+ it 'returns an empty array' do
123
+ parsing('foo ').should result_in([]).at(3)
124
+ end
125
+ end
100
126
  end
101
127
 
102
128
  describe '#capturing?' do
@@ -121,6 +147,36 @@ describe Repeat do
121
147
 
122
148
  end
123
149
 
150
+ describe '#capturing_decidable?' do
151
+
152
+ context 'with a decidably capturing parser' do
153
+
154
+ subject { Repeat[capturing_child, 0, nil] }
155
+
156
+ it 'is true' do
157
+ subject.should be_capturing_decidable
158
+ end
159
+ end
160
+
161
+ context 'with a decidably non-capturing parser' do
162
+
163
+ subject { Repeat[skipping_child, 0, nil] }
164
+
165
+ it 'is true' do
166
+ subject.should be_capturing_decidable
167
+ end
168
+ end
169
+
170
+ context 'with a non-capturing_decidable parser' do
171
+
172
+ subject { Repeat[Apply[:foo], 0, nil] }
173
+
174
+ it 'is false' do
175
+ subject.should_not be_capturing_decidable
176
+ end
177
+ end
178
+ end
179
+
124
180
  describe '#with_ws' do
125
181
 
126
182
  let(:ws) { Match[/\s*/] }
@@ -9,10 +9,52 @@ describe Rattler::Parsers::RuleSet do
9
9
  let(:rule_b) { Rule[:b, Match[/b/]] }
10
10
 
11
11
  describe '#rule' do
12
+
12
13
  it 'returns rules by name' do
13
14
  subject.rule(:a).should == rule_a
14
15
  subject.rule(:b).should == rule_b
15
16
  end
17
+
18
+ context 'with included rules' do
19
+
20
+ subject { RuleSet[rule_a, rule_b, {:includes => [RuleSet[rule_c]]}] }
21
+
22
+ let(:rule_c) { Rule[:c, Match[/c/]] }
23
+
24
+ context 'given a name only in the included rules' do
25
+ it 'returns the rule from the included rules' do
26
+ subject.inherited_rule(:c).should == rule_c
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#inherited_rule' do
33
+
34
+ context 'with no includes' do
35
+ it 'returns nil' do
36
+ subject.inherited_rule(:foo).should be_nil
37
+ end
38
+ end
39
+
40
+ context 'with included rules' do
41
+
42
+ subject { RuleSet[rule_a, rule_b, {:includes => [RuleSet[old_rule_a]]}] }
43
+
44
+ let(:old_rule_a) { Rule[:a, Match[/A/]] }
45
+
46
+ context 'given a name not in the rule set or the included rules' do
47
+ it 'returns nil' do
48
+ subject.inherited_rule(:foo).should be_nil
49
+ end
50
+ end
51
+
52
+ context 'given a name in the included rules' do
53
+ it 'returns the rule from the included rules' do
54
+ subject.inherited_rule(:a).should == old_rule_a
55
+ end
56
+ end
57
+ end
16
58
  end
17
59
 
18
60
  describe '#[]' do
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe SemanticAction do
4
+ include CombinatorParserSpecHelper
5
+
6
+ describe '#parse' do
7
+
8
+ let(:scope) { ParserScope.new(bindings, captures) }
9
+
10
+ let(:bindings) { {} }
11
+ let(:captures) { [] }
12
+
13
+ context 'when the expression has no parameters' do
14
+
15
+ subject { SemanticAction['42'] }
16
+
17
+ it 'returns the evaluation of the expression without advancing' do
18
+ parsing('anything').at(4).should result_in(42).at(4)
19
+ end
20
+ end
21
+
22
+ context 'when the expression has parameters' do
23
+
24
+ subject { SemanticAction['|a,b| a * b'] }
25
+ let(:captures) { [2, 3] }
26
+
27
+ it 'returns the evaluation of the expression using captures' do
28
+ parsing('anything').at(4).should result_in(6).at(4)
29
+ end
30
+ end
31
+
32
+ context 'when the expression uses "_"' do
33
+
34
+ context 'given a single capture' do
35
+
36
+ subject { SemanticAction['_ * 4'] }
37
+ let(:captures) { [3] }
38
+
39
+ it 'returns the evaluation of the expression using the capture' do
40
+ parsing('anything').at(4).should result_in(12).at(4)
41
+ end
42
+ end
43
+
44
+ context 'given multiple captures' do
45
+
46
+ subject { SemanticAction['_ * 2'] }
47
+ let(:captures) { [3, 2] }
48
+
49
+ it 'returns the evaluation of the expression using the array of captures' do
50
+ parsing('anything').at(4).should result_in([3, 2, 3, 2]).at(4)
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'when the expression uses labels' do
56
+
57
+ subject { SemanticAction['x * y'] }
58
+ let(:bindings) { {:x => 3, :y => 5 } }
59
+
60
+ it 'returns the evaluation of the expression using bindings' do
61
+ parsing('anything').at(4).should result_in(15).at(4)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#capturing?' do
67
+ it 'is true' do
68
+ SemanticAction['@foo'].should be_capturing
69
+ end
70
+ end
71
+
72
+ describe '#capturing_decidable?' do
73
+ it 'is true' do
74
+ SemanticAction['@foo'].should be_capturing_decidable
75
+ end
76
+ end
77
+
78
+ describe '#with_ws' do
79
+
80
+ subject { SemanticAction['@foo'] }
81
+
82
+ let(:ws) { Match[/\s*/] }
83
+
84
+ it 'returns the action unchanged' do
85
+ subject.with_ws(ws).should == subject
86
+ end
87
+ end
88
+
89
+ end
@@ -3,11 +3,11 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
3
  describe Sequence do
4
4
  include CombinatorParserSpecHelper
5
5
 
6
- subject { Sequence[*nested] }
6
+ subject { Sequence[*children] }
7
7
 
8
8
  describe '#parse' do
9
9
 
10
- let(:nested) { [Match[/[[:alpha:]]+/], Match[/\=/], Match[/[[:digit:]]+/]] }
10
+ let(:children) { [Match[/[[:alpha:]]+/], Match[/\=/], Match[/[[:digit:]]+/]] }
11
11
 
12
12
  context 'when all of the parsers match in sequence' do
13
13
  it 'matches returning the results in an array' do
@@ -23,7 +23,7 @@ describe Sequence do
23
23
 
24
24
  context 'with non-capturing parsers' do
25
25
 
26
- let :nested do
26
+ let :children do
27
27
  [Match[/[[:alpha:]]+/], Skip[Match[/\s+/]], Match[/[[:digit:]]+/]]
28
28
  end
29
29
 
@@ -36,7 +36,7 @@ describe Sequence do
36
36
 
37
37
  context 'with only one capturing parser' do
38
38
 
39
- let(:nested) { [Skip[Match[/\s+/]], Match[/\w+/]] }
39
+ let(:children) { [Skip[Match[/\s+/]], Match[/\w+/]] }
40
40
 
41
41
  context 'when all of the parsers match in sequence' do
42
42
  it 'returns the result of the capturing parser' do
@@ -47,7 +47,7 @@ describe Sequence do
47
47
 
48
48
  context 'with no capturing parsers' do
49
49
 
50
- let(:nested) { [Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]] }
50
+ let(:children) { [Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]] }
51
51
 
52
52
  context 'when all of the parsers match in sequence' do
53
53
  it 'returns true' do
@@ -58,7 +58,7 @@ describe Sequence do
58
58
 
59
59
  context 'with an apply parser referencing a non-capturing rule' do
60
60
 
61
- let(:nested) { [Match[/[[:alpha:]]+/], Apply[:ws], Match[/[[:digit:]]+/]] }
61
+ let(:children) { [Match[/[[:alpha:]]+/], Apply[:ws], Match[/[[:digit:]]+/]] }
62
62
 
63
63
  let(:rules) { RuleSet[Rule[:ws, Skip[Match[/\s+/]]]] }
64
64
 
@@ -68,13 +68,77 @@ describe Sequence do
68
68
  end
69
69
  end
70
70
  end
71
+
72
+ context 'with a single capture and a semantic action' do
73
+
74
+ context 'when the action uses a parameter' do
75
+
76
+ let(:children) { [Match[/\w+/], SemanticAction['|s| "<#{s}>"']] }
77
+
78
+ it 'binds the capture to the parameter' do
79
+ parsing('foo').should result_in ['foo', '<foo>']
80
+ end
81
+ end
82
+
83
+ context 'when the action uses "_"' do
84
+
85
+ let(:children) { [Match[/\w+/], SemanticAction['"<#{_}>"']] }
86
+
87
+ it 'binds the capture to "_"' do
88
+ parsing('foo').should result_in ['foo', '<foo>']
89
+ end
90
+ end
91
+ end
92
+
93
+ context 'with multiple captures and a semantic action' do
94
+
95
+ context 'when the action uses parameters' do
96
+
97
+ let(:children) { [Match[/[a-z]+/], Match[/\d+/], SemanticAction['|a,b| b+a']] }
98
+
99
+ it 'binds the captures to the parameters' do
100
+ parsing('abc123').should result_in ['abc', '123', '123abc']
101
+ end
102
+ end
103
+
104
+ context 'when the action uses "_"' do
105
+
106
+ let(:children) { [Match[/[a-z]+/], Match[/\d+/], SemanticAction['_']] }
107
+
108
+ it 'binds the array of captures to "_"' do
109
+ parsing('abc123').should result_in ['abc', '123', ['abc', '123']]
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'with a single labeled capture and a semantic action' do
115
+
116
+ let(:children) { [Label[:a, Match[/\w+/]], SemanticAction['"<#{a}>"']] }
117
+
118
+ it 'binds the capture to the label name' do
119
+ parsing('foo').should result_in ['foo', '<foo>']
120
+ end
121
+ end
122
+
123
+ context 'with multiple labeled captures and a semantic action' do
124
+
125
+ let(:children) { [
126
+ Label[:a, Match[/[[:alpha:]]+/]],
127
+ Label[:b, Match[/[[:digit:]]+/]],
128
+ SemanticAction['b + a']
129
+ ] }
130
+
131
+ it 'binds the captures to the label names' do
132
+ parsing('abc123').should result_in ['abc', '123', '123abc']
133
+ end
134
+ end
71
135
  end
72
136
 
73
137
  describe '#capturing?' do
74
138
 
75
139
  context 'with any capturing parsers' do
76
140
 
77
- let(:nested) { [Skip[Match[/\s*/]], Match[/\w+/]] }
141
+ let(:children) { [Skip[Match[/\s*/]], Match[/\w+/]] }
78
142
 
79
143
  it 'is true' do
80
144
  subject.should be_capturing
@@ -83,7 +147,7 @@ describe Sequence do
83
147
 
84
148
  context 'with no capturing parsers' do
85
149
 
86
- let(:nested) { [Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]] }
150
+ let(:children) { [Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]] }
87
151
 
88
152
  it 'is false' do
89
153
  subject.should_not be_capturing
@@ -94,14 +158,94 @@ describe Sequence do
94
158
  describe '#with_ws' do
95
159
 
96
160
  let(:ws) { Match[/\s*/] }
97
- let(:nested) { [Match[/[[:alpha:]]+/], Match[/[[:digit:]]+/]] }
161
+ let(:children) { [Match[/[[:alpha:]]+/], Match[/[[:digit:]]+/]] }
98
162
 
99
- it 'applies #with_ws to the nested parsers' do
163
+ it 'applies #with_ws to the children parsers' do
100
164
  subject.with_ws(ws).should == Sequence[
101
- Sequence[Skip[ws], nested[0]],
102
- Sequence[Skip[ws], nested[1]]
165
+ Sequence[Skip[ws], children[0]],
166
+ Sequence[Skip[ws], children[1]]
103
167
  ]
104
168
  end
105
169
  end
106
170
 
171
+ describe '#capture_count' do
172
+
173
+ context 'with no capturing parsers' do
174
+
175
+ let(:children) { [Skip[Match[/\s*/]], Skip[Match[/#[^\n]+/]]] }
176
+
177
+ it 'is 0' do
178
+ subject.capture_count.should == 0
179
+ end
180
+ end
181
+
182
+ context 'with a single capturing parser' do
183
+
184
+ let(:children) { [Skip[Match[/\s*/]], Match[/\w+/]] }
185
+
186
+ it 'is 1' do
187
+ subject.capture_count.should == 1
188
+ end
189
+ end
190
+
191
+ context 'with a two capturing parsers' do
192
+
193
+ let(:children) { [Match[/[a-z]+/], Match[/\d+/]] }
194
+
195
+ it 'is 2' do
196
+ subject.capture_count.should == 2
197
+ end
198
+ end
199
+
200
+ context 'with a non-capturing parser and two capturing parsers' do
201
+
202
+ let(:children) { [Match[/\d+/], Skip[Match[/\s*/]], Match[/\d+/]] }
203
+
204
+ it 'is 2' do
205
+ subject.capture_count.should == 2
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#capturing_decidable?' do
211
+
212
+ context 'with all capturing_decidable parsers' do
213
+
214
+ let(:children) { [Match[/\w+/], Skip[Match[/\s*/]]] }
215
+
216
+ it 'is true' do
217
+ subject.should be_capturing_decidable
218
+ end
219
+ end
220
+
221
+ context 'with any non-capturing_decidable parsers' do
222
+
223
+ let(:children) { [Match[/\w+/], Apply[:foo]] }
224
+
225
+ it 'is false' do
226
+ subject.should_not be_capturing_decidable
227
+ end
228
+ end
229
+ end
230
+
231
+ describe '#&' do
232
+
233
+ let(:children) { [Match[/[a-z]+/], Match[/\d+/]] }
234
+
235
+ it 'returns a new sequence with the given parser appended' do
236
+ (subject & Match[/:/]).should ==
237
+ Sequence[Match[/[a-z]+/], Match[/\d+/], Match[/:/]]
238
+ end
239
+ end
240
+
241
+ describe '#>>' do
242
+
243
+ let(:children) { [Match[/[a-z]+/], Match[/\d+/]] }
244
+
245
+ it 'returns an attributed sequence with the given semantic action' do
246
+ (subject >> SemanticAction['_']).should ==
247
+ AttributedSequence[Match[/[a-z]+/], Match[/\d+/], SemanticAction['_']]
248
+ end
249
+ end
250
+
107
251
  end