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