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.
- data/README.rdoc +3 -175
- data/features/README.markdown +27 -0
- data/features/Tutorial.md +224 -0
- data/features/command_line/output_option.feature +2 -1
- data/features/command_line/{parser_generator.feature → rtlr.feature} +43 -15
- data/features/error_reporting/automatic_error_messages.feature +40 -0
- data/features/error_reporting/custom_error_messages.feature +28 -0
- data/features/examples/json_parser.markdown +88 -0
- data/features/{grammar → extended_matching_syntax}/back_reference.feature +5 -3
- data/features/{grammar → extended_matching_syntax}/e_symbol.feature +2 -2
- data/features/{grammar → extended_matching_syntax}/eof.feature +4 -3
- data/features/{grammar → extended_matching_syntax}/fail.feature +8 -6
- data/features/extended_matching_syntax/fragments.feature +29 -0
- data/features/extended_matching_syntax/include.feature +42 -0
- data/features/{grammar → extended_matching_syntax}/list_matching.feature +7 -6
- data/features/extended_matching_syntax/posix_class.feature +127 -0
- data/features/{grammar → extended_matching_syntax}/repeat.feature +29 -3
- data/features/{grammar → extended_matching_syntax}/skip_operator.feature +2 -1
- data/features/extended_matching_syntax/super.feature +24 -0
- data/features/{grammar → extended_matching_syntax}/token.feature +6 -5
- data/features/{grammar → extended_matching_syntax}/whitespace.feature +7 -6
- data/features/{grammar → extended_matching_syntax}/word_literal.feature +10 -6
- data/features/grammar_heading/explicit_start_rule.feature +20 -0
- data/features/grammar_heading/grammar_declaration.feature +60 -0
- data/features/grammar_heading/include.feature +19 -0
- data/features/grammar_heading/require.feature +27 -0
- data/features/{grammar → peg_syntax}/any_character.feature +1 -1
- data/features/peg_syntax/character_class.feature +25 -0
- data/features/{grammar → peg_syntax}/comments.feature +1 -1
- data/features/{grammar → peg_syntax}/literal.feature +5 -3
- data/features/{grammar → peg_syntax}/negative_lookahead.feature +5 -3
- data/features/peg_syntax/nonterminal.feature +46 -0
- data/features/peg_syntax/one_or_more.feature +59 -0
- data/features/{grammar → peg_syntax}/optional.feature +2 -2
- data/features/peg_syntax/ordered_choice.feature +24 -0
- data/features/{grammar → peg_syntax}/positive_lookahead.feature +6 -4
- data/features/peg_syntax/sequence.feature +23 -0
- data/features/{grammar → peg_syntax}/start_rule.feature +1 -1
- data/features/peg_syntax/zero_or_more.feature +59 -0
- data/features/{grammar → semantics}/labels.feature +0 -0
- data/features/{grammar → semantics}/negative_semantic_predicate.feature +30 -9
- data/features/{grammar → semantics}/node_action.feature +0 -0
- data/features/{grammar → semantics}/positive_semantic_predicate.feature +29 -8
- data/features/{grammar/symantic_action.feature → semantics/semantic_action.feature} +2 -2
- data/features/semantics/semantic_result.feature +86 -0
- data/features/{grammar → semantics}/side_effect.feature +33 -21
- data/features/step_definitions/cli_steps.rb +1 -1
- data/features/step_definitions/grammar_steps.rb +19 -5
- data/features/support/env.rb +5 -0
- data/lib/rattler.rb +21 -44
- data/lib/rattler/compiler.rb +69 -0
- data/lib/rattler/{grammar → compiler}/grammar_parser.rb +58 -24
- data/lib/rattler/compiler/metagrammar.rb +1570 -0
- data/lib/rattler/compiler/optimizer.rb +77 -0
- data/lib/rattler/{back_end → compiler}/optimizer/composite_reducing.rb +2 -2
- data/lib/rattler/{back_end → compiler}/optimizer/flatten_choice.rb +3 -12
- data/lib/rattler/{back_end → compiler}/optimizer/flatten_sequence.rb +4 -16
- data/lib/rattler/{back_end → compiler}/optimizer/flattening.rb +2 -2
- data/lib/rattler/compiler/optimizer/inline_regular_rules.rb +24 -0
- data/lib/rattler/{back_end → compiler}/optimizer/join_match_capturing_sequence.rb +16 -14
- data/lib/rattler/{back_end → compiler}/optimizer/join_match_choice.rb +4 -13
- data/lib/rattler/{back_end → compiler}/optimizer/join_match_matching_sequence.rb +4 -13
- data/lib/rattler/compiler/optimizer/join_match_sequence.rb +7 -0
- data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_bare_match.rb +3 -12
- data/lib/rattler/compiler/optimizer/join_predicate_match.rb +7 -0
- data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_nested_match.rb +4 -13
- data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_or_bare_match.rb +3 -12
- data/lib/rattler/compiler/optimizer/join_predicate_or_match.rb +7 -0
- data/lib/rattler/{back_end → compiler}/optimizer/join_predicate_or_nested_match.rb +4 -13
- data/lib/rattler/{back_end → compiler}/optimizer/match_joining.rb +2 -2
- data/lib/rattler/{back_end → compiler}/optimizer/optimization.rb +12 -34
- data/lib/rattler/compiler/optimizer/optimization_context.rb +83 -0
- data/lib/rattler/{back_end → compiler}/optimizer/optimization_sequence.rb +3 -11
- data/lib/rattler/compiler/optimizer/optimizations.rb +27 -0
- data/lib/rattler/{back_end → compiler}/optimizer/optimize_children.rb +6 -14
- data/lib/rattler/{back_end → compiler}/optimizer/reduce_repeat_match.rb +4 -13
- data/lib/rattler/compiler/optimizer/remove_meaningless_wrapper.rb +22 -0
- data/lib/rattler/{back_end → compiler}/optimizer/simplify_redundant_repeat.rb +4 -13
- data/lib/rattler/{back_end → compiler}/optimizer/simplify_token_match.rb +4 -13
- data/lib/rattler/compiler/parser_generator.rb +108 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/apply_generator.rb +7 -21
- data/lib/rattler/{back_end → compiler}/parser_generator/assert_generator.rb +11 -19
- data/lib/rattler/compiler/parser_generator/attributed_sequence_generator.rb +37 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/back_reference_generator.rb +10 -10
- data/lib/rattler/{back_end → compiler}/parser_generator/choice_generator.rb +10 -22
- data/lib/rattler/{back_end → compiler}/parser_generator/delegating_generator.rb +2 -2
- data/lib/rattler/{back_end → compiler}/parser_generator/disallow_generator.rb +11 -19
- data/lib/rattler/{back_end → compiler}/parser_generator/e_symbol_generator.rb +2 -10
- data/lib/rattler/{back_end → compiler}/parser_generator/eof_generator.rb +2 -10
- data/lib/rattler/{back_end → compiler}/parser_generator/expr_generator.rb +9 -35
- data/lib/rattler/{back_end → compiler}/parser_generator/fail_generator.rb +7 -3
- data/lib/rattler/{back_end → compiler}/parser_generator/gen_method_names.rb +3 -5
- data/lib/rattler/{back_end → compiler}/parser_generator/general_list_generator.rb +6 -18
- data/lib/rattler/{back_end → compiler}/parser_generator/general_repeat_generator.rb +16 -22
- data/lib/rattler/{back_end/parser_generator/rule_set_generator.rb → compiler/parser_generator/grammar_generator.rb} +24 -33
- data/lib/rattler/compiler/parser_generator/group_match.rb +33 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/group_match_generator.rb +4 -17
- data/lib/rattler/compiler/parser_generator/label_generator.rb +37 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/list0_generating.rb +5 -5
- data/lib/rattler/{back_end → compiler}/parser_generator/list1_generating.rb +3 -3
- data/lib/rattler/{back_end → compiler}/parser_generator/list_generator.rb +2 -2
- data/lib/rattler/{back_end → compiler}/parser_generator/match_generator.rb +10 -10
- data/lib/rattler/{back_end → compiler}/parser_generator/nested.rb +2 -2
- data/lib/rattler/compiler/parser_generator/node_action_generator.rb +49 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/one_or_more_generating.rb +3 -3
- data/lib/rattler/{back_end → compiler}/parser_generator/optional_generating.rb +6 -22
- data/lib/rattler/compiler/parser_generator/predicate_propogating.rb +24 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/repeat_generator.rb +2 -2
- data/lib/rattler/compiler/parser_generator/rule_generator.rb +66 -0
- data/lib/rattler/compiler/parser_generator/rule_set_generator.rb +33 -0
- data/lib/rattler/compiler/parser_generator/semantic_action_generator.rb +58 -0
- data/lib/rattler/compiler/parser_generator/sequence_generating.rb +138 -0
- data/lib/rattler/compiler/parser_generator/sequence_generator.rb +57 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/skip_generator.rb +4 -18
- data/lib/rattler/compiler/parser_generator/skip_propogating.rb +16 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/sub_generating.rb +19 -11
- data/lib/rattler/compiler/parser_generator/super_generator.rb +54 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/token_generator.rb +3 -3
- data/lib/rattler/compiler/parser_generator/token_propogating.rb +10 -0
- data/lib/rattler/{back_end → compiler}/parser_generator/top_level.rb +2 -2
- data/lib/rattler/{back_end → compiler}/parser_generator/zero_or_more_generating.rb +5 -5
- data/lib/rattler/compiler/rattler.rtlr +201 -0
- data/lib/rattler/{back_end → compiler}/ruby_generator.rb +16 -25
- data/lib/rattler/parsers.rb +12 -33
- data/lib/rattler/parsers/action_code.rb +25 -16
- data/lib/rattler/{grammar → parsers}/analysis.rb +32 -11
- data/lib/rattler/parsers/apply.rb +10 -19
- data/lib/rattler/parsers/assert.rb +4 -14
- data/lib/rattler/parsers/atomic.rb +3 -10
- data/lib/rattler/parsers/attributed_sequence.rb +50 -0
- data/lib/rattler/parsers/back_reference.rb +19 -14
- data/lib/rattler/parsers/choice.rb +11 -12
- data/lib/rattler/parsers/combinator_parser.rb +15 -7
- data/lib/rattler/parsers/combining.rb +15 -9
- data/lib/rattler/parsers/disallow.rb +5 -12
- data/lib/rattler/parsers/e_symbol.rb +5 -14
- data/lib/rattler/parsers/eof.rb +10 -15
- data/lib/rattler/parsers/fail.rb +16 -26
- data/lib/rattler/{grammar → parsers}/grammar.rb +15 -20
- data/lib/rattler/parsers/label.rb +10 -16
- data/lib/rattler/parsers/list_parser.rb +14 -14
- data/lib/rattler/parsers/match.rb +5 -17
- data/lib/rattler/parsers/node_action.rb +72 -0
- data/lib/rattler/parsers/node_code.rb +47 -30
- data/lib/rattler/parsers/parser.rb +63 -32
- data/lib/rattler/parsers/parser_scope.rb +88 -0
- data/lib/rattler/parsers/predicate.rb +12 -10
- data/lib/rattler/parsers/repeat.rb +15 -8
- data/lib/rattler/parsers/rule.rb +8 -23
- data/lib/rattler/parsers/rule_set.rb +67 -12
- data/lib/rattler/parsers/semantic.rb +36 -0
- data/lib/rattler/parsers/semantic_action.rb +39 -0
- data/lib/rattler/parsers/sequence.rb +25 -40
- data/lib/rattler/parsers/sequencing.rb +40 -0
- data/lib/rattler/parsers/skip.rb +11 -12
- data/lib/rattler/parsers/super.rb +33 -0
- data/lib/rattler/parsers/token.rb +3 -13
- data/lib/rattler/rake_task.rb +50 -0
- data/lib/rattler/runner.rb +19 -22
- data/lib/rattler/runtime.rb +0 -10
- data/lib/rattler/runtime/extended_packrat_parser.rb +40 -45
- data/lib/rattler/runtime/packrat_parser.rb +17 -31
- data/lib/rattler/runtime/parse_failure.rb +16 -26
- data/lib/rattler/runtime/parse_node.rb +8 -18
- data/lib/rattler/runtime/parser.rb +6 -18
- data/lib/rattler/runtime/parser_helper.rb +3 -10
- data/lib/rattler/runtime/recursive_descent_parser.rb +26 -23
- data/lib/rattler/runtime/syntax_error.rb +0 -10
- data/lib/rattler/util.rb +2 -6
- data/lib/rattler/util/grammar_cli.rb +19 -0
- data/lib/rattler/util/graphviz.rb +6 -17
- data/lib/rattler/util/graphviz/digraph_builder.rb +10 -17
- data/lib/rattler/util/graphviz/node_builder.rb +45 -31
- data/lib/rattler/util/line_counter.rb +11 -20
- data/lib/rattler/util/node.rb +52 -30
- data/lib/rattler/util/parser_cli.rb +84 -0
- data/lib/rattler/util/parser_spec_helper.rb +8 -12
- data/spec/rattler/compiler/assert_compiler_examples.rb +284 -0
- data/spec/rattler/compiler/attributed_sequence_compiler_examples.rb +154 -0
- data/spec/rattler/compiler/disallow_compiler_examples.rb +293 -0
- data/spec/rattler/compiler/grammar_parser_spec.rb +700 -0
- data/spec/rattler/{back_end → compiler}/optimizer/flatten_choice_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/flatten_sequence_spec.rb +1 -1
- data/spec/rattler/compiler/optimizer/inline_regular_rules_spec.rb +50 -0
- data/spec/rattler/{back_end → compiler}/optimizer/join_match_capturing_sequence_spec.rb +106 -22
- data/spec/rattler/{back_end → compiler}/optimizer/join_match_choice_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/join_match_matching_sequence_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_bare_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_nested_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_or_bare_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/join_predicate_or_nested_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/reduce_repeat_match_spec.rb +1 -1
- data/spec/rattler/compiler/optimizer/remove_meaningless_wrapper_spec.rb +82 -0
- data/spec/rattler/{back_end → compiler}/optimizer/simplify_redundant_repeat_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer/simplify_token_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/optimizer_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/parser_generator/apply_generator_spec.rb +1 -39
- data/spec/rattler/{back_end → compiler}/parser_generator/assert_generator_spec.rb +1 -55
- data/spec/rattler/compiler/parser_generator/attributed_sequence_generator_spec.rb +699 -0
- data/spec/rattler/{back_end → compiler}/parser_generator/back_reference_generator_spec.rb +3 -56
- data/spec/rattler/{back_end → compiler}/parser_generator/choice_generator_spec.rb +1 -63
- data/spec/rattler/{back_end → compiler}/parser_generator/disallow_generator_spec.rb +1 -55
- data/spec/rattler/{back_end → compiler}/parser_generator/e_symbol_generator_spec.rb +1 -39
- data/spec/rattler/{back_end → compiler}/parser_generator/eof_generator_spec.rb +1 -39
- data/spec/rattler/{back_end → compiler}/parser_generator/fail_generator_spec.rb +94 -23
- data/spec/rattler/compiler/parser_generator/grammar_generator_spec.rb +98 -0
- data/spec/rattler/compiler/parser_generator/group_match_generator_spec.rb +67 -0
- data/spec/rattler/{back_end → compiler}/parser_generator/group_match_spec.rb +1 -1
- data/spec/rattler/{back_end → compiler}/parser_generator/label_generator_spec.rb +1 -55
- data/spec/rattler/{back_end → compiler}/parser_generator/list0_generator_examples.rb +0 -88
- data/spec/rattler/{back_end → compiler}/parser_generator/list1_generator_examples.rb +0 -88
- data/spec/rattler/{back_end → compiler}/parser_generator/list_generator_spec.rb +1 -227
- data/spec/rattler/{back_end → compiler}/parser_generator/match_generator_spec.rb +1 -55
- data/spec/rattler/compiler/parser_generator/node_action_generator_spec.rb +135 -0
- data/spec/rattler/{back_end → compiler}/parser_generator/one_or_more_generator_examples.rb +0 -74
- data/spec/rattler/{back_end → compiler}/parser_generator/optional_generator_examples.rb +0 -62
- data/spec/rattler/{back_end → compiler}/parser_generator/repeat_generator_spec.rb +66 -1
- data/spec/rattler/{back_end → compiler}/parser_generator/rule_generator_spec.rb +3 -2
- data/spec/rattler/{back_end → compiler}/parser_generator/rule_set_generator_spec.rb +9 -27
- data/spec/rattler/compiler/parser_generator/semantic_action_generator_spec.rb +437 -0
- data/spec/rattler/{back_end → compiler}/parser_generator/sequence_generator_spec.rb +234 -68
- data/spec/rattler/{back_end → compiler}/parser_generator/skip_generator_spec.rb +1 -55
- data/spec/rattler/compiler/parser_generator/super_generator_spec.rb +93 -0
- data/spec/rattler/{back_end → compiler}/parser_generator/token_generator_spec.rb +1 -55
- data/spec/rattler/{back_end → compiler}/parser_generator/zero_or_more_generator_examples.rb +0 -74
- data/spec/rattler/{back_end → compiler}/ruby_generator_spec.rb +13 -13
- data/spec/rattler/compiler/semantic_action_compiler_examples.rb +57 -0
- data/spec/rattler/{back_end → compiler}/shared_compiler_examples.rb +111 -140
- data/spec/rattler/{back_end → compiler}/skip_compiler_examples.rb +60 -57
- data/spec/rattler/{back_end → compiler}/token_compiler_examples.rb +99 -104
- data/spec/rattler/compiler_spec.rb +67 -0
- data/spec/rattler/parsers/action_code_spec.rb +34 -18
- data/spec/rattler/{grammar → parsers}/analysis_spec.rb +13 -67
- data/spec/rattler/parsers/apply_spec.rb +6 -0
- data/spec/rattler/parsers/assert_spec.rb +38 -2
- data/spec/rattler/parsers/attributed_sequence_spec.rb +204 -0
- data/spec/rattler/parsers/back_reference_spec.rb +6 -0
- data/spec/rattler/parsers/choice_spec.rb +38 -1
- data/spec/rattler/parsers/combinator_parser_spec.rb +2 -1
- data/spec/rattler/parsers/disallow_spec.rb +38 -2
- data/spec/rattler/parsers/e_symbol_spec.rb +6 -0
- data/spec/rattler/parsers/eof_spec.rb +6 -0
- data/spec/rattler/parsers/fail_spec.rb +6 -0
- data/spec/rattler/{grammar → parsers}/grammar_spec.rb +10 -15
- data/spec/rattler/parsers/label_spec.rb +30 -0
- data/spec/rattler/parsers/list_parser_spec.rb +31 -2
- data/spec/rattler/parsers/match_spec.rb +6 -0
- data/spec/rattler/parsers/node_action_spec.rb +121 -0
- data/spec/rattler/parsers/parser_scope_spec.rb +105 -0
- data/spec/rattler/parsers/repeat_spec.rb +56 -0
- data/spec/rattler/parsers/rule_set_spec.rb +42 -0
- data/spec/rattler/parsers/semantic_action_spec.rb +89 -0
- data/spec/rattler/parsers/sequence_spec.rb +156 -12
- data/spec/rattler/parsers/skip_spec.rb +21 -0
- data/spec/rattler/parsers/super_spec.rb +45 -0
- data/spec/rattler/parsers/token_spec.rb +33 -14
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +10 -8
- data/spec/rattler/runtime/recursive_descent_parser_spec.rb +26 -0
- data/spec/rattler/runtime/shared_parser_examples.rb +22 -16
- data/spec/rattler/util/graphviz/node_builder_spec.rb +33 -17
- data/spec/rattler/util/line_counter_spec.rb +21 -21
- data/spec/rattler/util/node_spec.rb +62 -0
- data/spec/rattler_spec.rb +7 -41
- data/spec/spec_helper.rb +1 -2
- data/spec/support/combinator_parser_spec_helper.rb +1 -1
- data/spec/support/compiler_spec_helper.rb +0 -4
- data/spec/support/parser_generator_spec_helper.rb +7 -7
- data/spec/support/runtime_parser_spec_helper.rb +57 -3
- metadata +447 -303
- data/features/grammar/character_class.feature +0 -20
- data/features/grammar/nonterminal.feature +0 -24
- data/features/grammar/one_or_more.feature +0 -34
- data/features/grammar/ordered_choice.feature +0 -21
- data/features/grammar/posix_class.feature +0 -70
- data/features/grammar/sequence.feature +0 -20
- data/features/grammar/zero_or_more.feature +0 -34
- data/lib/rattler/back_end.rb +0 -22
- data/lib/rattler/back_end/compiler.rb +0 -128
- data/lib/rattler/back_end/optimizer.rb +0 -101
- data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +0 -46
- data/lib/rattler/back_end/optimizer/join_match_sequence.rb +0 -17
- data/lib/rattler/back_end/optimizer/join_predicate_match.rb +0 -17
- data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +0 -17
- data/lib/rattler/back_end/optimizer/optimization_context.rb +0 -72
- data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +0 -32
- data/lib/rattler/back_end/optimizer/specialize_repeat.rb +0 -40
- data/lib/rattler/back_end/parser_generator.rb +0 -113
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +0 -45
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +0 -45
- data/lib/rattler/back_end/parser_generator/group_match.rb +0 -26
- data/lib/rattler/back_end/parser_generator/label_generator.rb +0 -64
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +0 -24
- data/lib/rattler/back_end/parser_generator/rule_generator.rb +0 -53
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +0 -190
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +0 -16
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +0 -10
- data/lib/rattler/grammar.rb +0 -43
- data/lib/rattler/grammar/grammar_dsl.rb +0 -51
- data/lib/rattler/grammar/metagrammar.rb +0 -990
- data/lib/rattler/grammar/rattler.rtlr +0 -183
- data/lib/rattler/parsers/assert_code.rb +0 -31
- data/lib/rattler/parsers/direct_action.rb +0 -85
- data/lib/rattler/parsers/disallow_code.rb +0 -31
- data/lib/rattler/parsers/dispatch_action.rb +0 -121
- data/lib/rattler/parsers/effect_code.rb +0 -31
- data/lib/rattler/parsers/parser_dsl.rb +0 -414
- data/lib/rattler/parsers/semantic_assert.rb +0 -19
- data/lib/rattler/parsers/semantic_disallow.rb +0 -19
- data/lib/rattler/parsers/side_effect.rb +0 -19
- data/spec/rattler/back_end/assert_compiler_examples.rb +0 -187
- data/spec/rattler/back_end/compiler_spec.rb +0 -43
- data/spec/rattler/back_end/direct_action_compiler_examples.rb +0 -227
- data/spec/rattler/back_end/disallow_compiler_examples.rb +0 -187
- data/spec/rattler/back_end/dispatch_action_compiler_examples.rb +0 -225
- data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +0 -80
- data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +0 -204
- data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +0 -204
- data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +0 -185
- data/spec/rattler/back_end/semantic_assert_compiler_examples.rb +0 -152
- data/spec/rattler/back_end/semantic_disallow_compiler_examples.rb +0 -152
- data/spec/rattler/back_end/side_effect_compiler_examples.rb +0 -227
- data/spec/rattler/grammar/grammar_parser_spec.rb +0 -626
- data/spec/rattler/parsers/direct_action_spec.rb +0 -224
- data/spec/rattler/parsers/dispatch_action_spec.rb +0 -209
- data/spec/rattler/parsers/node_code_spec.rb +0 -59
- data/spec/rattler/parsers/parser_dsl_spec.rb +0 -334
- data/spec/rattler/parsers/semantic_assert_spec.rb +0 -83
- data/spec/rattler/parsers/semantic_disallow_spec.rb +0 -83
- data/spec/rattler/parsers/side_effect_spec.rb +0 -214
data/README.rdoc
CHANGED
@@ -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
|
-
|
16
|
-
classes and modules can be generated statically using the "rtlr" command or
|
17
|
-
dynamically from strings.
|
15
|
+
=== Documentation
|
18
16
|
|
19
|
-
|
17
|
+
For the best documentation see the {cucumber features}[http://www.relishapp.com/jarhart/rattler]
|
20
18
|
|
21
|
-
{
|
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:
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
"""
|