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,93 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
include Rattler::Compiler::ParserGenerator
|
4
|
+
include Rattler::Parsers
|
5
|
+
|
6
|
+
describe SuperGenerator do
|
7
|
+
|
8
|
+
include ParserGeneratorSpecHelper
|
9
|
+
|
10
|
+
let(:parser) { Super[:foo] }
|
11
|
+
|
12
|
+
describe '#gen_basic' do
|
13
|
+
it 'generates "super"' do
|
14
|
+
nested_code {|g| g.gen_basic parser }.should == 'super'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#gen_assert' do
|
19
|
+
|
20
|
+
context 'when nested' do
|
21
|
+
it 'generates nested "assert super" code' do
|
22
|
+
nested_code {|g| g.gen_assert parser }.should == (<<-CODE).strip
|
23
|
+
begin
|
24
|
+
p = @scanner.pos
|
25
|
+
r = (super && true)
|
26
|
+
@scanner.pos = p
|
27
|
+
r
|
28
|
+
end
|
29
|
+
CODE
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when top level' do
|
34
|
+
it 'generates top-level "assert super" code' do
|
35
|
+
top_level_code {|g| g.gen_assert parser }.should == (<<-CODE).strip
|
36
|
+
p = @scanner.pos
|
37
|
+
r = (super && true)
|
38
|
+
@scanner.pos = p
|
39
|
+
r
|
40
|
+
CODE
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#gen_disallow' do
|
46
|
+
|
47
|
+
context 'when nested' do
|
48
|
+
it 'generates nested "disallow super" code' do
|
49
|
+
nested_code {|g| g.gen_disallow parser }.should == (<<-CODE).strip
|
50
|
+
begin
|
51
|
+
p = @scanner.pos
|
52
|
+
r = !super
|
53
|
+
@scanner.pos = p
|
54
|
+
r
|
55
|
+
end
|
56
|
+
CODE
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when top level' do
|
61
|
+
it 'generates top-level "disallow super" code' do
|
62
|
+
top_level_code {|g| g.gen_disallow parser }.should == (<<-CODE).strip
|
63
|
+
p = @scanner.pos
|
64
|
+
r = !super
|
65
|
+
@scanner.pos = p
|
66
|
+
r
|
67
|
+
CODE
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#gen_token' do
|
73
|
+
it 'generates "super.to_s"' do
|
74
|
+
nested_code {|g| g.gen_token parser }.should == 'super.to_s'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#gen_skip' do
|
79
|
+
|
80
|
+
context 'when nested' do
|
81
|
+
it 'generates "(super && true)"' do
|
82
|
+
nested_code {|g| g.gen_skip parser }.should == '(super && true)'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when top level' do
|
87
|
+
it 'generates "super && true"' do
|
88
|
+
top_level_code {|g| g.gen_skip parser }.should == 'super && true'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -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 TokenGenerator do
|
@@ -60,60 +60,6 @@ describe TokenGenerator do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
describe '#gen_dispatch_action' do
|
64
|
-
|
65
|
-
let(:code) { NodeCode.new('Word', 'parsed') }
|
66
|
-
|
67
|
-
context 'when nested' do
|
68
|
-
it 'generates nested matching code with a dispatch action' do
|
69
|
-
nested_code {|g| g.gen_dispatch_action token, code }.
|
70
|
-
should == (<<-CODE).strip
|
71
|
-
begin
|
72
|
-
(r = @scanner.scan(/\\w+/)) &&
|
73
|
-
Word.parsed([r])
|
74
|
-
end
|
75
|
-
CODE
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'when top-level' do
|
80
|
-
it 'generates top level matching code with a dispatch action' do
|
81
|
-
top_level_code {|g| g.gen_dispatch_action token, code }.
|
82
|
-
should == (<<-CODE).strip
|
83
|
-
(r = @scanner.scan(/\\w+/)) &&
|
84
|
-
Word.parsed([r])
|
85
|
-
CODE
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe '#gen_direct_action' do
|
91
|
-
|
92
|
-
let(:code) { ActionCode.new('|_| _.to_sym') }
|
93
|
-
|
94
|
-
context 'when nested' do
|
95
|
-
it 'generates nested matching code with a direct action' do
|
96
|
-
nested_code {|g| g.gen_direct_action token, code }.
|
97
|
-
should == (<<-CODE).strip
|
98
|
-
begin
|
99
|
-
(r = @scanner.scan(/\\w+/)) &&
|
100
|
-
(r.to_sym)
|
101
|
-
end
|
102
|
-
CODE
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context 'when top-level' do
|
107
|
-
it 'generates top level matching code with a direct action' do
|
108
|
-
top_level_code {|g| g.gen_direct_action token, code }.
|
109
|
-
should == (<<-CODE).strip
|
110
|
-
(r = @scanner.scan(/\\w+/)) &&
|
111
|
-
(r.to_sym)
|
112
|
-
CODE
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
63
|
describe '#gen_token' do
|
118
64
|
|
119
65
|
context 'when nested' do
|
@@ -83,80 +83,6 @@ a
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
describe '#gen_dispatch_action' do
|
87
|
-
|
88
|
-
let(:nested) { Match[/w+/] }
|
89
|
-
let(:code) { NodeCode.new('Word', 'parsed') }
|
90
|
-
|
91
|
-
context 'given a repeat with zero-or-more bounds' do
|
92
|
-
|
93
|
-
context 'when nested' do
|
94
|
-
it 'generates nested zero-or-more matching code with a dispatch action' do
|
95
|
-
nested_code {|g| g.gen_dispatch_action repeat, code }.
|
96
|
-
should == (<<-CODE).strip
|
97
|
-
begin
|
98
|
-
a = []
|
99
|
-
while r = @scanner.scan(/w+/)
|
100
|
-
a << r
|
101
|
-
end
|
102
|
-
Word.parsed(select_captures(a))
|
103
|
-
end
|
104
|
-
CODE
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'when top-level' do
|
109
|
-
it 'generates top level zero-or-more matching code with a dispatch action' do
|
110
|
-
top_level_code {|g| g.gen_dispatch_action repeat, code }.
|
111
|
-
should == (<<-CODE).strip
|
112
|
-
a = []
|
113
|
-
while r = @scanner.scan(/w+/)
|
114
|
-
a << r
|
115
|
-
end
|
116
|
-
Word.parsed(select_captures(a))
|
117
|
-
CODE
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe '#gen_direct_action' do
|
124
|
-
|
125
|
-
let(:nested) { Match[/w+/] }
|
126
|
-
let(:code) { ActionCode.new('|_| _.size') }
|
127
|
-
|
128
|
-
context 'given a repeat with zero-or-more bounds' do
|
129
|
-
|
130
|
-
context 'when nested' do
|
131
|
-
it 'generates nested zero-or-more matching code with a direct action' do
|
132
|
-
nested_code {|g| g.gen_direct_action repeat, code }.
|
133
|
-
should == (<<-CODE).strip
|
134
|
-
begin
|
135
|
-
a = []
|
136
|
-
while r = @scanner.scan(/w+/)
|
137
|
-
a << r
|
138
|
-
end
|
139
|
-
(select_captures(a).size)
|
140
|
-
end
|
141
|
-
CODE
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context 'when top-level' do
|
146
|
-
it 'generates top level zero-or-more matching code with a direct action' do
|
147
|
-
top_level_code {|g| g.gen_direct_action repeat, code }.
|
148
|
-
should == (<<-CODE).strip
|
149
|
-
a = []
|
150
|
-
while r = @scanner.scan(/w+/)
|
151
|
-
a << r
|
152
|
-
end
|
153
|
-
(select_captures(a).size)
|
154
|
-
CODE
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
86
|
describe '#gen_token' do
|
161
87
|
|
162
88
|
let(:nested) { Match[/w+/] }
|
@@ -1,41 +1,41 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
describe Rattler::
|
4
|
-
|
5
|
-
subject { Rattler::
|
6
|
-
|
3
|
+
describe Rattler::Compiler::RubyGenerator do
|
4
|
+
|
5
|
+
subject { Rattler::Compiler::RubyGenerator.new }
|
6
|
+
|
7
7
|
describe '<<' do
|
8
8
|
it 'concatenates code' do
|
9
9
|
(subject << 'foo' << '(:bar)').code.should == 'foo(:bar)'
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
describe '#newline' do
|
14
14
|
it 'starts new lines' do
|
15
15
|
((subject << 'foo').newline << 'bar').code.should == "foo\nbar"
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
describe '#indent' do
|
20
20
|
it 'indents lines' do
|
21
21
|
subject.indent { (subject << 'foo').newline << 'bar' }.code.
|
22
22
|
should == "\n foo\n bar"
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
describe '#surround' do
|
27
27
|
it 'surrounds code with the given prefix and suffix' do
|
28
28
|
subject.surround('(', ')') { subject << 'foo' }.code.should == '(foo)'
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
describe '#block' do
|
33
33
|
it 'generates blocks' do
|
34
34
|
subject.block('for n in names') { subject << 'puts n' }.code.
|
35
35
|
should == "for n in names\n puts n\nend"
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
describe '#intersperse' do
|
40
40
|
context 'given the :sep option by itself' do
|
41
41
|
it 'intersperses the separator without newlines' do
|
@@ -44,7 +44,7 @@ describe Rattler::BackEnd::RubyGenerator do
|
|
44
44
|
end.code.should == "aa + bb + cc"
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
context 'given :newline => true' do
|
49
49
|
it 'intersperses the separator with single newlines' do
|
50
50
|
subject.intersperse(['a', 'b', 'c'], :sep => ' +', :newline => true) do |_|
|
@@ -52,7 +52,7 @@ describe Rattler::BackEnd::RubyGenerator do
|
|
52
52
|
end.code.should == "aa +\nbb +\ncc"
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
context 'given :newlines => n' do
|
57
57
|
it 'intersperses separators with multiple newlines' do
|
58
58
|
subject.intersperse(['a', 'b', 'c'], :sep => ' +', :newlines => 2) do |_|
|
@@ -60,7 +60,7 @@ describe Rattler::BackEnd::RubyGenerator do
|
|
60
60
|
end.code.should == "aa +\n\nbb +\n\ncc"
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
context 'given :newlines => n and no :sep option' do
|
65
65
|
it 'intersperses the newlines without any other separator' do
|
66
66
|
subject.intersperse(['a', 'b', 'c'], :newline => true) do |_|
|
@@ -69,5 +69,5 @@ describe Rattler::BackEnd::RubyGenerator do
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
shared_examples_for 'a compiled parser with a semantic action' do
|
4
|
+
include CompilerSpecHelper
|
5
|
+
include RuntimeParserSpecHelper
|
6
|
+
|
7
|
+
subject { compiled_parser }
|
8
|
+
|
9
|
+
let(:reference_parser) { combinator_parser grammar }
|
10
|
+
|
11
|
+
let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
|
12
|
+
|
13
|
+
context 'when the expression has no parameters' do
|
14
|
+
let(:rules) { [
|
15
|
+
rule(:a) { semantic_action('42') }
|
16
|
+
] }
|
17
|
+
it { should parse('anything').succeeding.like reference_parser }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the expression has parameters' do
|
21
|
+
let(:rules) { [
|
22
|
+
rule(:a) { match(/\d+/) >> semantic_action('|a| a.to_i * 2') }
|
23
|
+
] }
|
24
|
+
it { should parse('451a').succeeding.like reference_parser }
|
25
|
+
it { should parse(' ').failing.like reference_parser }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the expression uses "_"' do
|
29
|
+
|
30
|
+
context 'given a single capture' do
|
31
|
+
let(:rules) { [
|
32
|
+
rule(:a) { match(/\d+/) >> semantic_action('_ * 2') }
|
33
|
+
] }
|
34
|
+
it { should parse('451a').succeeding.like reference_parser }
|
35
|
+
it { should parse(' ').failing.like reference_parser }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'given multiple captures' do
|
39
|
+
let(:rules) { [
|
40
|
+
rule(:a) {
|
41
|
+
(match(/\d+/) & skip(/\s+/) & match(/\d+/)) >> semantic_action('_')
|
42
|
+
}
|
43
|
+
] }
|
44
|
+
it { should parse('23 42').succeeding.like reference_parser }
|
45
|
+
it { should parse(' ').failing.like reference_parser }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when the expression uses labels' do
|
50
|
+
let(:rules) { [
|
51
|
+
rule(:a) { label(:a, /\d+/) & semantic_action('a.to_i * 2') }
|
52
|
+
] }
|
53
|
+
it { should parse('451a').succeeding.like reference_parser }
|
54
|
+
it { should parse(' ').failing.like reference_parser }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -1,24 +1,19 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
require File.expand_path('assert_compiler_examples', File.dirname(__FILE__))
|
3
3
|
require File.expand_path('disallow_compiler_examples', File.dirname(__FILE__))
|
4
|
-
require File.expand_path('
|
5
|
-
require File.expand_path('
|
6
|
-
require File.expand_path('side_effect_compiler_examples', File.dirname(__FILE__))
|
7
|
-
require File.expand_path('semantic_assert_compiler_examples', File.dirname(__FILE__))
|
8
|
-
require File.expand_path('semantic_disallow_compiler_examples', File.dirname(__FILE__))
|
4
|
+
require File.expand_path('semantic_action_compiler_examples', File.dirname(__FILE__))
|
5
|
+
require File.expand_path('attributed_sequence_compiler_examples', File.dirname(__FILE__))
|
9
6
|
require File.expand_path('token_compiler_examples', File.dirname(__FILE__))
|
10
7
|
require File.expand_path('skip_compiler_examples', File.dirname(__FILE__))
|
11
8
|
|
12
9
|
shared_examples_for 'a compiled parser' do
|
13
10
|
include CompilerSpecHelper
|
11
|
+
include RuntimeParserSpecHelper
|
14
12
|
|
15
13
|
it_behaves_like 'a compiled parser with an assert'
|
16
14
|
it_behaves_like 'a compiled parser with a disallow'
|
17
|
-
it_behaves_like 'a compiled parser with a
|
18
|
-
it_behaves_like 'a compiled parser with
|
19
|
-
it_behaves_like 'a compiled parser with a side effect'
|
20
|
-
it_behaves_like 'a compiled parser with a positive semantic predicate'
|
21
|
-
it_behaves_like 'a compiled parser with a negative semantic predicate'
|
15
|
+
it_behaves_like 'a compiled parser with a semantic action'
|
16
|
+
it_behaves_like 'a compiled parser with an attributed sequence'
|
22
17
|
it_behaves_like 'a compiled parser with a token'
|
23
18
|
it_behaves_like 'a compiled parser with a skip'
|
24
19
|
|
@@ -26,11 +21,13 @@ shared_examples_for 'a compiled parser' do
|
|
26
21
|
|
27
22
|
let(:reference_parser) { combinator_parser grammar }
|
28
23
|
|
24
|
+
let(:grammar) { Rattler::Parsers::Grammar[Rattler::Parsers::RuleSet[*rules]] }
|
25
|
+
|
29
26
|
########## match ##########
|
30
27
|
context 'with a match rule' do
|
31
|
-
let(:
|
32
|
-
rule(:digit) { match
|
33
|
-
|
28
|
+
let(:rules) { [
|
29
|
+
rule(:digit) { match(/\d/) }
|
30
|
+
] }
|
34
31
|
it { should parse('451').succeeding.twice.like reference_parser }
|
35
32
|
it { should parse(' 4').failing.like reference_parser }
|
36
33
|
it { should parse('foo').failing.like reference_parser }
|
@@ -38,50 +35,46 @@ shared_examples_for 'a compiled parser' do
|
|
38
35
|
|
39
36
|
########## choice ##########
|
40
37
|
context 'with a choice rule' do
|
41
|
-
let(:
|
38
|
+
let(:rules) { [
|
42
39
|
rule(:atom) { match(/[[:alpha:]]+/) | match(/[[:digit:]]+/) }
|
43
|
-
|
40
|
+
] }
|
44
41
|
it { should parse('abc123').succeeding.twice.like reference_parser }
|
45
42
|
it { should parse('==').failing.like reference_parser }
|
46
43
|
|
47
44
|
context 'with non-capturing parsers' do
|
48
|
-
let(:
|
49
|
-
rule
|
50
|
-
|
51
|
-
end
|
52
|
-
end }
|
45
|
+
let(:rules) { [
|
46
|
+
rule(:foo) { skip(/\s+/) | skip(/\{[^\}]*\}/) }
|
47
|
+
] }
|
53
48
|
it { should parse(' foo').succeeding.like reference_parser }
|
54
49
|
it { should parse('{foo}').succeeding.like reference_parser }
|
55
50
|
end
|
56
51
|
|
57
52
|
context 'with nested choices' do
|
58
|
-
let(:
|
59
|
-
rule(:foo)
|
53
|
+
let(:rules) { [
|
54
|
+
rule(:foo) {
|
60
55
|
( (match('a') | match('b')) \
|
61
56
|
| (match('c') | match('d')) )
|
62
|
-
|
63
|
-
|
57
|
+
}
|
58
|
+
] }
|
64
59
|
it { should parse('abcd').succeeding(4).times.like reference_parser }
|
65
60
|
it { should parse('123').failing.like reference_parser }
|
66
61
|
end
|
67
62
|
|
68
63
|
context 'with nested sequences' do
|
69
|
-
let(:
|
70
|
-
rule(:foo)
|
64
|
+
let(:rules) { [
|
65
|
+
rule(:foo) {
|
71
66
|
( match('a') & match('b') \
|
72
67
|
| match('c') & match('d') )
|
73
|
-
|
74
|
-
|
68
|
+
}
|
69
|
+
] }
|
75
70
|
it { should parse('abcd').succeeding.twice.like reference_parser }
|
76
71
|
it { should parse('123').failing.like reference_parser }
|
77
72
|
end
|
78
73
|
|
79
74
|
context 'with nested optional parsers' do
|
80
|
-
let(:
|
81
|
-
rule(:foo)
|
82
|
-
|
83
|
-
end
|
84
|
-
end }
|
75
|
+
let(:rules) { [
|
76
|
+
rule(:foo) { match('a').optional | match('b').optional }
|
77
|
+
] }
|
85
78
|
it { should parse('abcd').succeeding(3).times.like reference_parser }
|
86
79
|
it { should parse('123').succeeding.like reference_parser }
|
87
80
|
end
|
@@ -89,70 +82,60 @@ shared_examples_for 'a compiled parser' do
|
|
89
82
|
|
90
83
|
########## sequence ##########
|
91
84
|
context 'with a sequence rule' do
|
92
|
-
let(:
|
93
|
-
rule
|
85
|
+
let(:rules) { [
|
86
|
+
rule(:assignment) {
|
94
87
|
match(/[[:alpha:]]+/) & match('=') & match(/[[:digit:]]+/)
|
95
|
-
|
96
|
-
|
88
|
+
}
|
89
|
+
] }
|
97
90
|
it { should parse('val=42 ').succeeding.like reference_parser }
|
98
91
|
it { should parse('val=x ').failing.like reference_parser }
|
99
92
|
|
100
93
|
context 'with non-capturing parsers' do
|
101
|
-
let(:
|
102
|
-
rule
|
94
|
+
let(:rules) { [
|
95
|
+
rule(:foo) {
|
103
96
|
match(/[[:alpha:]]+/) & skip(/\s+/) & match(/[[:digit:]]+/)
|
104
|
-
|
105
|
-
|
97
|
+
}
|
98
|
+
] }
|
106
99
|
it { should parse('foo 42').succeeding.like reference_parser }
|
107
100
|
end
|
108
101
|
|
109
102
|
context 'with only one capturing parser' do
|
110
|
-
let(:
|
111
|
-
rule
|
112
|
-
|
113
|
-
end
|
114
|
-
end }
|
103
|
+
let(:rules) { [
|
104
|
+
rule(:foo) { skip(/\s+/) & match(/\w+/) }
|
105
|
+
] }
|
115
106
|
it { should parse(' abc123').succeeding.like reference_parser }
|
116
107
|
end
|
117
108
|
|
118
109
|
context 'with no capturing parsers' do
|
119
|
-
let(:
|
120
|
-
rule
|
121
|
-
|
122
|
-
end
|
123
|
-
end }
|
110
|
+
let(:rules) { [
|
111
|
+
rule(:foo) { skip(/\s*/) & skip(/#[^\n]+/) }
|
112
|
+
] }
|
124
113
|
it { should parse(' # foo').succeeding.like reference_parser }
|
125
114
|
end
|
126
115
|
|
127
116
|
context 'with an apply referencing a non-capturing rule' do
|
128
|
-
let(:
|
129
|
-
rule
|
117
|
+
let(:rules) { [
|
118
|
+
rule(:foo) {
|
130
119
|
match(/[[:alpha:]]+/) & match(:ws) & match(/[[:digit:]]+/)
|
131
|
-
|
132
|
-
rule
|
133
|
-
|
134
|
-
end
|
135
|
-
end }
|
120
|
+
},
|
121
|
+
rule(:ws) { skip(/\s+/) }
|
122
|
+
] }
|
136
123
|
it { should parse('foo 42').succeeding.like reference_parser }
|
137
124
|
end
|
138
125
|
end
|
139
126
|
|
140
127
|
########## optional ##########
|
141
128
|
context 'with an optional rule' do
|
142
|
-
let(:
|
143
|
-
rule
|
144
|
-
|
145
|
-
end
|
146
|
-
end }
|
129
|
+
let(:rules) { [
|
130
|
+
rule(:foo) { match(/\w+/).optional }
|
131
|
+
] }
|
147
132
|
it { should parse('foo ').succeeding.like reference_parser }
|
148
133
|
it { should parse(' ').succeeding.like reference_parser }
|
149
134
|
|
150
135
|
context 'with a non-capturing parser' do
|
151
|
-
let(:
|
152
|
-
rule
|
153
|
-
|
154
|
-
end
|
155
|
-
end }
|
136
|
+
let(:rules) { [
|
137
|
+
rule(:foo) { skip(/\w+/).optional }
|
138
|
+
] }
|
156
139
|
it { should parse('foo ').succeeding.like reference_parser }
|
157
140
|
it { should parse(' ').succeeding.like reference_parser }
|
158
141
|
end
|
@@ -160,20 +143,16 @@ shared_examples_for 'a compiled parser' do
|
|
160
143
|
|
161
144
|
########## zero-or-more ##########
|
162
145
|
context 'with an zero-or-more rule' do
|
163
|
-
let(:
|
164
|
-
rule
|
165
|
-
|
166
|
-
end
|
167
|
-
end }
|
146
|
+
let(:rules) { [
|
147
|
+
rule(:foo) { match(/\w/).zero_or_more }
|
148
|
+
] }
|
168
149
|
it { should parse('foo ').succeeding.like reference_parser }
|
169
150
|
it { should parse(' ').succeeding.like reference_parser }
|
170
151
|
|
171
152
|
context 'with a non-capturing parser' do
|
172
|
-
let(:
|
173
|
-
rule
|
174
|
-
|
175
|
-
end
|
176
|
-
end }
|
153
|
+
let(:rules) { [
|
154
|
+
rule(:foo) { skip(/\w/).zero_or_more }
|
155
|
+
] }
|
177
156
|
it { should parse('foo ').succeeding.like reference_parser }
|
178
157
|
it { should parse(' ').succeeding.like reference_parser }
|
179
158
|
end
|
@@ -181,20 +160,16 @@ shared_examples_for 'a compiled parser' do
|
|
181
160
|
|
182
161
|
########## one-or-more ##########
|
183
162
|
context 'with an one-or-more rule' do
|
184
|
-
let(:
|
185
|
-
rule
|
186
|
-
|
187
|
-
end
|
188
|
-
end }
|
163
|
+
let(:rules) { [
|
164
|
+
rule(:foo) { match(/\w/).one_or_more }
|
165
|
+
] }
|
189
166
|
it { should parse('foo ').succeeding.like reference_parser }
|
190
167
|
it { should parse(' ').failing.like reference_parser }
|
191
168
|
|
192
169
|
context 'with a non-capturing parser' do
|
193
|
-
let(:
|
194
|
-
rule
|
195
|
-
|
196
|
-
end
|
197
|
-
end }
|
170
|
+
let(:rules) { [
|
171
|
+
rule(:foo) { skip(/\w/).one_or_more }
|
172
|
+
] }
|
198
173
|
it { should parse('foo ').succeeding.like reference_parser }
|
199
174
|
it { should parse(' ').failing.like reference_parser }
|
200
175
|
end
|
@@ -202,55 +177,59 @@ shared_examples_for 'a compiled parser' do
|
|
202
177
|
|
203
178
|
########## repeat ##########
|
204
179
|
context 'with a repeat rule' do
|
205
|
-
let(:
|
206
|
-
rule
|
207
|
-
|
208
|
-
end
|
209
|
-
end }
|
180
|
+
let(:rules) { [
|
181
|
+
rule(:foo) { match(/\w/).repeat(2, 4) }
|
182
|
+
] }
|
210
183
|
it { should parse('foo ').succeeding.like reference_parser }
|
211
184
|
it { should parse('abcde ').succeeding.like reference_parser }
|
212
185
|
it { should parse('a ').failing.like reference_parser }
|
213
186
|
|
214
187
|
context 'with no upper bound' do
|
215
|
-
let(:
|
216
|
-
rule
|
217
|
-
|
218
|
-
end
|
219
|
-
end }
|
188
|
+
let(:rules) { [
|
189
|
+
rule(:foo) { match(/\w/).repeat(2, nil) }
|
190
|
+
] }
|
220
191
|
it { should parse('foo ').succeeding.like reference_parser }
|
221
192
|
it { should parse('abcde ').succeeding.like reference_parser }
|
222
193
|
it { should parse('a ').failing.like reference_parser }
|
223
194
|
end
|
224
195
|
|
225
196
|
context 'with a non-capturing parser' do
|
226
|
-
let(:
|
227
|
-
rule
|
228
|
-
|
229
|
-
end
|
230
|
-
end }
|
197
|
+
let(:rules) { [
|
198
|
+
rule(:foo) { skip(/\w/).repeat(2, 4) }
|
199
|
+
] }
|
231
200
|
it { should parse('foo ').succeeding.like reference_parser }
|
232
201
|
it { should parse('abcde ').succeeding.like reference_parser }
|
233
202
|
it { should parse('a ').failing.like reference_parser }
|
234
203
|
end
|
204
|
+
|
205
|
+
context 'with a choice of capturing or non-capturing parsers' do
|
206
|
+
let(:rules) { [
|
207
|
+
rule(:foo) { (match(/a/) | skip(/b/)).repeat(2, 4) }
|
208
|
+
] }
|
209
|
+
it { should parse('abac').succeeding.like reference_parser }
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'with an attributed sequence with an action returning true' do
|
213
|
+
let(:rules) { [
|
214
|
+
rule(:foo) { (match(/\w/) >> semantic_action('true')).repeat(2, 4) }
|
215
|
+
] }
|
216
|
+
it { should parse('abc ').succeeding.like reference_parser }
|
217
|
+
end
|
235
218
|
end
|
236
219
|
|
237
220
|
########## list ##########
|
238
221
|
context 'given a list rule' do
|
239
|
-
let(:
|
240
|
-
rule
|
241
|
-
|
242
|
-
end
|
243
|
-
end }
|
222
|
+
let(:rules) { [
|
223
|
+
rule(:foo) { match(/\w+/).list(match(/[,;]/), 2, nil) }
|
224
|
+
] }
|
244
225
|
it { should parse('foo ').failing.like reference_parser }
|
245
226
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
246
227
|
it { should parse('foo,bar, ').succeeding.like reference_parser }
|
247
228
|
|
248
229
|
context 'with an upper bound' do
|
249
|
-
let(:
|
250
|
-
rule
|
251
|
-
|
252
|
-
end
|
253
|
-
end }
|
230
|
+
let(:rules) { [
|
231
|
+
rule(:foo) { match(/\w+/).list(match(/[,;]/), 2, 4) }
|
232
|
+
] }
|
254
233
|
it { should parse('foo ').failing.like reference_parser }
|
255
234
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
256
235
|
it { should parse('a,b,c,d,e ').succeeding.like reference_parser }
|
@@ -258,21 +237,17 @@ shared_examples_for 'a compiled parser' do
|
|
258
237
|
end
|
259
238
|
|
260
239
|
context 'with a non-capturing parser' do
|
261
|
-
let(:
|
262
|
-
rule
|
263
|
-
|
264
|
-
end
|
265
|
-
end }
|
240
|
+
let(:rules) { [
|
241
|
+
rule(:foo) { skip(/\w+/).list(match(/[,;]/), 2, nil) }
|
242
|
+
] }
|
266
243
|
it { should parse('foo ').failing.like reference_parser }
|
267
244
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
268
245
|
it { should parse('foo,bar, ').succeeding.like reference_parser }
|
269
246
|
|
270
247
|
context 'with an upper bound' do
|
271
|
-
let(:
|
272
|
-
rule
|
273
|
-
|
274
|
-
end
|
275
|
-
end }
|
248
|
+
let(:rules) { [
|
249
|
+
rule(:foo) { skip(/\w+/).list(match(/[,;]/), 2, 4) }
|
250
|
+
] }
|
276
251
|
it { should parse('foo ').failing.like reference_parser }
|
277
252
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
278
253
|
it { should parse('a,b,c,d,e ').succeeding.like reference_parser }
|
@@ -280,22 +255,18 @@ shared_examples_for 'a compiled parser' do
|
|
280
255
|
end
|
281
256
|
|
282
257
|
context 'with "zero-or-more" bounds' do
|
283
|
-
let(:
|
284
|
-
rule
|
285
|
-
|
286
|
-
end
|
287
|
-
end }
|
258
|
+
let(:rules) { [
|
259
|
+
rule(:foo) { skip(/\w+/).list(match(/[,;]/), 0, nil) }
|
260
|
+
] }
|
288
261
|
it { should parse(' ').succeeding.like reference_parser }
|
289
262
|
it { should parse('foo ').succeeding.like reference_parser }
|
290
263
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
291
264
|
end
|
292
265
|
|
293
266
|
context 'with "one-or-more" bounds' do
|
294
|
-
let(:
|
295
|
-
rule
|
296
|
-
|
297
|
-
end
|
298
|
-
end }
|
267
|
+
let(:rules) { [
|
268
|
+
rule(:foo) { skip(/\w+/).list(match(/[,;]/), 1, nil) }
|
269
|
+
] }
|
299
270
|
it { should parse(' ').failing.like reference_parser }
|
300
271
|
it { should parse('foo ').succeeding.like reference_parser }
|
301
272
|
it { should parse('foo,bar;baz ').succeeding.like reference_parser }
|
@@ -305,19 +276,19 @@ shared_examples_for 'a compiled parser' do
|
|
305
276
|
|
306
277
|
########## apply ##########
|
307
278
|
context 'given an apply rule' do
|
308
|
-
let(:
|
309
|
-
rule(:digit) { match /\d/ }
|
279
|
+
let(:rules) { [
|
280
|
+
rule(:digit) { match /\d/ },
|
310
281
|
rule(:foo) { match :digit }
|
311
|
-
|
282
|
+
] }
|
312
283
|
it { should parse('451 ').twice.succeeding.like reference_parser }
|
313
284
|
it { should parse('hi').failing.like reference_parser }
|
314
285
|
end
|
315
286
|
|
316
287
|
########## eof ##########
|
317
288
|
context 'given eof' do
|
318
|
-
let(:
|
289
|
+
let(:rules) { [
|
319
290
|
rule(:foo) { eof }
|
320
|
-
|
291
|
+
] }
|
321
292
|
it { should parse('').succeeding.like reference_parser }
|
322
293
|
it { should parse('foo').from(3).succeeding.like reference_parser }
|
323
294
|
it { should parse('foo').failing.like reference_parser }
|
@@ -325,9 +296,9 @@ shared_examples_for 'a compiled parser' do
|
|
325
296
|
|
326
297
|
########## E ##########
|
327
298
|
context 'given "E" symbol' do
|
328
|
-
let(:
|
299
|
+
let(:rules) { [
|
329
300
|
rule(:foo) { e }
|
330
|
-
|
301
|
+
] }
|
331
302
|
it { should parse('').succeeding.like reference_parser }
|
332
303
|
it { should parse('foo').succeeding.like reference_parser }
|
333
304
|
end
|