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
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
2
|
|
3
|
-
include Rattler::
|
3
|
+
include Rattler::Compiler::ParserGenerator
|
4
4
|
include Rattler::Parsers
|
5
5
|
|
6
6
|
describe AssertGenerator do
|
@@ -58,60 +58,6 @@ describe AssertGenerator do
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
describe '#gen_dispatch_action' do
|
62
|
-
|
63
|
-
let(:code) { NodeCode.new('Word', 'parsed') }
|
64
|
-
|
65
|
-
context 'when nested' do
|
66
|
-
it 'generates nested positive lookahead code with a dispatch action' do
|
67
|
-
nested_code {|g| g.gen_dispatch_action assert, code }.
|
68
|
-
should == (<<-CODE).strip
|
69
|
-
begin
|
70
|
-
@scanner.skip(/(?=\\d)/) &&
|
71
|
-
Word.parsed([])
|
72
|
-
end
|
73
|
-
CODE
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'when top-level' do
|
78
|
-
it 'generates top level positive lookahead code with a dispatch action' do
|
79
|
-
top_level_code {|g| g.gen_dispatch_action assert, code }.
|
80
|
-
should == (<<-CODE).strip
|
81
|
-
@scanner.skip(/(?=\\d)/) &&
|
82
|
-
Word.parsed([])
|
83
|
-
CODE
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe '#gen_direct_action' do
|
89
|
-
|
90
|
-
let(:code) { ActionCode.new(':t') }
|
91
|
-
|
92
|
-
context 'when nested' do
|
93
|
-
it 'generates nested positive lookahead code with a direct action' do
|
94
|
-
nested_code {|g| g.gen_direct_action assert, code }.
|
95
|
-
should == (<<-CODE).strip
|
96
|
-
begin
|
97
|
-
@scanner.skip(/(?=\\d)/) &&
|
98
|
-
(:t)
|
99
|
-
end
|
100
|
-
CODE
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
context 'when top-level' do
|
105
|
-
it 'generates top level positive lookahead code with a direct action' do
|
106
|
-
top_level_code {|g| g.gen_direct_action assert, code }.
|
107
|
-
should == (<<-CODE).strip
|
108
|
-
@scanner.skip(/(?=\\d)/) &&
|
109
|
-
(:t)
|
110
|
-
CODE
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
61
|
describe '#gen_token' do
|
116
62
|
|
117
63
|
context 'when nested' do
|
@@ -0,0 +1,699 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::Compiler::ParserGenerator
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe AttributedSequenceGenerator do
|
7
|
+
|
8
|
+
include ParserGeneratorSpecHelper
|
9
|
+
include Rattler::Runtime
|
10
|
+
|
11
|
+
let(:sequence) { AttributedSequence[*children] }
|
12
|
+
|
13
|
+
describe '#gen_basic' do
|
14
|
+
|
15
|
+
context 'given a sequence with a single capture and a semantic action' do
|
16
|
+
|
17
|
+
let(:children) { [Match[/\w+/], action] }
|
18
|
+
|
19
|
+
context 'when the action uses a paramter' do
|
20
|
+
|
21
|
+
let(:action) { SemanticAction['|s| "<#{s}>"'] }
|
22
|
+
|
23
|
+
it 'generates code that binds the capture to the parameter and returns the result' do
|
24
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
25
|
+
should == (<<-'CODE').strip
|
26
|
+
p0 = @scanner.pos
|
27
|
+
begin
|
28
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
29
|
+
("<#{r0_0}>")
|
30
|
+
end || begin
|
31
|
+
@scanner.pos = p0
|
32
|
+
false
|
33
|
+
end
|
34
|
+
CODE
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when the action uses a "_"' do
|
39
|
+
|
40
|
+
let(:action) { SemanticAction['"<#{_}>"'] }
|
41
|
+
|
42
|
+
it 'generates code that binds the capture to "_" and returns the result' do
|
43
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
44
|
+
should == (<<-'CODE').strip
|
45
|
+
p0 = @scanner.pos
|
46
|
+
begin
|
47
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
48
|
+
("<#{r0_0}>")
|
49
|
+
end || begin
|
50
|
+
@scanner.pos = p0
|
51
|
+
false
|
52
|
+
end
|
53
|
+
CODE
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'given a sequence with a single capture and a node action' do
|
59
|
+
|
60
|
+
let(:children) { [Match[/\w+/], NodeAction['Expr']] }
|
61
|
+
|
62
|
+
it 'generates code that returns a new node with the capture' do
|
63
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
64
|
+
should == (<<-'CODE').strip
|
65
|
+
p0 = @scanner.pos
|
66
|
+
begin
|
67
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
68
|
+
Expr.parsed([r0_0])
|
69
|
+
end || begin
|
70
|
+
@scanner.pos = p0
|
71
|
+
false
|
72
|
+
end
|
73
|
+
CODE
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'given a sequence with an undecidable capture and a node action' do
|
78
|
+
|
79
|
+
let(:children) { [Apply[:a], NodeAction['Expr']] }
|
80
|
+
|
81
|
+
it 'generates code that returns a new node using select_captures' do
|
82
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
83
|
+
should == (<<-'CODE').strip
|
84
|
+
p0 = @scanner.pos
|
85
|
+
begin
|
86
|
+
(r0_0 = match(:a)) &&
|
87
|
+
Expr.parsed(select_captures([r0_0]))
|
88
|
+
end || begin
|
89
|
+
@scanner.pos = p0
|
90
|
+
false
|
91
|
+
end
|
92
|
+
CODE
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'given a sequence with multiple captures and a semantic action' do
|
97
|
+
|
98
|
+
let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
|
99
|
+
|
100
|
+
context 'when the action uses parameters' do
|
101
|
+
|
102
|
+
let(:action) { SemanticAction['|a,b| b + a'] }
|
103
|
+
|
104
|
+
it 'generates code that binds the captures to the parameter and returns the result' do
|
105
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
106
|
+
should == (<<-'CODE').strip
|
107
|
+
p0 = @scanner.pos
|
108
|
+
begin
|
109
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
110
|
+
@scanner.skip(/\s+/) &&
|
111
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
112
|
+
(r0_1 + r0_0)
|
113
|
+
end || begin
|
114
|
+
@scanner.pos = p0
|
115
|
+
false
|
116
|
+
end
|
117
|
+
CODE
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when the action uses "_"' do
|
122
|
+
|
123
|
+
let(:action) { SemanticAction['_ * 2'] }
|
124
|
+
|
125
|
+
it 'generates code that binds the array of captures to the parameter and returns the result' do
|
126
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
127
|
+
should == (<<-'CODE').strip
|
128
|
+
p0 = @scanner.pos
|
129
|
+
begin
|
130
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
131
|
+
@scanner.skip(/\s+/) &&
|
132
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
133
|
+
([r0_0, r0_1] * 2)
|
134
|
+
end || begin
|
135
|
+
@scanner.pos = p0
|
136
|
+
false
|
137
|
+
end
|
138
|
+
CODE
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'given a sequence with multiple captures and a node action' do
|
144
|
+
|
145
|
+
let :children do
|
146
|
+
[Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], NodeAction['Nums']]
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'generates code that returns a new node with the captures' do
|
150
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
151
|
+
should == (<<-'CODE').strip
|
152
|
+
p0 = @scanner.pos
|
153
|
+
begin
|
154
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
155
|
+
@scanner.skip(/\s+/) &&
|
156
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
157
|
+
Nums.parsed([r0_0, r0_1])
|
158
|
+
end || begin
|
159
|
+
@scanner.pos = p0
|
160
|
+
false
|
161
|
+
end
|
162
|
+
CODE
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'given a sequence with labeled captures and a semantic action' do
|
167
|
+
|
168
|
+
let(:children) { [
|
169
|
+
Label[:x, Match[/\d+/]],
|
170
|
+
Skip[Match[/\s+/]],
|
171
|
+
Label[:y, Match[/\d+/]],
|
172
|
+
SemanticAction['y + x']
|
173
|
+
] }
|
174
|
+
|
175
|
+
it 'generates code that binds the labeled captures to the parameter and returns the result' do
|
176
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
177
|
+
should == (<<-'CODE').strip
|
178
|
+
p0 = @scanner.pos
|
179
|
+
begin
|
180
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
181
|
+
@scanner.skip(/\s+/) &&
|
182
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
183
|
+
(r0_1 + r0_0)
|
184
|
+
end || begin
|
185
|
+
@scanner.pos = p0
|
186
|
+
false
|
187
|
+
end
|
188
|
+
CODE
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'given a sequence with labeled captures and a node action' do
|
193
|
+
|
194
|
+
let(:children) { [
|
195
|
+
Label[:x, Match[/\d+/]],
|
196
|
+
Skip[Match[/\s+/]],
|
197
|
+
Match[/\d+/],
|
198
|
+
NodeAction['Nums']
|
199
|
+
] }
|
200
|
+
|
201
|
+
it 'generates code that returns a new node with the bindings as the :labeled attribute' do
|
202
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_basic sequence }.
|
203
|
+
should == (<<-'CODE').strip
|
204
|
+
p0 = @scanner.pos
|
205
|
+
begin
|
206
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
207
|
+
@scanner.skip(/\s+/) &&
|
208
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
209
|
+
Nums.parsed([r0_0, r0_1], :labeled => {:x => r0_0})
|
210
|
+
end || begin
|
211
|
+
@scanner.pos = p0
|
212
|
+
false
|
213
|
+
end
|
214
|
+
CODE
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#gen_assert' do
|
220
|
+
|
221
|
+
context 'given a sequence with a single capture and a semantic action' do
|
222
|
+
|
223
|
+
let(:children) { [Match[/\w+/], action] }
|
224
|
+
|
225
|
+
context 'when the action uses a paramter' do
|
226
|
+
|
227
|
+
let(:action) { SemanticAction['|s| "<#{s}>"'] }
|
228
|
+
|
229
|
+
it 'generates code that binds the capture to the parameter and asserts the result' do
|
230
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
|
231
|
+
should == (<<-'CODE').strip
|
232
|
+
p0 = @scanner.pos
|
233
|
+
r = begin
|
234
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
235
|
+
("<#{r0_0}>") &&
|
236
|
+
true
|
237
|
+
end
|
238
|
+
@scanner.pos = p0
|
239
|
+
r
|
240
|
+
CODE
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when the action uses a "_"' do
|
245
|
+
|
246
|
+
let(:action) { SemanticAction['"<#{_}>"'] }
|
247
|
+
|
248
|
+
it 'generates code that binds the capture to "_" and asserts the result' do
|
249
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
|
250
|
+
should == (<<-'CODE').strip
|
251
|
+
p0 = @scanner.pos
|
252
|
+
r = begin
|
253
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
254
|
+
("<#{r0_0}>") &&
|
255
|
+
true
|
256
|
+
end
|
257
|
+
@scanner.pos = p0
|
258
|
+
r
|
259
|
+
CODE
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'given a sequence with multiple captures and a semantic action' do
|
265
|
+
|
266
|
+
let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
|
267
|
+
|
268
|
+
context 'when the action uses parameters' do
|
269
|
+
|
270
|
+
let(:action) { SemanticAction['|a,b| b + a'] }
|
271
|
+
|
272
|
+
it 'generates code that binds the captures to the parameter and asserts the result' do
|
273
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
|
274
|
+
should == (<<-'CODE').strip
|
275
|
+
p0 = @scanner.pos
|
276
|
+
r = begin
|
277
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
278
|
+
@scanner.skip(/\s+/) &&
|
279
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
280
|
+
(r0_1 + r0_0) &&
|
281
|
+
true
|
282
|
+
end
|
283
|
+
@scanner.pos = p0
|
284
|
+
r
|
285
|
+
CODE
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'when the action uses "_"' do
|
290
|
+
|
291
|
+
let(:action) { SemanticAction['_ * 2'] }
|
292
|
+
|
293
|
+
it 'generates code that binds the array of captures to the parameter and asserts the result' do
|
294
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
|
295
|
+
should == (<<-'CODE').strip
|
296
|
+
p0 = @scanner.pos
|
297
|
+
r = begin
|
298
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
299
|
+
@scanner.skip(/\s+/) &&
|
300
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
301
|
+
([r0_0, r0_1] * 2) &&
|
302
|
+
true
|
303
|
+
end
|
304
|
+
@scanner.pos = p0
|
305
|
+
r
|
306
|
+
CODE
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'given a sequence with labeled captures and a semantic action' do
|
312
|
+
|
313
|
+
let(:children) { [
|
314
|
+
Label[:x, Match[/\d+/]],
|
315
|
+
Skip[Match[/\s+/]],
|
316
|
+
Label[:y, Match[/\d+/]],
|
317
|
+
SemanticAction['y + x']
|
318
|
+
] }
|
319
|
+
|
320
|
+
it 'generates code that binds the labeled captures to the parameter and asserts the result' do
|
321
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_assert sequence }.
|
322
|
+
should == (<<-'CODE').strip
|
323
|
+
p0 = @scanner.pos
|
324
|
+
r = begin
|
325
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
326
|
+
@scanner.skip(/\s+/) &&
|
327
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
328
|
+
(r0_1 + r0_0) &&
|
329
|
+
true
|
330
|
+
end
|
331
|
+
@scanner.pos = p0
|
332
|
+
r
|
333
|
+
CODE
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
describe '#gen_disallow' do
|
339
|
+
|
340
|
+
context 'given a sequence with a single capture and a semantic action' do
|
341
|
+
|
342
|
+
let(:children) { [Match[/\w+/], action] }
|
343
|
+
|
344
|
+
context 'when the action uses a paramter' do
|
345
|
+
|
346
|
+
let(:action) { SemanticAction['|s| "<#{s}>"'] }
|
347
|
+
|
348
|
+
it 'generates code that binds the capture to the parameter and disallows the result' do
|
349
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
|
350
|
+
should == (<<-'CODE').strip
|
351
|
+
p0 = @scanner.pos
|
352
|
+
r = !begin
|
353
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
354
|
+
("<#{r0_0}>")
|
355
|
+
end
|
356
|
+
@scanner.pos = p0
|
357
|
+
r
|
358
|
+
CODE
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'when the action uses a "_"' do
|
363
|
+
|
364
|
+
let(:action) { SemanticAction['"<#{_}>"'] }
|
365
|
+
|
366
|
+
it 'generates code that binds the capture to "_" and disallows the result' do
|
367
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
|
368
|
+
should == (<<-'CODE').strip
|
369
|
+
p0 = @scanner.pos
|
370
|
+
r = !begin
|
371
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
372
|
+
("<#{r0_0}>")
|
373
|
+
end
|
374
|
+
@scanner.pos = p0
|
375
|
+
r
|
376
|
+
CODE
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context 'given a sequence with multiple captures and a semantic action' do
|
382
|
+
|
383
|
+
let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
|
384
|
+
|
385
|
+
context 'when the action uses parameters' do
|
386
|
+
|
387
|
+
let(:action) { SemanticAction['|a,b| b + a'] }
|
388
|
+
|
389
|
+
it 'generates code that binds the captures to the parameter and disallows the result' do
|
390
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
|
391
|
+
should == (<<-'CODE').strip
|
392
|
+
p0 = @scanner.pos
|
393
|
+
r = !begin
|
394
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
395
|
+
@scanner.skip(/\s+/) &&
|
396
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
397
|
+
(r0_1 + r0_0)
|
398
|
+
end
|
399
|
+
@scanner.pos = p0
|
400
|
+
r
|
401
|
+
CODE
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context 'when the action uses "_"' do
|
406
|
+
|
407
|
+
let(:action) { SemanticAction['_ * 2'] }
|
408
|
+
|
409
|
+
it 'generates code that binds the array of captures to the parameter and disallows the result' do
|
410
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
|
411
|
+
should == (<<-'CODE').strip
|
412
|
+
p0 = @scanner.pos
|
413
|
+
r = !begin
|
414
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
415
|
+
@scanner.skip(/\s+/) &&
|
416
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
417
|
+
([r0_0, r0_1] * 2)
|
418
|
+
end
|
419
|
+
@scanner.pos = p0
|
420
|
+
r
|
421
|
+
CODE
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context 'given a sequence with labeled captures and a semantic action' do
|
427
|
+
|
428
|
+
let(:children) { [
|
429
|
+
Label[:x, Match[/\d+/]],
|
430
|
+
Skip[Match[/\s+/]],
|
431
|
+
Label[:y, Match[/\d+/]],
|
432
|
+
SemanticAction['y + x']
|
433
|
+
] }
|
434
|
+
|
435
|
+
it 'generates code that binds the labeled captures to the parameter and disallows the result' do
|
436
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_disallow sequence }.
|
437
|
+
should == (<<-'CODE').strip
|
438
|
+
p0 = @scanner.pos
|
439
|
+
r = !begin
|
440
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
441
|
+
@scanner.skip(/\s+/) &&
|
442
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
443
|
+
(r0_1 + r0_0)
|
444
|
+
end
|
445
|
+
@scanner.pos = p0
|
446
|
+
r
|
447
|
+
CODE
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
describe '#gen_token' do
|
453
|
+
|
454
|
+
context 'given a sequence with a single capture and a semantic action' do
|
455
|
+
|
456
|
+
let(:children) { [Match[/\w+/], action] }
|
457
|
+
|
458
|
+
context 'when the action uses a paramter' do
|
459
|
+
|
460
|
+
let(:action) { SemanticAction['|s| "<#{s}>"'] }
|
461
|
+
|
462
|
+
it 'generates code that binds the capture to the parameter and returns the matched string' do
|
463
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
|
464
|
+
should == (<<-'CODE').strip
|
465
|
+
p0 = @scanner.pos
|
466
|
+
begin
|
467
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
468
|
+
("<#{r0_0}>") &&
|
469
|
+
@scanner.string[p0...(@scanner.pos)]
|
470
|
+
end || begin
|
471
|
+
@scanner.pos = p0
|
472
|
+
false
|
473
|
+
end
|
474
|
+
CODE
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
context 'when the action uses a "_"' do
|
479
|
+
|
480
|
+
let(:action) { SemanticAction['"<#{_}>"'] }
|
481
|
+
|
482
|
+
it 'generates code that binds the capture to "_" and returns the matched string' do
|
483
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
|
484
|
+
should == (<<-'CODE').strip
|
485
|
+
p0 = @scanner.pos
|
486
|
+
begin
|
487
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
488
|
+
("<#{r0_0}>") &&
|
489
|
+
@scanner.string[p0...(@scanner.pos)]
|
490
|
+
end || begin
|
491
|
+
@scanner.pos = p0
|
492
|
+
false
|
493
|
+
end
|
494
|
+
CODE
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
context 'given a sequence with multiple captures and a semantic action' do
|
500
|
+
|
501
|
+
let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
|
502
|
+
|
503
|
+
context 'when the action uses parameters' do
|
504
|
+
|
505
|
+
let(:action) { SemanticAction['|a,b| b + a'] }
|
506
|
+
|
507
|
+
it 'generates code that binds the captures to the parameter and returns the matched string' do
|
508
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
|
509
|
+
should == (<<-'CODE').strip
|
510
|
+
p0 = @scanner.pos
|
511
|
+
begin
|
512
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
513
|
+
@scanner.skip(/\s+/) &&
|
514
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
515
|
+
(r0_1 + r0_0) &&
|
516
|
+
@scanner.string[p0...(@scanner.pos)]
|
517
|
+
end || begin
|
518
|
+
@scanner.pos = p0
|
519
|
+
false
|
520
|
+
end
|
521
|
+
CODE
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
context 'when the action uses "_"' do
|
526
|
+
|
527
|
+
let(:action) { SemanticAction['_ * 2'] }
|
528
|
+
|
529
|
+
it 'generates code that binds the array of captures to the parameter and returns the matched string' do
|
530
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
|
531
|
+
should == (<<-'CODE').strip
|
532
|
+
p0 = @scanner.pos
|
533
|
+
begin
|
534
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
535
|
+
@scanner.skip(/\s+/) &&
|
536
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
537
|
+
([r0_0, r0_1] * 2) &&
|
538
|
+
@scanner.string[p0...(@scanner.pos)]
|
539
|
+
end || begin
|
540
|
+
@scanner.pos = p0
|
541
|
+
false
|
542
|
+
end
|
543
|
+
CODE
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
context 'given a sequence with labeled captures and a semantic action' do
|
549
|
+
|
550
|
+
let(:children) { [
|
551
|
+
Label[:x, Match[/\d+/]],
|
552
|
+
Skip[Match[/\s+/]],
|
553
|
+
Label[:y, Match[/\d+/]],
|
554
|
+
SemanticAction['y + x']
|
555
|
+
] }
|
556
|
+
|
557
|
+
it 'generates code that binds the labeled captures to the parameter and returns the matched string' do
|
558
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_token sequence }.
|
559
|
+
should == (<<-'CODE').strip
|
560
|
+
p0 = @scanner.pos
|
561
|
+
begin
|
562
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
563
|
+
@scanner.skip(/\s+/) &&
|
564
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
565
|
+
(r0_1 + r0_0) &&
|
566
|
+
@scanner.string[p0...(@scanner.pos)]
|
567
|
+
end || begin
|
568
|
+
@scanner.pos = p0
|
569
|
+
false
|
570
|
+
end
|
571
|
+
CODE
|
572
|
+
end
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
describe '#gen_skip' do
|
577
|
+
|
578
|
+
context 'given a sequence with a single capture and a semantic action' do
|
579
|
+
|
580
|
+
let(:children) { [Match[/\w+/], action] }
|
581
|
+
|
582
|
+
context 'when the action uses a paramter' do
|
583
|
+
|
584
|
+
let(:action) { SemanticAction['|s| "<#{s}>"'] }
|
585
|
+
|
586
|
+
it 'generates code that binds the capture to the parameter and skips the result' do
|
587
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
|
588
|
+
should == (<<-'CODE').strip
|
589
|
+
p0 = @scanner.pos
|
590
|
+
begin
|
591
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
592
|
+
("<#{r0_0}>") &&
|
593
|
+
true
|
594
|
+
end || begin
|
595
|
+
@scanner.pos = p0
|
596
|
+
false
|
597
|
+
end
|
598
|
+
CODE
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
context 'when the action uses a "_"' do
|
603
|
+
|
604
|
+
let(:action) { SemanticAction['"<#{_}>"'] }
|
605
|
+
|
606
|
+
it 'generates code that binds the capture to "_" and skips the result' do
|
607
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
|
608
|
+
should == (<<-'CODE').strip
|
609
|
+
p0 = @scanner.pos
|
610
|
+
begin
|
611
|
+
(r0_0 = @scanner.scan(/\w+/)) &&
|
612
|
+
("<#{r0_0}>") &&
|
613
|
+
true
|
614
|
+
end || begin
|
615
|
+
@scanner.pos = p0
|
616
|
+
false
|
617
|
+
end
|
618
|
+
CODE
|
619
|
+
end
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
context 'given a sequence with multiple captures and a semantic action' do
|
624
|
+
|
625
|
+
let(:children) { [Match[/\d+/], Skip[Match[/\s+/]], Match[/\d+/], action] }
|
626
|
+
|
627
|
+
context 'when the action uses parameters' do
|
628
|
+
|
629
|
+
let(:action) { SemanticAction['|a,b| b + a'] }
|
630
|
+
|
631
|
+
it 'generates code that binds the captures to the parameter and skips the result' do
|
632
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
|
633
|
+
should == (<<-'CODE').strip
|
634
|
+
p0 = @scanner.pos
|
635
|
+
begin
|
636
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
637
|
+
@scanner.skip(/\s+/) &&
|
638
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
639
|
+
(r0_1 + r0_0) &&
|
640
|
+
true
|
641
|
+
end || begin
|
642
|
+
@scanner.pos = p0
|
643
|
+
false
|
644
|
+
end
|
645
|
+
CODE
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
context 'when the action uses "_"' do
|
650
|
+
|
651
|
+
let(:action) { SemanticAction['_ * 2'] }
|
652
|
+
|
653
|
+
it 'generates code that binds the array of captures to the parameter and skips the result' do
|
654
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
|
655
|
+
should == (<<-'CODE').strip
|
656
|
+
p0 = @scanner.pos
|
657
|
+
begin
|
658
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
659
|
+
@scanner.skip(/\s+/) &&
|
660
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
661
|
+
([r0_0, r0_1] * 2) &&
|
662
|
+
true
|
663
|
+
end || begin
|
664
|
+
@scanner.pos = p0
|
665
|
+
false
|
666
|
+
end
|
667
|
+
CODE
|
668
|
+
end
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
context 'given a sequence with labeled captures and a semantic action' do
|
673
|
+
|
674
|
+
let(:children) { [
|
675
|
+
Label[:x, Match[/\d+/]],
|
676
|
+
Skip[Match[/\s+/]],
|
677
|
+
Label[:y, Match[/\d+/]],
|
678
|
+
SemanticAction['y + x']
|
679
|
+
] }
|
680
|
+
|
681
|
+
it 'generates code that binds the labeled captures to the parameter and skips the result' do
|
682
|
+
top_level_code(:sequence_level => 0) {|g| g.gen_skip sequence }.
|
683
|
+
should == (<<-'CODE').strip
|
684
|
+
p0 = @scanner.pos
|
685
|
+
begin
|
686
|
+
(r0_0 = @scanner.scan(/\d+/)) &&
|
687
|
+
@scanner.skip(/\s+/) &&
|
688
|
+
(r0_1 = @scanner.scan(/\d+/)) &&
|
689
|
+
(r0_1 + r0_0) &&
|
690
|
+
true
|
691
|
+
end || begin
|
692
|
+
@scanner.pos = p0
|
693
|
+
false
|
694
|
+
end
|
695
|
+
CODE
|
696
|
+
end
|
697
|
+
end
|
698
|
+
end
|
699
|
+
end
|