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,626 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
-
|
3
|
-
include Rattler::Parsers
|
4
|
-
|
5
|
-
describe Rattler::Grammar::GrammarParser do
|
6
|
-
include Rattler::Util::ParserSpecHelper
|
7
|
-
|
8
|
-
let :posix_names do
|
9
|
-
%w{alnum alpha blank cntrl digit graph lower print punct space upper xdigit}
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#match(:expression)' do
|
13
|
-
|
14
|
-
context 'given a string literal' do
|
15
|
-
|
16
|
-
context 'delimited by double quotes' do
|
17
|
-
it 'parses as a regex match' do
|
18
|
-
matching(%{ "a string" }).as(:expression).
|
19
|
-
should result_in(Match[/a\ string/]).at(11)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'delimited by single quotes' do
|
24
|
-
it 'parses as a regex match' do
|
25
|
-
matching(%{ 'a string' }).as(:expression).
|
26
|
-
should result_in(Match[/a\ string/]).at(11)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'using "general delimited text" syntax' do
|
31
|
-
|
32
|
-
context 'with "(" and ")"' do
|
33
|
-
it 'parses as a regex match' do
|
34
|
-
matching(' %(a string) ').as(:expression).
|
35
|
-
should result_in(Match[/a\ string/]).at(12)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with "{" and "}"' do
|
40
|
-
it 'parses as a regex match' do
|
41
|
-
matching(' %{a string} ').as(:expression).
|
42
|
-
should result_in(Match[/a\ string/]).at(12)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'with "[" and "]"' do
|
47
|
-
it 'parses as a regex match' do
|
48
|
-
matching(' %[a string] ').as(:expression).
|
49
|
-
should result_in(Match[/a\ string/]).at(12)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'with "<" and ">"' do
|
54
|
-
it 'parses as a regex match' do
|
55
|
-
matching(' %<a string> ').as(:expression).
|
56
|
-
should result_in(Match[/a\ string/]).at(12)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'with arbitrary delimiters' do
|
61
|
-
it 'parses as a regex match' do
|
62
|
-
matching(' %!a string! ').as(:expression).
|
63
|
-
should result_in(Match[/a\ string/]).at(12)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'delimited by backquotes' do
|
69
|
-
it 'parses as a word literal' do
|
70
|
-
matching(%{ `where` }).as(:expression).should result_in(
|
71
|
-
Token[Sequence[Match[/where/], Disallow[Match[/[[:alnum:]_]/]]]]
|
72
|
-
).at(8)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context 'with special characters' do
|
77
|
-
it 'escapes the special characters' do
|
78
|
-
matching(%{ "[...]" }).as(:expression).
|
79
|
-
should result_in(Match[/\[\.\.\.\]/]).at(8)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'given a character class expression' do
|
85
|
-
|
86
|
-
context 'with a simple list of characters' do
|
87
|
-
it 'parses as a regex match' do
|
88
|
-
matching(' [abc123] ').as(:expression).
|
89
|
-
should result_in(Match[/[abc123]/]).at(9)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context 'with octal codes' do
|
94
|
-
it 'parses as a regex match' do
|
95
|
-
matching(' [\010\012\015] ').as(:expression).
|
96
|
-
should result_in(Match[/[\010\012\015]/]).at(15)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'with hex codes' do
|
101
|
-
it 'parses as a regex match' do
|
102
|
-
matching(' [\x08\x0A\x0D] ').as(:expression).
|
103
|
-
should result_in(Match[/[\x08\x0A\x0D]/]).at(15)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context 'with a range of characters' do
|
108
|
-
it 'parses as a regex match' do
|
109
|
-
matching(' [A-F] ').as(:expression).
|
110
|
-
should result_in(Match[/[A-F]/]).at(6)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
context 'with a range of octal codes' do
|
115
|
-
it 'parses as a regex match' do
|
116
|
-
matching(' [\000-\177] ').as(:expression).
|
117
|
-
should result_in(Match[/[\000-\177]/]).at(12)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'with a range of hex codes' do
|
122
|
-
it 'parses as a regex match' do
|
123
|
-
matching(' [\x00-\x7F] ').as(:expression).
|
124
|
-
should result_in(Match[/[\x00-\x7F]/]).at(12)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'given a "."' do
|
130
|
-
it 'parses as Match[/./]' do
|
131
|
-
matching(' . ').as(:expression).should result_in(Match[/./]).at(2)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
context 'given a lower-case word' do
|
136
|
-
it 'parses as an Apply' do
|
137
|
-
matching(' fooBar ').as(:expression).should result_in(Apply[:fooBar]).at(7)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
context 'given a upper-case word' do
|
142
|
-
it 'parses it as an Apply' do
|
143
|
-
matching(' FooBar ').as(:expression).should result_in(Apply[:FooBar]).at(7)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'given the EOF keyword' do
|
148
|
-
it 'parses as Eof[]' do
|
149
|
-
matching(' EOF ').as(:expression).should result_in(Eof[]).at(4)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'given the E symbol' do
|
154
|
-
it 'parses as ESymbol[]' do
|
155
|
-
matching(' E ').as(:expression).should result_in(ESymbol[]).at(2)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'given an upper-case POSIX class name' do
|
160
|
-
it 'parses as a Match of a POSIX character class' do
|
161
|
-
for name in posix_names
|
162
|
-
matching(" #{name.upcase} ").as(:expression).
|
163
|
-
should result_in(Match[Regexp.new("[[:#{name}:]]")]).
|
164
|
-
at(name.length + 1)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
context 'given the non-POSIX WORD class name' do
|
170
|
-
it 'parses as syntactic sugar for [[:alnum:]_]' do
|
171
|
-
matching(' WORD ').as(:expression).
|
172
|
-
should result_in(Match[/[[:alnum:]_]/]).at(5)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
context 'given an optional expression' do
|
177
|
-
it 'parses as a Repeat with optional bounds' do
|
178
|
-
matching(' expr? ').as(:expression).
|
179
|
-
should result_in(Repeat[Apply[:expr], 0, 1]).at(6)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'given a zero-or-more expression' do
|
184
|
-
it 'parses as a Repeat with zero-or-more bounds' do
|
185
|
-
matching(' expr* ').as(:expression).
|
186
|
-
should result_in(Repeat[Apply[:expr], 0, nil]).at(6)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context 'given a one-or-more expression' do
|
191
|
-
it 'parses as a Repeat with one-or-more bounds' do
|
192
|
-
matching(' expr+ ').as(:expression).
|
193
|
-
should result_in(Repeat[Apply[:expr], 1, nil]).at(6)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context 'given a generalized repeat expression' do
|
198
|
-
context 'with a single count' do
|
199
|
-
it 'parses as a Repeat with the count as both lower and upper bounds' do
|
200
|
-
matching(' expr 2 ').as(:expression).
|
201
|
-
should result_in(Repeat[Apply[:expr], 2, 2]).at(7)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
context 'with a range' do
|
206
|
-
it 'parses as a Repeat with lower and upper bounds' do
|
207
|
-
matching(' expr 2..4 ').as(:expression).
|
208
|
-
should result_in(Repeat[Apply[:expr], 2, 4]).at(10)
|
209
|
-
end
|
210
|
-
|
211
|
-
context 'with no upper bound' do
|
212
|
-
it 'parses as a Repeat with no upper bound' do
|
213
|
-
matching(' expr 2.. ').as(:expression).
|
214
|
-
should result_in(Repeat[Apply[:expr], 2, nil]).at(9)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context 'given a zero-or-more list expression' do
|
221
|
-
it 'parses as a ListParser with zero-or-more bounds' do
|
222
|
-
matching(' expr *, ";" ').as(:expression).
|
223
|
-
should result_in(ListParser[Apply[:expr], Match[/;/], 0, nil]).at(12)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context 'given a one-or-more list expression' do
|
228
|
-
it 'parses as a ListParser with one-or-more bounds' do
|
229
|
-
matching(' expr +, ";" ').as(:expression).
|
230
|
-
should result_in(ListParser[Apply[:expr], Match[/;/], 1, nil]).at(12)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
context 'given a generalized list expression' do
|
235
|
-
context 'with a single count' do
|
236
|
-
it 'parses as a ListParser with the count as both lower and upper bounds' do
|
237
|
-
matching(' expr 2, ";" ').as(:expression).
|
238
|
-
should result_in(ListParser[Apply[:expr], Match[/;/], 2, 2]).at(12)
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'with a range' do
|
243
|
-
it 'parses as a ListParser with lower and upper bounds' do
|
244
|
-
matching(' expr 2..4, ";" ').as(:expression).
|
245
|
-
should result_in(ListParser[Apply[:expr], Match[/;/], 2, 4]).at(15)
|
246
|
-
end
|
247
|
-
|
248
|
-
context 'with no upper bound' do
|
249
|
-
it 'parses as a Repeat with no upper bound' do
|
250
|
-
matching(' expr 2.., ";" ').as(:expression).
|
251
|
-
should result_in(ListParser[Apply[:expr], Match[/;/], 2, nil]).at(14)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
context 'given a dispatch-action-attributed expression' do
|
258
|
-
|
259
|
-
context 'given an action with a class name' do
|
260
|
-
it 'parses as a DispatchAction with the default method' do
|
261
|
-
matching(' expr <Expr> ').as(:expression).
|
262
|
-
should result_in(DispatchAction[Apply[:expr],
|
263
|
-
{:target => 'Expr', :method => 'parsed'}
|
264
|
-
]).at(12)
|
265
|
-
end
|
266
|
-
|
267
|
-
context 'with a literal' do
|
268
|
-
it 'uses the literal as the name' do
|
269
|
-
matching(' expr <Expr "expression"> ').as(:expression).
|
270
|
-
should result_in(DispatchAction[Apply[:expr],
|
271
|
-
{:target => 'Expr', :method => 'parsed',
|
272
|
-
:target_attrs => {:name => 'expression'} }
|
273
|
-
]).at(25)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
context 'given an action with a class and method names' do
|
279
|
-
it 'parses as a DispatchAction with the default method' do
|
280
|
-
matching(' expr <Expr.eval> ').as(:expression).
|
281
|
-
should result_in(DispatchAction[Apply[:expr],
|
282
|
-
{:target => 'Expr', :method => 'eval'}
|
283
|
-
]).at(17)
|
284
|
-
end
|
285
|
-
|
286
|
-
context 'with a literal' do
|
287
|
-
it 'uses the literal as the name' do
|
288
|
-
matching(' expr <Expr.eval "expression"> ').as(:expression).
|
289
|
-
should result_in(DispatchAction[Apply[:expr],
|
290
|
-
{ :target => 'Expr', :method => 'eval',
|
291
|
-
:target_attrs => {:name => 'expression'} }
|
292
|
-
]).at(30)
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
context 'given an empty action' do
|
298
|
-
it 'parses as a DispatchAction with the default target and method' do
|
299
|
-
matching(' expr <> ').as(:expression).
|
300
|
-
should result_in(DispatchAction[Apply[:expr],
|
301
|
-
{:target => 'Rattler::Runtime::ParseNode', :method => 'parsed'}
|
302
|
-
]).at(8)
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
context 'given an action with just a literal' do
|
307
|
-
it 'parses as a default node with the literal as the name' do
|
308
|
-
matching(' expr <"expression"> ').as(:expression).
|
309
|
-
should result_in(DispatchAction[Apply[:expr],
|
310
|
-
{ :target => 'Rattler::Runtime::ParseNode',
|
311
|
-
:method => 'parsed',
|
312
|
-
:target_attrs => {:name => 'expression'} }
|
313
|
-
]).at(20)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
context 'given a lone dispatch action' do
|
319
|
-
it 'parses as a DispatchAction on ESymbol[]' do
|
320
|
-
matching(' <Foo> ').as(:expression).
|
321
|
-
should result_in(DispatchAction[ESymbol[],
|
322
|
-
{:target => 'Foo', :method => 'parsed'}]).
|
323
|
-
at(6)
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
context 'given a direct-action-attributed expression' do
|
328
|
-
it 'parses as a DirectAction' do
|
329
|
-
matching(' digits {|_| _.to_i} ').as(:expression).
|
330
|
-
should result_in(DirectAction[Apply[:digits], '|_| _.to_i']).at(20)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
context 'given a lone direct action' do
|
335
|
-
it 'parses as a DirectAction on ESymbol[]' do
|
336
|
-
matching(' { :foo } ').as(:expression).
|
337
|
-
should result_in(DirectAction[ESymbol[], ':foo']).at(9)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
context 'given a side-effect-attributed expression' do
|
342
|
-
it 'parses as a SideEffect' do
|
343
|
-
matching(' digits ~{|_| @i = _.to_i} ').as(:expression).
|
344
|
-
should result_in(SideEffect[Apply[:digits], '|_| @i = _.to_i']).at(26)
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
context 'given a lone side effect' do
|
349
|
-
it 'parses as a SideEffect on ESymbol[]' do
|
350
|
-
matching(' ~{ @i = :foo } ').as(:expression).
|
351
|
-
should result_in(SideEffect[ESymbol[], '@i = :foo']).at(15)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
context 'given a positive semantic-predicate-attributed expression' do
|
356
|
-
it 'parses as a SemanticAssert' do
|
357
|
-
matching(' digits &{|_| _.to_i} ').as(:expression).
|
358
|
-
should result_in(SemanticAssert[Apply[:digits], '|_| _.to_i']).at(21)
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
context 'given a lone positive semantic predicate' do
|
363
|
-
it 'parses as a SemanticAssert on ESymbol[]' do
|
364
|
-
matching(' &{ @foo } ').as(:expression).
|
365
|
-
should result_in(SemanticAssert[ESymbol[], '@foo']).at(10)
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
context 'given a negative semantic-predicate-attributed expression' do
|
370
|
-
it 'parses as a SemanticDisallow' do
|
371
|
-
matching(' digits !{|_| _.to_i} ').as(:expression).
|
372
|
-
should result_in(SemanticDisallow[Apply[:digits], '|_| _.to_i']).at(21)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
context 'given a lone negative semantic predicate' do
|
377
|
-
it 'parses as a SemanticDisallow on ESymbol[]' do
|
378
|
-
matching(' !{ @foo } ').as(:expression).
|
379
|
-
should result_in(SemanticDisallow[ESymbol[], '@foo']).at(10)
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
context 'given a sequence expression' do
|
384
|
-
it 'parses as a Sequence' do
|
385
|
-
matching(' name "=" value ').as(:expression).
|
386
|
-
should result_in(Sequence[Apply[:name], Match[%r{=}], Apply[:value]]).at(15)
|
387
|
-
end
|
388
|
-
|
389
|
-
context 'with a nested sequence expression' do
|
390
|
-
it 'parses as a nested Sequence' do
|
391
|
-
matching(' a (b c) d ').as(:expression).
|
392
|
-
should result_in(Sequence[
|
393
|
-
Apply[:a],
|
394
|
-
Sequence[Apply[:b], Apply[:c]],
|
395
|
-
Apply[:d]
|
396
|
-
]).at(10)
|
397
|
-
end
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
context 'given a dispatch-attributed sequence expression' do
|
402
|
-
it 'parses as a DispatchAction with a nested Sequence' do
|
403
|
-
matching(' name "=" value <Assign>').as(:expression).
|
404
|
-
should result_in(DispatchAction[
|
405
|
-
Sequence[Apply[:name], Match[%r{=}], Apply[:value]],
|
406
|
-
{:target => 'Assign', :method => 'parsed'}
|
407
|
-
]).at(24)
|
408
|
-
end
|
409
|
-
end
|
410
|
-
|
411
|
-
context 'given a multiple-dispatch-attributed expression' do
|
412
|
-
it 'parses as nested DispatchActions' do
|
413
|
-
matching(' digits <Int> <Foo> ').as(:expression).
|
414
|
-
should result_in(DispatchAction[
|
415
|
-
DispatchAction[Apply[:digits], {:target => 'Int', :method => 'parsed'}],
|
416
|
-
{:target => 'Foo', :method => 'parsed'}
|
417
|
-
]).at(19)
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
context 'given consecutive dispatch-attributed expressions' do
|
422
|
-
it 'parses as nested DispatchActions' do
|
423
|
-
matching(' digits <Int> foo <Foo> ').as(:expression).
|
424
|
-
should result_in(DispatchAction[
|
425
|
-
Sequence[
|
426
|
-
DispatchAction[Apply[:digits], {:target => 'Int', :method => 'parsed'}],
|
427
|
-
Apply[:foo]
|
428
|
-
],
|
429
|
-
{:target => 'Foo', :method => 'parsed'}
|
430
|
-
]).at(23)
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
context 'given a direct-attributed sequence expression' do
|
435
|
-
it 'parses as a DirectAction with a nested Sequence' do
|
436
|
-
matching(' name "=" value {|_| _.size }').as(:expression).
|
437
|
-
should result_in(DirectAction[
|
438
|
-
Sequence[Apply[:name], Match[%r{=}], Apply[:value]],
|
439
|
-
'|_| _.size'
|
440
|
-
]).at(29)
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
|
-
context 'given a multiple-direct-attirbuted expression' do
|
445
|
-
it 'parses as nested DirectActions' do
|
446
|
-
matching(' digits {|_| _.to_i } {|_| _ * 2 } ').as(:expression).
|
447
|
-
should result_in(DirectAction[
|
448
|
-
DirectAction[Apply[:digits], '|_| _.to_i'],
|
449
|
-
'|_| _ * 2'
|
450
|
-
]).at(34)
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
context 'given consecutive direct-attributed expressions' do
|
455
|
-
it 'parses as nested DirectActions' do
|
456
|
-
matching(' digits {|_| _.to_i } foo {|_| _ * 2 } ').as(:expression).
|
457
|
-
should result_in(DirectAction[
|
458
|
-
Sequence[
|
459
|
-
DirectAction[Apply[:digits], '|_| _.to_i'],
|
460
|
-
Apply[:foo]
|
461
|
-
],
|
462
|
-
'|_| _ * 2'
|
463
|
-
]).at(38)
|
464
|
-
end
|
465
|
-
end
|
466
|
-
|
467
|
-
context 'given a side-effect-attributed sequence expression' do
|
468
|
-
it 'parses as a SideEffect with a nested Sequence' do
|
469
|
-
matching(' name "=" value ~{|_| @n = _.size }').as(:expression).
|
470
|
-
should result_in(SideEffect[
|
471
|
-
Sequence[Apply[:name], Match[%r{=}], Apply[:value]],
|
472
|
-
'|_| @n = _.size'
|
473
|
-
]).at(35)
|
474
|
-
end
|
475
|
-
end
|
476
|
-
|
477
|
-
context 'given a multiple-effect-attirbuted expression' do
|
478
|
-
it 'parses as nested SideEffects' do
|
479
|
-
matching(' digits ~{|_| @i = _.to_i } ~{|_| @j = _ * 2 } ').as(:expression).
|
480
|
-
should result_in(SideEffect[
|
481
|
-
SideEffect[Apply[:digits], '|_| @i = _.to_i'],
|
482
|
-
'|_| @j = _ * 2'
|
483
|
-
]).at(46)
|
484
|
-
end
|
485
|
-
end
|
486
|
-
|
487
|
-
context 'given consecutive side-effect-attributed expressions' do
|
488
|
-
it 'parses as nested SideEffects' do
|
489
|
-
matching(' digits ~{|_| @i = _.to_i } foo ~{|_| @j = _ * 2 } ').as(:expression).
|
490
|
-
should result_in(SideEffect[
|
491
|
-
Sequence[
|
492
|
-
SideEffect[Apply[:digits], '|_| @i = _.to_i'],
|
493
|
-
Apply[:foo]
|
494
|
-
],
|
495
|
-
'|_| @j = _ * 2'
|
496
|
-
]).at(50)
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
context 'given a positive predicate-attributed sequence expression' do
|
501
|
-
it 'parses as a SemanticAssert with a nested Sequence' do
|
502
|
-
matching(' digits digits &{|a, b| a.to_i > b.to_i } ').as(:expression).
|
503
|
-
should result_in(SemanticAssert[
|
504
|
-
Sequence[Apply[:digits], Apply[:digits]],
|
505
|
-
'|a, b| a.to_i > b.to_i'
|
506
|
-
]).at(41)
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
context 'given a multiple-predicate-attirbuted expression' do
|
511
|
-
it 'parses as nested SemanticAsserts' do
|
512
|
-
matching(' digits &{|_| _.to_i > 1 } &{|_| _.to_i < 7 } ').as(:expression).
|
513
|
-
should result_in(SemanticAssert[
|
514
|
-
SemanticAssert[Apply[:digits], '|_| _.to_i > 1'],
|
515
|
-
'|_| _.to_i < 7'
|
516
|
-
]).at(45)
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
context 'given consecutive predicate-attributed expressions' do
|
521
|
-
it 'parses as nested SemanticAsserts' do
|
522
|
-
matching(' digits &{|_| _.to_i > 1 } foo &{|_| _.empty? } ').as(:expression).
|
523
|
-
should result_in(SemanticAssert[
|
524
|
-
Sequence[
|
525
|
-
SemanticAssert[Apply[:digits], '|_| _.to_i > 1'],
|
526
|
-
Apply[:foo]
|
527
|
-
],
|
528
|
-
'|_| _.empty?'
|
529
|
-
]).at(47)
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
context 'given a negative predicate-attributed sequence expression' do
|
534
|
-
it 'parses as a SemanticAssert with a nested Sequence' do
|
535
|
-
matching(' digits digits !{|a, b| a.to_i > b.to_i } ').as(:expression).
|
536
|
-
should result_in(SemanticDisallow[
|
537
|
-
Sequence[Apply[:digits], Apply[:digits]],
|
538
|
-
'|a, b| a.to_i > b.to_i'
|
539
|
-
]).at(41)
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
context 'given an ordered choice expression' do
|
544
|
-
it 'parses as a Choice' do
|
545
|
-
matching(' string / number ').as(:expression).
|
546
|
-
should result_in(Choice[Apply[:string], Apply[:number]]).at(16)
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
context 'given an ordered choice with sequences' do
|
551
|
-
it 'parses as a Choice of Sequences' do
|
552
|
-
matching(' foo bar / boo far ').as(:expression).
|
553
|
-
should result_in(Choice[
|
554
|
-
Sequence[Apply[:foo], Apply[:bar]],
|
555
|
-
Sequence[Apply[:boo], Apply[:far]]
|
556
|
-
]).at(18)
|
557
|
-
end
|
558
|
-
end
|
559
|
-
|
560
|
-
it 'skips normal whitespace' do
|
561
|
-
matching(" \n\t foo").as(:expression).should result_in(Apply[:foo]).at(8)
|
562
|
-
end
|
563
|
-
|
564
|
-
it 'skips comments' do
|
565
|
-
matching("\n# a comment\n\t foo").as(:expression).
|
566
|
-
should result_in(Apply[:foo]).at(18)
|
567
|
-
end
|
568
|
-
end
|
569
|
-
|
570
|
-
describe '#match(:attributed)' do
|
571
|
-
it 'recognizes dispatch-action-attributed expressions' do
|
572
|
-
matching(' expr <Expr> ').as(:attributed).
|
573
|
-
should result_in(DispatchAction[Apply[:expr], {:target => 'Expr', :method => 'parsed'}]).
|
574
|
-
at(12)
|
575
|
-
end
|
576
|
-
|
577
|
-
it 'recognizes direct-action-attributed expressions' do
|
578
|
-
matching(' digits {|_| _.to_i} ').as(:attributed).
|
579
|
-
should result_in(DirectAction[Apply[:digits], '|_| _.to_i']).at(20)
|
580
|
-
end
|
581
|
-
end
|
582
|
-
|
583
|
-
describe '#match(:term)' do
|
584
|
-
it 'recognizes assert terms' do
|
585
|
-
matching(' &expr ').as(:term).should result_in(Assert[Apply[:expr]]).at(6)
|
586
|
-
end
|
587
|
-
|
588
|
-
it 'recognizes disallow terms' do
|
589
|
-
matching(' !expr ').as(:term).should result_in(Disallow[Apply[:expr]]).at(6)
|
590
|
-
end
|
591
|
-
|
592
|
-
it 'recognizes skip terms' do
|
593
|
-
matching(' ~expr ').as(:term).should result_in(Skip[Apply[:expr]]).at(6)
|
594
|
-
end
|
595
|
-
|
596
|
-
it 'recognizes token terms' do
|
597
|
-
matching(' @expr ').as(:term).should result_in(Token[Apply[:expr]]).at(6)
|
598
|
-
end
|
599
|
-
|
600
|
-
it 'recognizes labeled terms' do
|
601
|
-
matching(' val:expr ').as(:term).should result_in(Label[:val, Apply[:expr]]).at(9)
|
602
|
-
end
|
603
|
-
|
604
|
-
it 'recognizes fail expressions' do
|
605
|
-
matching(' fail("bad!") ').as(:term).
|
606
|
-
should result_in(Fail[:expr, 'bad!']).at(13)
|
607
|
-
matching(' fail "bad!" ').as(:term).
|
608
|
-
should result_in(Fail[:expr, 'bad!']).at(12)
|
609
|
-
end
|
610
|
-
|
611
|
-
it 'recognizes fail_rule expressions' do
|
612
|
-
matching(' fail_rule("bad!") ').as(:term).
|
613
|
-
should result_in(Fail[:rule, 'bad!']).at(18)
|
614
|
-
matching(' fail_rule "bad!" ').as(:term).
|
615
|
-
should result_in(Fail[:rule, 'bad!']).at(17)
|
616
|
-
end
|
617
|
-
|
618
|
-
it 'recognizes fail_parse expressions' do
|
619
|
-
matching(' fail_parse("bad!") ').as(:term).
|
620
|
-
should result_in(Fail[:parse, 'bad!']).at(19)
|
621
|
-
matching(' fail_parse "bad!" ').as(:term).
|
622
|
-
should result_in(Fail[:parse, 'bad!']).at(18)
|
623
|
-
end
|
624
|
-
end
|
625
|
-
|
626
|
-
end
|