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
@@ -12,183 +12,11 @@ as possible. To that end, the normal parsing expression grammar syntax is
12
12
  extended with simple features to overcome some of the limitations of pure
13
13
  PEG grammars.
14
14
 
15
- A language syntax is specified in a grammar using the Rattler syntax. Parser
16
- classes and modules can be generated statically using the "rtlr" command or
17
- dynamically from strings.
15
+ === Documentation
18
16
 
19
- The cucumber features are currently the best documentation.
17
+ For the best documentation see the {cucumber features}[http://www.relishapp.com/jarhart/rattler]
20
18
 
21
- {RDoc}[http://rubydoc.info/gems/rattler/0.5.0/frames]
22
-
23
- == FEATURES:
24
-
25
- * Uses readable PEG-like grammars
26
- * Supports directly and indirectly left-recursive grammars
27
- * Whitespace can be specified in one place and skipped automatically
28
- * Automatic and custom parse error reporting
29
- * Optimizing parser generator generates efficient pure-ruby parsers
30
- * Compatible with Ruby 1.8.7 and 1.9.2, tested with MRI and JRuby on Linux and
31
- Windows and with Rubinius on Linux
32
-
33
- == PROBLEMS/LIMITATIONS:
34
-
35
- * Only strings can be parsed, so files have to be read completely before parsing
36
- * There are many holes in the tests so there are undoubtedly many bugs
37
- * Support for composable grammars is not yet implemented
38
- * Semantics of automatic whitespace skipping could be refined
39
- * Incomplete documentation
40
-
41
- == EXAMPLES:
42
-
43
- === Example 1: Statically generated parser class
44
-
45
- ==== json.rtlr:
46
-
47
- # JSON parser based on the grammar at http://www.json.org
48
-
49
- require File.expand_path('json_helper', File.dirname(__FILE__))
50
-
51
- parser JsonParser < Rattler::Runtime::PackratParser
52
-
53
- include JsonHelper
54
-
55
- %whitespace (SPACE+ / comment)* {
56
-
57
- json_text <- (object / array) EOF
58
-
59
- object <- ~'{' members ~'}' { object _ }
60
-
61
- members <- pair *, ','
62
-
63
- pair <- string ~':' value
64
-
65
- array <- ~'[' elements ~']'
66
-
67
- elements <- value *, ','
68
-
69
- value <- string
70
- / number
71
- / object
72
- / array
73
- / `true` { :true }
74
- / `false` { :false }
75
- / `null` { :null }
76
- / fail "value expected"
77
-
78
- string <- @('"' char* '"') { string _ }
79
-
80
- number <- @(int frac? exp?) { number _ }
81
- }
82
-
83
- %inline {
84
-
85
- char <- !('"' / '\\' / CNTRL) .
86
- / '\\' (["\\/bfnrt] / 'u' XDIGIT XDIGIT XDIGIT XDIGIT)
87
-
88
- int <- '-'? ('0' !DIGIT / [1-9] DIGIT*)
89
-
90
- frac <- '.' DIGIT+
91
-
92
- exp <- [eE] [+-]? DIGIT+
93
-
94
- comment <- '/*' (! '*/' .)* '*/'
95
- / '//' [^\n]*
96
- }
97
-
98
- ==== json_helper.rb:
99
-
100
- module JsonHelper
101
-
102
- def object(members)
103
- Hash[*members.flatten(1)]
104
- end
105
-
106
- def string(expr)
107
- eval "%q#{expr}", TOPLEVEL_BINDING
108
- end
109
-
110
- def number(expr)
111
- eval expr, TOPLEVEL_BINDING
112
- end
113
-
114
- end
115
-
116
- ==== $ rtlr json.rtlr
117
-
118
- json.rtlr -> json_parser.rb
119
-
120
- ==== parse_json.rb:
121
-
122
- require 'rubygems'
123
- require 'rattler'
124
- require 'json_parser'
125
-
126
- begin
127
- p JsonParser.parse!(open(ARGV[0]) {|io| io.read })
128
- rescue Rattler::Runtime::SyntaxError => e
129
- puts e
130
- end
131
-
132
- === Example 2: Statically generated grammar module
133
-
134
- ==== json.rtlr:
135
-
136
- # JSON parser based on the grammar at http://www.json.org
137
-
138
- grammar JsonGrammar
139
-
140
- %whitespace (SPACE+ / comment)* {
141
-
142
- ...
143
-
144
- ==== $ rtlr json.rtlr
145
-
146
- json.rtlr -> json_grammar.rb
147
-
148
- ==== json_parser.rb:
149
-
150
- require 'rubygems'
151
- require 'rattler'
152
- require 'json_grammar'
153
-
154
- class JsonParser < Rattler::Runtime::PackratParser
155
-
156
- include JsonGrammar
157
-
158
- def object(members)
159
- Hash[*members.flatten(1)]
160
- end
161
-
162
- ...
163
-
164
- === Example 3: Dynamically generated parser class
165
-
166
- require 'rubygems'
167
- require 'rattler'
168
-
169
- Calculator = Rattler::compile_parser %{
170
- %whitespace SPACE*
171
-
172
- start <- expr EOF
173
-
174
- expr <- expr ~'+' term {|a, b| a + b }
175
- / expr ~'-' term {|a, b| a - b }
176
- / term
177
-
178
- term <- term ~'*' primary {|a, b| a * b }
179
- / term ~'/' primary {|a, b| a / b }
180
- / primary
181
-
182
- primary <- ~'(' expr ~')'
183
- / @('-'? DIGIT+ ('.' DIGIT+)?) { _.to_f }
184
- },
185
- :type => :extended_packrat
186
-
187
- begin
188
- puts Calculator.parse!(expr)
189
- rescue Rattler::Runtime::SyntaxError => e
190
- puts e
191
- end
19
+ You may also wish to browse the {API Docs}[http://rubydoc.info/gems/rattler/0.5.0/frames]
192
20
 
193
21
  == REQUIREMENTS:
194
22
 
@@ -0,0 +1,27 @@
1
+ # Rattler - Ruby Tool for Language Recognition
2
+
3
+ Parsing for Ruby that's so easy it feels like cheating.
4
+
5
+ Rattler is a parser generator for Ruby based on parsing expression grammars.
6
+ Rattler's purpose is to make language design and recognition as simple and fun
7
+ as possible. To that end, the normal parsing expression grammar syntax is
8
+ extended with simple features to overcome many of the limitations of pure
9
+ PEG grammars.
10
+
11
+ A language syntax is specified in a grammar using the Rattler syntax. Parser
12
+ classes and modules can be generated statically using the "rtlr" command or
13
+ dynamically from strings.
14
+
15
+ ## Features
16
+
17
+ * Languages are described using readable PEG-based grammars
18
+ * Directly and indirectly left-recursive grammars can be used
19
+ * Whitespace can be specified in one place and skipped automatically
20
+ * Useful parse error messages are created automatically
21
+ * Custom parse error messages can be specified easily
22
+ * Generates efficient optimized pure-ruby parsers
23
+ * Works with MRI 1.8.7 and 1.9.2, JRuby and Rubinius
24
+
25
+ [Source](https://github.com/jarhart/rattler)
26
+
27
+ [API Docs](http://rubydoc.info/gems/rattler/0.5.0/frames)
@@ -0,0 +1,224 @@
1
+ To demonstrate how to get started using Rattler, we'll walk through writing the
2
+ ubiquitous arithmetic expression parser. This tutorial assumes that your are
3
+ familiar with parsing expression grammars. If you are not, you may wish to read
4
+ the [Wikipedia article](http://en.wikipedia.org/wiki/Parsing_expression_grammar)
5
+ on them to familiarize yourself.
6
+
7
+ ### Install Rattler
8
+
9
+ $ gem install rattler
10
+
11
+ ### Write a grammar
12
+
13
+ We'll start by writing just enough to describe the syntax of simple arithmetic
14
+ expressions in a way that automatically honors the standard order of operations.
15
+
16
+ We'll write the following and save it to a file called "`arithmetic.rtlr`":
17
+
18
+ require 'rattler'
19
+
20
+ parser ArithmeticParser < Rattler::Runtime::ExtendedPackratParser
21
+
22
+ %whitespace SPACE*
23
+
24
+ expr <- expr "+" term
25
+ / expr "-" term
26
+ / term
27
+
28
+ term <- term "*" primary
29
+ / term "/" primary
30
+ / primary
31
+
32
+ primary <- "(" expr ")"
33
+ / @("-"? DIGIT+ ("." DIGIT+)?)
34
+
35
+
36
+ If you have experience with recursive descent parsing, you might think the
37
+ above grammar won't work because recursive descent parsers can't handle left
38
+ recursion. Actually, there is an
39
+ [algorithm](http://www.cs.ucla.edu/~todd/research/pepm08.html) for packrat
40
+ parsing that handles left recursion. Rattler includes an implementation of that
41
+ algorithm, so left-recursive grammars are fine.
42
+
43
+ Our grammar starts with a [require](/jarhart/rattler/docs/grammar-heading/require)
44
+ statement to require the Rattler library. Any `require` statements in the
45
+ grammar heading are placed at the top of the generated parser.
46
+
47
+ Next we declare our parser class with a
48
+ [grammar declaration](/jarhart/rattler/docs/grammar-heading/grammar-declaration).
49
+ We extend the ExtendedPackratParser base class, which implements the packrat
50
+ parsing algorithm that supports left recursion.
51
+
52
+ After the declaring our parser class, we use the
53
+ [`%whitespace`](/jarhart/rattler/docs/extended-matching-syntax/whitespace-skipping)
54
+ directive to tell Rattler to generate a parser that automatically ignores any
55
+ whitespace characters. `SPACE` is a
56
+ [POSIX character class](/jarhart/rattler/docs/extended-matching-syntax/posix-character-classes)
57
+ that matches any whitespace character.
58
+
59
+ The rest of the grammar is a standard parsing expression grammar until we get
60
+ to the last line. The expression "`@("-"? DIGIT+ ("." DIGIT+)?)`" will match a
61
+ decimal number. The `@` is the
62
+ [Token Operator](/jarhart/rattler/docs/extended-matching-syntax/token-operator)
63
+ which causes the expression to be matched as a single string instead of
64
+ producing a parse tree. The `DIGIT` character class matches decimal digits.
65
+
66
+ ### Generate the parser
67
+
68
+ $ rtlr arithmetic.rtlr
69
+ arithmetic.rtlr -> arithmetic_parser.rb
70
+
71
+ This generates a file called `arithmetic_parser.rb`. We can test out the parser
72
+ by running the file as a script.
73
+
74
+ $ echo "1 + 2 / 3" | ruby arithmetic_parser.rb
75
+
76
+ This will print out the parse tree:
77
+
78
+ ["1", "+", ["2", "/", "3"]]
79
+
80
+ If you have GraphViz and the ruby-graphviz gem installed you can view the parse
81
+ tree with dotty:
82
+
83
+ $ echo "1 + 2 / 3" | ruby arithmetic_parser.rb --graphviz
84
+
85
+ You can use the `--help` option to see all of the available command-line
86
+ options:
87
+
88
+ $ arithmetic_parser.rb --help
89
+ Usage: arithmetic_parser.rb [filenames] [options]
90
+
91
+ -g, --graphviz Display the parse tree using GraphViz dotty
92
+ --jpg FILENAME Output the parse tree as a JPG file using GraphViz
93
+ --png FILENAME Output the parse tree as a PNG file using GraphViz
94
+ --svg FILENAME Output the parse tree as an SVG file using GraphViz
95
+ --pdf FILENAME Output the parse tree as a PDF file using GraphViz
96
+ --ps FILENAME Output the parse tree as a PS file using GraphViz
97
+ --ps2 FILENAME Output the parse tree as a PS2 file using GraphViz
98
+ --eps FILENAME Output the parse tree as an EPS file using GraphViz
99
+ -f, --file FILENAME Output the parse tree as a GraphViz DOT language file
100
+ -d, --dot Output the parse tree in the GraphViz DOT language
101
+
102
+ -h, --help Show this message
103
+
104
+ ### Iterate
105
+
106
+ Let's try parentheses to see if the parser groups the operations correctly:
107
+
108
+ $ echo "(1 + 2) / 3" | ruby arithmetic_parser.rb
109
+ [["(", ["1", "+", "2"], ")"], "/", "3"]
110
+
111
+ The grouping works, but we get the parentheses in the parse tree, which we
112
+ really don't need. Let's fix that by using the `~` operator to
113
+ [skip](/jarhart/rattler/docs/extended-matching-syntax/skip-operator) those:
114
+
115
+ Change the line
116
+
117
+ primary <- "(" expr ")"
118
+
119
+ To read:
120
+
121
+ primary <- ~"(" expr ~")"
122
+
123
+
124
+ And regenerate the parser, using `-f` to force overwriting the file.
125
+
126
+ $ rtlr arithmetic.rtlr -f
127
+ arithmetic.rtlr -> arithmetic_parser.rb
128
+
129
+ Now when we try parsing the expression with parentheses:
130
+
131
+ $ echo "(1 + 2) / 3" | ruby arithmetic_parser.rb
132
+ [["1", "+", "2"], "/", "3"]
133
+
134
+ We get the correct grouping without the superflous parentheses in the result.
135
+
136
+ We're still just getting arrays of tokens, and while that makes it easy to see
137
+ the parse tree in this case, it doesn't help much when we want to add semantics.
138
+ Each type of operation is matched by a separate sequence expression, but that
139
+ information is partially lost by making everything an array. We can add
140
+ [semantic attributes](/jarhart/rattler/docs/semantics/node-actions) to capture
141
+ the different operations.
142
+
143
+ We'll start by just using generic parse nodes and giving them mnemonic names.
144
+ We can also discard the matched operator tokens themselves at this point.
145
+
146
+ Change the `expr` and `term` rules to look like this:
147
+
148
+ expr <- expr ~"+" term <"ADD">
149
+ / expr ~"-" term <"SUB">
150
+ / term
151
+
152
+ term <- term ~"*" primary <"MUL">
153
+ / term ~"/" primary <"DIV">
154
+ / primary
155
+
156
+ Don't forget the `~` in front of the operators to omit them from the parse
157
+ results.
158
+
159
+ Using parse nodes like this makes it very easy to see the parse tree with
160
+ graphviz, especially with more complex expressions.
161
+
162
+ $ rtlr arithmetic.rtlr -f
163
+ arithmetic.rtlr -> arithmetic_parser.rb
164
+ $ echo "1+2*3/4-5+6-7*8/9" | ruby arithmetic_parser.rb -g
165
+
166
+ This feature is useful for debugging more complex grammars, but we can see that
167
+ our parser is parsing correctly, so let's finish by replacing the parse node
168
+ attributes with
169
+ [semantic actions](/jarhart/rattler/docs/semantics/semantic-actions) to perform
170
+ the arithmetic operations as it parses.
171
+
172
+ Change the `expr` and `term` rules to look like this:
173
+
174
+ expr <- expr ~"+" term {|a, b| a + b }
175
+ / expr ~"-" term {|a, b| a - b }
176
+ / term
177
+
178
+ term <- term ~"*" primary {|a, b| a * b }
179
+ / term ~"/" primary {|a, b| a / b }
180
+ / primary
181
+
182
+ Semantic actions look like ruby blocks and, for the most part, act like them
183
+ too. The parse results are bound to the parameters and the actions are
184
+ performed as soon as the parsing expression matches. The special `_` variable
185
+ can be used to refer to the entire parse results.
186
+
187
+ $ echo "1+2*3/4-5+6-7*8/9" | bundle exec ruby arithmetic_parser.rb
188
+ -2.7222222222222223
189
+
190
+ Success! Of course we could have accomplished the same thing with
191
+ "`eval ARGV.join`" but it's just a tutorial.
192
+
193
+ ### Finish
194
+
195
+ There's one last finishing touch to add. As it is now, the parser will accept
196
+ any input the starts with a valid expression no matter what comes after it.
197
+ We'll add a new rule at the top so that it only matches if the entire input is
198
+ a valid expression:
199
+
200
+ start <- expr EOF
201
+
202
+ The [`EOF`](/jarhart/rattler/docs/extended-matching-syntax/eof-symbol) symbol
203
+ matches only if there is no more input to parse.
204
+
205
+ Our final grammar looks like this:
206
+
207
+ require 'rattler'
208
+
209
+ parser ArithmeticParser < Rattler::Runtime::ExtendedPackratParser
210
+
211
+ %whitespace SPACE*
212
+
213
+ start <- expr EOF
214
+
215
+ expr <- expr ~"+" term {|a, b| a + b }
216
+ / expr ~"-" term {|a, b| a - b }
217
+ / term
218
+
219
+ term <- term ~"*" primary {|a, b| a * b }
220
+ / term ~"/" primary {|a, b| a / b }
221
+ / primary
222
+
223
+ primary <- ~"(" expr ~")"
224
+ / @("-"? DIGIT+ ("." DIGIT+)?) { _.to_f }
@@ -1,7 +1,8 @@
1
1
  Feature: --output option
2
2
 
3
3
  Use the --output (or -o) option to specify a different output file name, or
4
- "-" for STDOUT.
4
+ "-" for STDOUT. By default the output filename is the grammar or parser name
5
+ converted from camel-case to underscore.
5
6
 
6
7
  @command-line
7
8
  Scenario: Specify a different file name
@@ -1,7 +1,8 @@
1
- Feature: Parser Generator
1
+ Feature: rtlr
2
2
 
3
3
  The "rtlr" command is used to generate a grammar module or parser class from
4
- a Rattler grammar file.
4
+ a Rattler grammar file. The generated file is itself a parser script that
5
+ makes it easy to try out the parser.
5
6
 
6
7
  @command-line
7
8
  Scenario: Getting help
@@ -14,7 +15,6 @@ Feature: Parser Generator
14
15
  -d, --dest DIRECTORY Specify an explicit destination directory
15
16
  -o, --output FILENAME Specify a different output filename ("-" = STDOUT)
16
17
  -f, --force Force overwrite if the output file exists
17
- -s, --standalone Optimize for use as a standalone parser
18
18
  -n, --no-optimize Disable optimization
19
19
 
20
20
  -h, --help Show this message
@@ -27,7 +27,7 @@ Feature: Parser Generator
27
27
  grammar BinaryGrammar
28
28
  expr <- [01]*
29
29
  """
30
- When I run `rtlr binary.rtlr --standalone`
30
+ When I run `rtlr binary.rtlr`
31
31
  Then the output should contain "binary.rtlr -> binary_grammar.rb"
32
32
  And the file "binary_grammar.rb" should contain:
33
33
  """
@@ -41,13 +41,27 @@ Feature: Parser Generator
41
41
 
42
42
  # @private
43
43
  def match_expr #:nodoc:
44
- a0 = []
45
- while r = @scanner.scan(/[01]/)
46
- a0 << r
47
- end
48
- a0
44
+ apply :match_expr!
49
45
  end
50
46
 
47
+ # @private
48
+ def match_expr! #:nodoc:
49
+ begin
50
+ a0 = []
51
+ while r = @scanner.scan(/[01]/)
52
+ a0 << r
53
+ end
54
+ a0
55
+ end ||
56
+ fail { :expr }
57
+ end
58
+
59
+ end
60
+
61
+ if __FILE__ == $0
62
+ require 'rubygems'
63
+ require 'rattler'
64
+ Rattler::Util::GrammarCLI.run(BinaryGrammar)
51
65
  end
52
66
  """
53
67
 
@@ -59,7 +73,7 @@ Feature: Parser Generator
59
73
  parser BinaryParser < Rattler::Runtime::PackratParser
60
74
  expr <- [01]*
61
75
  """
62
- When I run `rtlr binary.rtlr --standalone`
76
+ When I run `rtlr binary.rtlr`
63
77
  Then the output should contain "binary.rtlr -> binary_parser.rb"
64
78
  And the file "binary_parser.rb" should contain:
65
79
  """
@@ -75,12 +89,26 @@ Feature: Parser Generator
75
89
 
76
90
  # @private
77
91
  def match_expr #:nodoc:
78
- a0 = []
79
- while r = @scanner.scan(/[01]/)
80
- a0 << r
81
- end
82
- a0
92
+ apply :match_expr!
83
93
  end
84
94
 
95
+ # @private
96
+ def match_expr! #:nodoc:
97
+ begin
98
+ a0 = []
99
+ while r = @scanner.scan(/[01]/)
100
+ a0 << r
101
+ end
102
+ a0
103
+ end ||
104
+ fail { :expr }
105
+ end
106
+
107
+ end
108
+
109
+ if __FILE__ == $0
110
+ require 'rubygems'
111
+ require 'rattler'
112
+ Rattler::Util::ParserCLI.run(BinaryParser)
85
113
  end
86
114
  """