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
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'rattler/util'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module Rattler::Util
|
5
|
+
|
6
|
+
# +ParserCLI+ defines a command line interface for generated parsers.
|
7
|
+
class ParserCLI
|
8
|
+
|
9
|
+
# The supported graph file formats
|
10
|
+
@@graph_formats = %w{jpg png svg pdf ps ps2 eps}
|
11
|
+
|
12
|
+
# Create and run the command line interface for the given parser class
|
13
|
+
#
|
14
|
+
# @param (see #initialize)
|
15
|
+
def self.run(parser_class)
|
16
|
+
self.new(parser_class).run
|
17
|
+
end
|
18
|
+
|
19
|
+
# Create a new command line interface for the given parser class
|
20
|
+
#
|
21
|
+
# @param [Class] parser_class the parser class to run the command line
|
22
|
+
# interface for
|
23
|
+
def initialize(parser_class)
|
24
|
+
@parser_class = parser_class
|
25
|
+
|
26
|
+
OptionParser.new do |opts|
|
27
|
+
|
28
|
+
opts.banner = "Usage: #{File.basename($0)} [filenames] [options]"
|
29
|
+
|
30
|
+
opts.separator ''
|
31
|
+
|
32
|
+
opts.on '-g', '--graphviz',
|
33
|
+
'Display the parse tree using GraphViz dotty' do |g|
|
34
|
+
@graphviz = {:dot => '|dotty'}
|
35
|
+
end
|
36
|
+
|
37
|
+
@@graph_formats.each do |format|
|
38
|
+
a = 'aefhilmnorsx'.include?(format[0]) ? 'an' : 'a'
|
39
|
+
desc = "#{format.upcase} file"
|
40
|
+
opts.on "--#{format} FILENAME",
|
41
|
+
"Output the parse tree as #{a} #{desc} using GraphViz" do |f|
|
42
|
+
@graphviz = {format => f}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on '-f', '--file FILENAME',
|
47
|
+
'Output the parse tree as a GraphViz DOT language file' do |file|
|
48
|
+
@graphviz = {:dot => file}
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on '-d', '--dot',
|
52
|
+
'Output the parse tree in the GraphViz DOT language' do |d|
|
53
|
+
@graphviz = {:dot => nil}
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.separator ''
|
57
|
+
|
58
|
+
opts.on_tail '-h', '--help', 'Show this message' do
|
59
|
+
abort "#{opts}\n"
|
60
|
+
end
|
61
|
+
end.parse!(ARGV)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Run the command line interface
|
65
|
+
def run
|
66
|
+
show_result @parser_class.parse!(ARGF.read)
|
67
|
+
rescue Rattler::Runtime::SyntaxError => e
|
68
|
+
puts e
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# @private
|
74
|
+
def show_result(result) #:nodoc:
|
75
|
+
if @graphviz
|
76
|
+
GraphViz.digraph(result).output(@graphviz)
|
77
|
+
else
|
78
|
+
require 'pp'
|
79
|
+
pp result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -1,34 +1,28 @@
|
|
1
|
-
#
|
2
|
-
# = rattler/util/parser_spec_helper.rb
|
3
|
-
#
|
4
|
-
# Author:: Jason Arhart
|
5
|
-
# Documentation:: Author
|
6
|
-
#
|
7
1
|
require 'rattler/util'
|
8
2
|
|
9
3
|
module Rattler::Util
|
10
|
-
|
4
|
+
|
11
5
|
# +ParserSpecHelper+ defines a fluent interface for writing RSpec examples
|
12
6
|
# for parsers.
|
13
7
|
#
|
14
8
|
# @example
|
15
9
|
#
|
16
|
-
# require '
|
10
|
+
# require 'my_awesome_language/my_awesome_parser'
|
17
11
|
# require 'rattler/util/parser_spec_helper'
|
18
12
|
#
|
19
|
-
# describe
|
13
|
+
# describe MyAwesomeLanguage::MyAwesomeParser do
|
20
14
|
# include Rattler::Util::ParserSpecHelper
|
21
15
|
#
|
22
16
|
# describe '#match(:var_name)' do
|
23
17
|
# it 'recognizes variable names' do
|
24
18
|
# matching(' fooBar ').as(:var_name).should result_in('fooBar').at(7)
|
25
|
-
#
|
19
|
+
# end
|
20
|
+
# it 'rejects non-variables' do
|
21
|
+
# matching(' 42 ').as(:var_name).should fail.with_message('variable name expected')
|
26
22
|
# end
|
27
23
|
# end
|
28
24
|
# end
|
29
25
|
#
|
30
|
-
# @author Jason Arhart
|
31
|
-
#
|
32
26
|
module ParserSpecHelper
|
33
27
|
|
34
28
|
# Return a parse result to be matched using #result_in or #fail
|
@@ -49,6 +43,8 @@ module Rattler::Util
|
|
49
43
|
Matching.new(parser(source))
|
50
44
|
end
|
51
45
|
|
46
|
+
private
|
47
|
+
|
52
48
|
def parser(source)
|
53
49
|
(self.respond_to?(:parser_class) ? parser_class : described_class).new(source)
|
54
50
|
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
shared_examples_for 'a compiled parser with an assert' do
|
4
|
+
include CompilerSpecHelper
|
5
|
+
include RuntimeParserSpecHelper
|
6
|
+
|
7
|
+
subject { compiled_parser }
|
8
|
+
|
9
|
+
let(:reference_parser) { combinator_parser grammar }
|
10
|
+
|
11
|
+
let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
|
12
|
+
|
13
|
+
context 'with a nested match rule' do
|
14
|
+
let(:rules) { [
|
15
|
+
rule(:word) { assert(/\w+/) }
|
16
|
+
] }
|
17
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
18
|
+
it { should parse(' ').failing.like reference_parser }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a nested eof rule' do
|
22
|
+
let(:rules) { [
|
23
|
+
rule(:foo) { assert(eof) }
|
24
|
+
] }
|
25
|
+
it { should parse('').succeeding.like reference_parser }
|
26
|
+
it { should parse('foo').from(3).succeeding.like reference_parser }
|
27
|
+
it { should parse('foo').failing.like reference_parser }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a nested "E" symbol rule' do
|
31
|
+
let(:rules) { [
|
32
|
+
rule(:foo) { assert(e) }
|
33
|
+
] }
|
34
|
+
it { should parse('').succeeding.like reference_parser }
|
35
|
+
it { should parse('foo').succeeding.like reference_parser }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with a nested choice rule' do
|
39
|
+
let(:rules) { [
|
40
|
+
rule(:word) { assert(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/)) }
|
41
|
+
] }
|
42
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
43
|
+
it { should parse(' ').failing.like reference_parser }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with a nested sequence rule' do
|
47
|
+
let(:rules) { [
|
48
|
+
rule(:word) { assert(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)) }
|
49
|
+
] }
|
50
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
51
|
+
it { should parse(' ').failing.like reference_parser }
|
52
|
+
|
53
|
+
context 'with a semantic action' do
|
54
|
+
|
55
|
+
context 'when the expression has parameters' do
|
56
|
+
let(:rules) { [
|
57
|
+
rule(:a) { assert(match(/\d+/) >> semantic_action('|a| a.to_i * 2')) }
|
58
|
+
] }
|
59
|
+
it { should parse('451a').succeeding.like reference_parser }
|
60
|
+
it { should parse(' ').failing.like reference_parser }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when the expression uses "_"' do
|
64
|
+
|
65
|
+
context 'given a single capture' do
|
66
|
+
let(:rules) { [
|
67
|
+
rule(:a) { assert(match(/\d+/) >> semantic_action('_ * 2')) }
|
68
|
+
] }
|
69
|
+
it { should parse('451a').succeeding.like reference_parser }
|
70
|
+
it { should parse(' ').failing.like reference_parser }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'given multiple captures' do
|
74
|
+
let(:rules) { [
|
75
|
+
rule(:a) { assert(
|
76
|
+
(match(/\d+/) & skip(/\s+/) & match(/\d+/)) >> semantic_action('_')
|
77
|
+
) }
|
78
|
+
] }
|
79
|
+
it { should parse('23 42').succeeding.like reference_parser }
|
80
|
+
it { should parse(' ').failing.like reference_parser }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when the expression uses labels' do
|
85
|
+
let(:rules) { [
|
86
|
+
rule(:a) { assert(label(:a, /\d+/) >> semantic_action('a.to_i * 2')) }
|
87
|
+
] }
|
88
|
+
it { should parse('451a').succeeding.like reference_parser }
|
89
|
+
it { should parse(' ').failing.like reference_parser }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'with a nested optional rule' do
|
95
|
+
let(:rules) { [
|
96
|
+
rule(:word) { assert(match(/\w+/).optional) }
|
97
|
+
] }
|
98
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
99
|
+
it { should parse(' ').succeeding.like reference_parser }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with a nested zero-or-more rule' do
|
103
|
+
let(:rules) { [
|
104
|
+
rule(:word) { assert(match(/\w/).zero_or_more) }
|
105
|
+
] }
|
106
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
107
|
+
it { should parse(' ').succeeding.like reference_parser }
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with a nested one-or-more rule' do
|
111
|
+
let(:rules) { [
|
112
|
+
rule(:word) { assert(match(/\w/).one_or_more) }
|
113
|
+
] }
|
114
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
115
|
+
it { should parse(' ').failing.like reference_parser }
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'with a nested repeat rule' do
|
119
|
+
let(:rules) { [
|
120
|
+
rule(:word) { assert(match(/\w/).repeat(2, nil)) }
|
121
|
+
] }
|
122
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
123
|
+
it { should parse('a ').failing.like reference_parser }
|
124
|
+
|
125
|
+
context 'with zero-or-more bounds' do
|
126
|
+
let(:rules) { [
|
127
|
+
rule(:word) { assert(match(/\w/).repeat(0, nil)) }
|
128
|
+
] }
|
129
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
130
|
+
it { should parse(' ').succeeding.like reference_parser }
|
131
|
+
|
132
|
+
context 'with an upper bound' do
|
133
|
+
let(:rules) { [
|
134
|
+
rule(:word) { assert(match(/\w/).repeat(0, 2)) }
|
135
|
+
] }
|
136
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
137
|
+
it { should parse(' ').succeeding.like reference_parser }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'with one-or-more bounds' do
|
142
|
+
let(:rules) { [
|
143
|
+
rule(:word) { assert(match(/\w/).repeat(1, nil)) }
|
144
|
+
] }
|
145
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
146
|
+
it { should parse(' ').failing.like reference_parser }
|
147
|
+
|
148
|
+
context 'with an upper bound' do
|
149
|
+
let(:rules) { [
|
150
|
+
rule(:word) { assert(match(/\w/).repeat(1, 2)) }
|
151
|
+
] }
|
152
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
153
|
+
it { should parse(' ').failing.like reference_parser }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with a nested list rule' do
|
159
|
+
let(:rules) { [
|
160
|
+
rule(:foo) { assert(match(/\w+/).list(match(/[,;]/), 2, nil)) }
|
161
|
+
] }
|
162
|
+
it { should parse('foo ').failing.like reference_parser }
|
163
|
+
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
164
|
+
|
165
|
+
context 'with an upper bound' do
|
166
|
+
let(:rules) { [
|
167
|
+
rule(:foo) { assert(match(/\w+/).list(match(/[,;]/), 2, 4)) }
|
168
|
+
] }
|
169
|
+
it { should parse('foo ').failing.like reference_parser }
|
170
|
+
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'with a non-capturing parser' do
|
174
|
+
let(:rules) { [
|
175
|
+
rule(:foo) { assert(skip(/\w+/).list(match(/[,;]/), 2, nil)) }
|
176
|
+
] }
|
177
|
+
it { should parse('foo ').failing.like reference_parser }
|
178
|
+
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
179
|
+
|
180
|
+
context 'with an upper bound' do
|
181
|
+
let(:rules) { [
|
182
|
+
rule(:foo) { assert skip(/\w+/).list(match(/[,;]/), 2, 4) }
|
183
|
+
] }
|
184
|
+
it { should parse('foo ').failing.like reference_parser }
|
185
|
+
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'with a nested apply rule' do
|
191
|
+
let(:rules) { [
|
192
|
+
rule(:foo) { match(:word) },
|
193
|
+
rule(:word) { assert(/\w+/) }
|
194
|
+
] }
|
195
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
196
|
+
it { should parse(' ').failing.like reference_parser }
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'with a nested semantic action' do
|
200
|
+
let(:rules) { [
|
201
|
+
rule(:a) { assert(semantic_action('42')) }
|
202
|
+
] }
|
203
|
+
it { should parse('anything').succeeding.like reference_parser }
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with a nested attributed sequence' do
|
207
|
+
|
208
|
+
context 'with a single capture and a semantic action' do
|
209
|
+
|
210
|
+
context 'when the action uses a parameter' do
|
211
|
+
let(:rules) { [
|
212
|
+
rule(:a) { assert(match(/\d+/) >> semantic_action('|a| a.to_i')) }
|
213
|
+
] }
|
214
|
+
it { should parse('451a').succeeding.like reference_parser }
|
215
|
+
it { should parse(' ').failing.like reference_parser }
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'when the action uses "_"' do
|
219
|
+
let(:rules) { [
|
220
|
+
rule(:a) { assert(match(/\d+/) >> semantic_action('_.to_i')) }
|
221
|
+
] }
|
222
|
+
it { should parse('451a').succeeding.like reference_parser }
|
223
|
+
it { should parse(' ').failing.like reference_parser }
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'with multiple captures and a semantic action' do
|
228
|
+
|
229
|
+
context 'when the action uses parameters' do
|
230
|
+
let(:rules) { [
|
231
|
+
rule(:a) { assert(
|
232
|
+
(match(/[a-z]+/) & match(/\d+/)) >> semantic_action('|a,b| b+a')
|
233
|
+
) }
|
234
|
+
] }
|
235
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
236
|
+
it { should parse(' ').failing.like reference_parser }
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'when the action uses "_"' do
|
240
|
+
let(:rules) { [
|
241
|
+
rule(:a) { assert(
|
242
|
+
(match(/[a-z]+/) & match(/\d+/)) >> semantic_action('_.reverse')
|
243
|
+
) }
|
244
|
+
] }
|
245
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
246
|
+
it { should parse(' ').failing.like reference_parser }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'with a single labeled capture and a semantic action' do
|
251
|
+
let(:rules) { [
|
252
|
+
rule(:e) { assert(label(:a, /\d+/) >> semantic_action('a.to_i')) }
|
253
|
+
] }
|
254
|
+
it { should parse('451a').succeeding.like reference_parser }
|
255
|
+
it { should parse(' ').failing.like reference_parser }
|
256
|
+
end
|
257
|
+
|
258
|
+
context 'with multiple labeled captures and a semantic action' do
|
259
|
+
let(:rules) { [
|
260
|
+
rule(:e) { assert(
|
261
|
+
(label(:a, /[a-z]+/) & label(:b, /\d+/)) >> semantic_action('b + a')
|
262
|
+
) }
|
263
|
+
] }
|
264
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
265
|
+
it { should parse(' ').failing.like reference_parser }
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'with a nested token rule' do
|
270
|
+
let(:rules) { [
|
271
|
+
rule(:word) { assert(token(/\w+/)) }
|
272
|
+
] }
|
273
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
274
|
+
it { should parse(' ').failing.like reference_parser }
|
275
|
+
end
|
276
|
+
|
277
|
+
context 'with a nested skip rule' do
|
278
|
+
let(:rules) { [
|
279
|
+
rule(:word) { assert(skip(/\w+/)) }
|
280
|
+
] }
|
281
|
+
it { should parse('abc123 ').succeeding.like reference_parser }
|
282
|
+
it { should parse(' ').failing.like reference_parser }
|
283
|
+
end
|
284
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
shared_examples_for 'a compiled parser with an attributed sequence' do
|
4
|
+
include CompilerSpecHelper
|
5
|
+
include RuntimeParserSpecHelper
|
6
|
+
|
7
|
+
subject { compiled_parser }
|
8
|
+
|
9
|
+
let(:reference_parser) { combinator_parser grammar }
|
10
|
+
|
11
|
+
let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
|
12
|
+
|
13
|
+
context 'with a single capture and a semantic action' do
|
14
|
+
|
15
|
+
context 'when the action uses no parameters' do
|
16
|
+
let(:rules) { [
|
17
|
+
rule(:a) { match(/\d+/) >> semantic_action('42') }
|
18
|
+
] }
|
19
|
+
it { should parse('451a').succeeding.like reference_parser }
|
20
|
+
it { should parse(' ').failing.like reference_parser }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the action uses a parameter' do
|
24
|
+
let(:rules) { [
|
25
|
+
rule(:a) { match(/\d+/) >> semantic_action('|a| a.to_i') }
|
26
|
+
] }
|
27
|
+
it { should parse('451a').succeeding.like reference_parser }
|
28
|
+
it { should parse(' ').failing.like reference_parser }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when the action uses "_"' do
|
32
|
+
let(:rules) { [
|
33
|
+
rule(:a) { match(/\d+/) >> semantic_action('_.to_i') }
|
34
|
+
] }
|
35
|
+
it { should parse('451a').succeeding.like reference_parser }
|
36
|
+
it { should parse(' ').failing.like reference_parser }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with a single capture and a node action' do
|
41
|
+
let(:rules) { [
|
42
|
+
rule(:a) { match(/\d+/) >> node_action('Rattler::Runtime::ParseNode') }
|
43
|
+
] }
|
44
|
+
it { should parse('451a').succeeding.like reference_parser }
|
45
|
+
it { should parse(' ').failing.like reference_parser }
|
46
|
+
|
47
|
+
context 'when the action has node attributes' do
|
48
|
+
let(:rules) { [
|
49
|
+
rule(:a) do
|
50
|
+
match(/\d+/) >> node_action('Rattler::Runtime::ParseNode', :node_attrs => {:name => "FOO"})
|
51
|
+
end
|
52
|
+
] }
|
53
|
+
it { should parse('451a').succeeding.like reference_parser }
|
54
|
+
it { should parse(' ').failing.like reference_parser }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with a capturing nonterminal and a node action' do
|
59
|
+
let(:rules) { [
|
60
|
+
rule(:a) { match(:b) >> node_action('Rattler::Runtime::ParseNode') },
|
61
|
+
rule(:b) { match(/\d+/) }
|
62
|
+
] }
|
63
|
+
it { should parse('451a').succeeding.like reference_parser }
|
64
|
+
it { should parse(' ').failing.like reference_parser }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with a non-capturing nonterminal and a node action' do
|
68
|
+
let(:rules) { [
|
69
|
+
rule(:a) { match(:b) >> node_action('Rattler::Runtime::ParseNode') },
|
70
|
+
rule(:b) { skip(/\d+/) }
|
71
|
+
] }
|
72
|
+
it { should parse('451a').succeeding.like reference_parser }
|
73
|
+
it { should parse(' ').failing.like reference_parser }
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with multiple captures and a semantic action' do
|
77
|
+
|
78
|
+
context 'when the action uses parameters' do
|
79
|
+
let(:rules) { [
|
80
|
+
rule(:a) {
|
81
|
+
(match(/[a-z]+/) & match(/\d+/)) >> semantic_action('|a,b| b+a')
|
82
|
+
}
|
83
|
+
] }
|
84
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
85
|
+
it { should parse(' ').failing.like reference_parser }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when the action uses "_"' do
|
89
|
+
let(:rules) { [
|
90
|
+
rule(:a) {
|
91
|
+
(match(/[a-z]+/) & match(/\d+/)) >> semantic_action('_.reverse')
|
92
|
+
}
|
93
|
+
] }
|
94
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
95
|
+
it { should parse(' ').failing.like reference_parser }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with multiple captures and a node action' do
|
100
|
+
let(:rules) { [
|
101
|
+
rule(:a) {
|
102
|
+
(match(/[a-z]+/) & match(/\d+/)) >> node_action('Rattler::Runtime::ParseNode')
|
103
|
+
}
|
104
|
+
] }
|
105
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
106
|
+
it { should parse(' ').failing.like reference_parser }
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'with a single labeled capture and a semantic action' do
|
110
|
+
let(:rules) { [
|
111
|
+
rule(:e) { label(:a, /\d+/) >> semantic_action('a.to_i') }
|
112
|
+
] }
|
113
|
+
it { should parse('451a').succeeding.like reference_parser }
|
114
|
+
it { should parse(' ').failing.like reference_parser }
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with multiple labeled captures and a semantic action' do
|
118
|
+
let(:rules) { [
|
119
|
+
rule(:e) {
|
120
|
+
(label(:a, /[a-z]+/) & label(:b, /\d+/)) >> semantic_action('b + a')
|
121
|
+
}
|
122
|
+
] }
|
123
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
124
|
+
it { should parse(' ').failing.like reference_parser }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with a single labeled capture and a node action' do
|
128
|
+
let(:rules) { [
|
129
|
+
rule(:e) { label(:a, /\d+/) >> node_action('Rattler::Runtime::ParseNode') }
|
130
|
+
] }
|
131
|
+
it { should parse('451a').succeeding.like reference_parser }
|
132
|
+
it { should parse(' ').failing.like reference_parser }
|
133
|
+
|
134
|
+
context 'when the action has node attributes' do
|
135
|
+
let(:rules) { [
|
136
|
+
rule(:e) {
|
137
|
+
label(:a, /\d+/) >> node_action('Rattler::Runtime::ParseNode', :node_attrs => {:name => "FOO"})
|
138
|
+
}
|
139
|
+
] }
|
140
|
+
it { should parse('451a').succeeding.like reference_parser }
|
141
|
+
it { should parse(' ').failing.like reference_parser }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'with multiple labeled captures and a node action' do
|
146
|
+
let(:rules) { [
|
147
|
+
rule(:e) {
|
148
|
+
(label(:a, /[a-z]+/) & label(:b, /\d+/)) >> node_action('Rattler::Runtime::ParseNode')
|
149
|
+
}
|
150
|
+
] }
|
151
|
+
it { should parse('abc123').succeeding.like reference_parser }
|
152
|
+
it { should parse(' ').failing.like reference_parser }
|
153
|
+
end
|
154
|
+
end
|