rattler 0.4.2 → 0.5.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 +9 -3
- data/features/command_line/dest_option.feature +1 -1
- data/features/command_line/lib_option.feature +2 -2
- data/features/command_line/output_option.feature +2 -2
- data/features/command_line/parser_generator.feature +3 -3
- data/features/grammar/any_character.feature +0 -4
- data/features/grammar/back_reference.feature +0 -4
- data/features/grammar/character_class.feature +0 -4
- data/features/grammar/comments.feature +0 -4
- data/features/grammar/e_symbol.feature +18 -0
- data/features/grammar/eof.feature +0 -4
- data/features/grammar/fail.feature +0 -4
- data/features/grammar/list_matching.feature +52 -3
- data/features/grammar/literal.feature +0 -4
- data/features/grammar/negative_lookahead.feature +0 -4
- data/features/grammar/negative_semantic_predicate.feature +99 -0
- data/features/grammar/node_action.feature +17 -4
- data/features/grammar/nonterminal.feature +3 -7
- data/features/grammar/one_or_more.feature +0 -4
- data/features/grammar/optional.feature +0 -4
- data/features/grammar/ordered_choice.feature +0 -4
- data/features/grammar/positive_lookahead.feature +0 -4
- data/features/grammar/positive_semantic_predicate.feature +99 -0
- data/features/grammar/posix_class.feature +3 -6
- data/features/grammar/repeat.feature +50 -0
- data/features/grammar/sequence.feature +0 -4
- data/features/grammar/side_effect.feature +81 -0
- data/features/grammar/skip_operator.feature +2 -5
- data/features/grammar/start_rule.feature +1 -5
- data/features/grammar/symantic_action.feature +9 -4
- data/features/grammar/token.feature +0 -4
- data/features/grammar/whitespace.feature +0 -4
- data/features/grammar/word_literal.feature +0 -4
- data/features/grammar/zero_or_more.feature +0 -4
- data/features/step_definitions/grammar_steps.rb +5 -1
- data/lib/rattler/back_end/optimizer.rb +1 -0
- data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +20 -8
- data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +10 -7
- data/lib/rattler/back_end/optimizer/specialize_repeat.rb +40 -0
- data/lib/rattler/back_end/parser_generator.rb +11 -6
- data/lib/rattler/back_end/parser_generator/delegating_generator.rb +20 -0
- data/lib/rattler/back_end/parser_generator/e_symbol_generator.rb +52 -0
- data/lib/rattler/back_end/parser_generator/eof_generator.rb +58 -0
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +6 -2
- data/lib/rattler/back_end/parser_generator/gen_method_names.rb +15 -5
- data/lib/rattler/back_end/parser_generator/general_list_generator.rb +194 -0
- data/lib/rattler/back_end/parser_generator/general_repeat_generator.rb +177 -0
- data/lib/rattler/back_end/parser_generator/label_generator.rb +4 -1
- data/lib/rattler/back_end/parser_generator/list0_generating.rb +36 -0
- data/lib/rattler/back_end/parser_generator/list1_generating.rb +30 -0
- data/lib/rattler/back_end/parser_generator/list_generator.rb +16 -20
- data/lib/rattler/back_end/parser_generator/one_or_more_generating.rb +25 -0
- data/lib/rattler/back_end/parser_generator/{optional_generator.rb → optional_generating.rb} +66 -81
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +4 -4
- data/lib/rattler/back_end/parser_generator/repeat_generator.rb +53 -0
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +2 -2
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +16 -18
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
- data/lib/rattler/back_end/parser_generator/zero_or_more_generating.rb +31 -0
- data/lib/rattler/grammar/grammar_parser.rb +20 -0
- data/lib/rattler/grammar/metagrammar.rb +131 -13
- data/lib/rattler/grammar/rattler.rtlr +25 -12
- data/lib/rattler/parsers.rb +9 -5
- data/lib/rattler/parsers/assert_code.rb +31 -0
- data/lib/rattler/parsers/atomic.rb +19 -0
- data/lib/rattler/parsers/direct_action.rb +12 -4
- data/lib/rattler/parsers/disallow_code.rb +31 -0
- data/lib/rattler/parsers/dispatch_action.rb +3 -2
- data/lib/rattler/parsers/e_symbol.rb +47 -0
- data/lib/rattler/parsers/effect_code.rb +31 -0
- data/lib/rattler/parsers/eof.rb +6 -13
- data/lib/rattler/parsers/list_parser.rb +33 -14
- data/lib/rattler/parsers/match.rb +1 -6
- data/lib/rattler/parsers/parser_dsl.rb +78 -35
- data/lib/rattler/parsers/predicate.rb +1 -4
- data/lib/rattler/parsers/repeat.rb +76 -0
- data/lib/rattler/parsers/semantic_assert.rb +19 -0
- data/lib/rattler/parsers/semantic_disallow.rb +19 -0
- data/lib/rattler/parsers/side_effect.rb +19 -0
- data/lib/rattler/parsers/skip.rb +1 -9
- data/lib/rattler/parsers/token.rb +1 -6
- data/lib/rattler/util/graphviz/node_builder.rb +6 -3
- data/spec/rattler/back_end/assert_compiler_examples.rb +187 -0
- data/spec/rattler/back_end/direct_action_compiler_examples.rb +227 -0
- data/spec/rattler/back_end/disallow_compiler_examples.rb +187 -0
- data/spec/rattler/back_end/dispatch_action_compiler_examples.rb +225 -0
- data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +45 -33
- data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +32 -172
- data/spec/rattler/back_end/parser_generator/e_symbol_generator_spec.rb +149 -0
- data/spec/rattler/back_end/parser_generator/eof_generator_spec.rb +152 -0
- data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +4 -4
- data/spec/rattler/back_end/parser_generator/list0_generator_examples.rb +322 -0
- data/spec/rattler/back_end/parser_generator/list1_generator_examples.rb +343 -0
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +597 -140
- data/spec/rattler/back_end/parser_generator/one_or_more_generator_examples.rb +292 -0
- data/spec/rattler/back_end/parser_generator/optional_generator_examples.rb +233 -0
- data/spec/rattler/back_end/parser_generator/repeat_generator_spec.rb +281 -0
- data/spec/rattler/back_end/parser_generator/zero_or_more_generator_examples.rb +277 -0
- data/spec/rattler/back_end/semantic_assert_compiler_examples.rb +152 -0
- data/spec/rattler/back_end/semantic_disallow_compiler_examples.rb +152 -0
- data/spec/rattler/back_end/shared_compiler_examples.rb +106 -651
- data/spec/rattler/back_end/side_effect_compiler_examples.rb +227 -0
- data/spec/rattler/back_end/skip_compiler_examples.rb +161 -0
- data/spec/rattler/back_end/token_compiler_examples.rb +262 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +302 -23
- data/spec/rattler/parsers/apply_spec.rb +6 -0
- data/spec/rattler/parsers/assert_spec.rb +18 -7
- data/spec/rattler/parsers/back_reference_spec.rb +9 -0
- data/spec/rattler/parsers/choice_spec.rb +36 -21
- data/spec/rattler/parsers/direct_action_spec.rb +76 -36
- data/spec/rattler/parsers/disallow_spec.rb +18 -7
- data/spec/rattler/parsers/dispatch_action_spec.rb +128 -22
- data/spec/rattler/parsers/e_symbol_spec.rb +30 -0
- data/spec/rattler/parsers/eof_spec.rb +15 -6
- data/spec/rattler/parsers/label_spec.rb +15 -2
- data/spec/rattler/parsers/list_parser_spec.rb +187 -0
- data/spec/rattler/parsers/match_spec.rb +16 -7
- data/spec/rattler/parsers/parser_dsl_spec.rb +82 -23
- data/spec/rattler/parsers/repeat_spec.rb +233 -0
- data/spec/rattler/parsers/semantic_assert_spec.rb +83 -0
- data/spec/rattler/parsers/semantic_disallow_spec.rb +83 -0
- data/spec/rattler/parsers/sequence_spec.rb +34 -20
- data/spec/rattler/parsers/side_effect_spec.rb +214 -0
- data/spec/rattler/parsers/skip_spec.rb +17 -6
- data/spec/rattler_spec.rb +2 -0
- data/spec/support/compiler_spec_helper.rb +8 -0
- metadata +156 -447
- data/bin/rtlr.compiled.rbc +0 -201
- data/features/step_definitions/cli_steps.rbc +0 -149
- data/features/step_definitions/grammar_steps.rbc +0 -1211
- data/features/support/env.rbc +0 -389
- data/lib/rattler.rbc +0 -1231
- data/lib/rattler/back_end.rbc +0 -286
- data/lib/rattler/back_end/compiler.rbc +0 -1394
- data/lib/rattler/back_end/optimizer.rbc +0 -2000
- data/lib/rattler/back_end/optimizer/composite_reducing.rbc +0 -337
- data/lib/rattler/back_end/optimizer/flatten_choice.rbc +0 -443
- data/lib/rattler/back_end/optimizer/flatten_sequence.rbc +0 -827
- data/lib/rattler/back_end/optimizer/flattening.rbc +0 -570
- data/lib/rattler/back_end/optimizer/inline_regular_rules.rbc +0 -691
- data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rbc +0 -1299
- data/lib/rattler/back_end/optimizer/join_match_choice.rbc +0 -523
- data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rbc +0 -619
- data/lib/rattler/back_end/optimizer/join_match_sequence.rbc +0 -174
- data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rbc +0 -1505
- data/lib/rattler/back_end/optimizer/join_predicate_match.rbc +0 -174
- data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rbc +0 -620
- data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rbc +0 -1502
- data/lib/rattler/back_end/optimizer/join_predicate_or_match.rbc +0 -174
- data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rbc +0 -616
- data/lib/rattler/back_end/optimizer/match_joining.rbc +0 -1454
- data/lib/rattler/back_end/optimizer/optimization.rbc +0 -1366
- data/lib/rattler/back_end/optimizer/optimization_context.rbc +0 -1386
- data/lib/rattler/back_end/optimizer/optimization_sequence.rbc +0 -520
- data/lib/rattler/back_end/optimizer/optimize_children.rbc +0 -793
- data/lib/rattler/back_end/optimizer/reduce_repeat_match.rbc +0 -788
- data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rbc +0 -508
- data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rbc +0 -807
- data/lib/rattler/back_end/optimizer/simplify_token_match.rbc +0 -561
- data/lib/rattler/back_end/parser_generator.rbc +0 -1326
- data/lib/rattler/back_end/parser_generator/apply_generator.rbc +0 -2148
- data/lib/rattler/back_end/parser_generator/assert_generator.rbc +0 -1967
- data/lib/rattler/back_end/parser_generator/back_reference_generator.rbc +0 -1665
- data/lib/rattler/back_end/parser_generator/choice_generator.rbc +0 -2793
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rbc +0 -1071
- data/lib/rattler/back_end/parser_generator/disallow_generator.rbc +0 -1967
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rbc +0 -1071
- data/lib/rattler/back_end/parser_generator/expr_generator.rbc +0 -2295
- data/lib/rattler/back_end/parser_generator/fail_generator.rbc +0 -1216
- data/lib/rattler/back_end/parser_generator/gen_method_names.rbc +0 -296
- data/lib/rattler/back_end/parser_generator/group_match.rbc +0 -612
- data/lib/rattler/back_end/parser_generator/group_match_generator.rbc +0 -1647
- data/lib/rattler/back_end/parser_generator/label_generator.rbc +0 -1401
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +0 -54
- data/lib/rattler/back_end/parser_generator/list1_generator.rbc +0 -1237
- data/lib/rattler/back_end/parser_generator/list_generating.rb +0 -71
- data/lib/rattler/back_end/parser_generator/list_generating.rbc +0 -1900
- data/lib/rattler/back_end/parser_generator/list_generator.rbc +0 -1068
- data/lib/rattler/back_end/parser_generator/match_generator.rbc +0 -1743
- data/lib/rattler/back_end/parser_generator/nested.rbc +0 -496
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +0 -56
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rbc +0 -1277
- data/lib/rattler/back_end/parser_generator/optional_generator.rbc +0 -2025
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rbc +0 -648
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +0 -57
- data/lib/rattler/back_end/parser_generator/repeat_generating.rbc +0 -1549
- data/lib/rattler/back_end/parser_generator/rule_generator.rbc +0 -1239
- data/lib/rattler/back_end/parser_generator/rule_set_generator.rbc +0 -2641
- data/lib/rattler/back_end/parser_generator/sequence_generator.rbc +0 -4867
- data/lib/rattler/back_end/parser_generator/skip_generator.rbc +0 -1278
- data/lib/rattler/back_end/parser_generator/skip_propogating.rbc +0 -432
- data/lib/rattler/back_end/parser_generator/sub_generating.rbc +0 -2785
- data/lib/rattler/back_end/parser_generator/token_generator.rbc +0 -755
- data/lib/rattler/back_end/parser_generator/token_propogating.rbc +0 -324
- data/lib/rattler/back_end/parser_generator/top_level.rbc +0 -352
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +0 -53
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rbc +0 -1111
- data/lib/rattler/back_end/ruby_generator.rbc +0 -1841
- data/lib/rattler/grammar.rbc +0 -557
- data/lib/rattler/grammar/analysis.rbc +0 -1944
- data/lib/rattler/grammar/grammar.rbc +0 -1090
- data/lib/rattler/grammar/grammar_dsl.rbc +0 -1401
- data/lib/rattler/grammar/grammar_parser.rbc +0 -2096
- data/lib/rattler/grammar/metagrammar.rbc +0 -11014
- data/lib/rattler/parsers.rbc +0 -1006
- data/lib/rattler/parsers/action_code.rbc +0 -1577
- data/lib/rattler/parsers/apply.rbc +0 -562
- data/lib/rattler/parsers/assert.rbc +0 -378
- data/lib/rattler/parsers/back_reference.rbc +0 -871
- data/lib/rattler/parsers/choice.rbc +0 -607
- data/lib/rattler/parsers/combinator_parser.rbc +0 -612
- data/lib/rattler/parsers/combining.rbc +0 -570
- data/lib/rattler/parsers/direct_action.rbc +0 -1472
- data/lib/rattler/parsers/disallow.rbc +0 -379
- data/lib/rattler/parsers/dispatch_action.rbc +0 -2078
- data/lib/rattler/parsers/eof.rbc +0 -567
- data/lib/rattler/parsers/fail.rbc +0 -745
- data/lib/rattler/parsers/label.rbc +0 -749
- data/lib/rattler/parsers/list.rbc +0 -292
- data/lib/rattler/parsers/list0.rb +0 -26
- data/lib/rattler/parsers/list0.rbc +0 -292
- data/lib/rattler/parsers/list1.rb +0 -26
- data/lib/rattler/parsers/list1.rbc +0 -305
- data/lib/rattler/parsers/list_parser.rbc +0 -886
- data/lib/rattler/parsers/match.rbc +0 -621
- data/lib/rattler/parsers/node_code.rbc +0 -1064
- data/lib/rattler/parsers/one_or_more.rb +0 -47
- data/lib/rattler/parsers/one_or_more.rbc +0 -475
- data/lib/rattler/parsers/optional.rb +0 -42
- data/lib/rattler/parsers/optional.rbc +0 -450
- data/lib/rattler/parsers/parser.rbc +0 -994
- data/lib/rattler/parsers/parser_dsl.rbc +0 -4765
- data/lib/rattler/parsers/predicate.rbc +0 -490
- data/lib/rattler/parsers/rule.rbc +0 -777
- data/lib/rattler/parsers/rule_set.rbc +0 -1438
- data/lib/rattler/parsers/sequence.rbc +0 -1040
- data/lib/rattler/parsers/skip.rbc +0 -613
- data/lib/rattler/parsers/token.rbc +0 -457
- data/lib/rattler/parsers/zero_or_more.rb +0 -40
- data/lib/rattler/parsers/zero_or_more.rbc +0 -462
- data/lib/rattler/runner.rbc +0 -3813
- data/lib/rattler/runtime.rbc +0 -370
- data/lib/rattler/runtime/extended_packrat_parser.rbc +0 -2351
- data/lib/rattler/runtime/packrat_parser.rbc +0 -1390
- data/lib/rattler/runtime/parse_failure.rbc +0 -909
- data/lib/rattler/runtime/parse_node.rbc +0 -1007
- data/lib/rattler/runtime/parser.rbc +0 -2267
- data/lib/rattler/runtime/parser_helper.rbc +0 -337
- data/lib/rattler/runtime/recursive_descent_parser.rbc +0 -942
- data/lib/rattler/util.rbc +0 -286
- data/lib/rattler/util/graphviz.rbc +0 -327
- data/lib/rattler/util/graphviz/node_builder.rbc +0 -2207
- data/lib/rattler/util/line_counter.rbc +0 -988
- data/lib/rattler/util/node.rbc +0 -2393
- data/lib/rattler/util/parser_spec_helper.rbc +0 -2533
- data/spec/rattler/back_end/compiler_spec.rbc +0 -1187
- data/spec/rattler/back_end/optimizer/flatten_choice_spec.rbc +0 -2093
- data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rbc +0 -4055
- data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rbc +0 -2345
- data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rbc +0 -7006
- data/spec/rattler/back_end/optimizer/join_match_choice_spec.rbc +0 -3252
- data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rbc +0 -3681
- data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rbc +0 -5603
- data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rbc +0 -5232
- data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rbc +0 -4272
- data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rbc +0 -4342
- data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rbc +0 -2960
- data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rbc +0 -6929
- data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rbc +0 -2327
- data/spec/rattler/back_end/optimizer_spec.rbc +0 -372
- data/spec/rattler/back_end/parser_generator/apply_generator_spec.rbc +0 -4710
- data/spec/rattler/back_end/parser_generator/assert_generator_spec.rbc +0 -4697
- data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rbc +0 -4855
- data/spec/rattler/back_end/parser_generator/choice_generator_spec.rbc +0 -5350
- data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rbc +0 -4737
- data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rbc +0 -4697
- data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rbc +0 -4731
- data/spec/rattler/back_end/parser_generator/fail_generator_spec.rbc +0 -2115
- data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rbc +0 -4195
- data/spec/rattler/back_end/parser_generator/group_match_spec.rbc +0 -1414
- data/spec/rattler/back_end/parser_generator/label_generator_spec.rbc +0 -4696
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +0 -309
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rbc +0 -5213
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rbc +0 -5179
- data/spec/rattler/back_end/parser_generator/match_generator_spec.rbc +0 -4681
- data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +0 -259
- data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rbc +0 -4957
- data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +0 -190
- data/spec/rattler/back_end/parser_generator/optional_generator_spec.rbc +0 -4704
- data/spec/rattler/back_end/parser_generator/rule_generator_spec.rbc +0 -545
- data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rbc +0 -1110
- data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rbc +0 -5453
- data/spec/rattler/back_end/parser_generator/skip_generator_spec.rbc +0 -4691
- data/spec/rattler/back_end/parser_generator/token_generator_spec.rbc +0 -4691
- data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +0 -244
- data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rbc +0 -4924
- data/spec/rattler/back_end/ruby_generator_spec.rbc +0 -2460
- data/spec/rattler/back_end/shared_compiler_examples.rbc +0 -41886
- data/spec/rattler/grammar/analysis_spec.rbc +0 -4365
- data/spec/rattler/grammar/grammar_parser_spec.rbc +0 -10344
- data/spec/rattler/grammar/grammar_spec.rbc +0 -1701
- data/spec/rattler/parsers/action_code_spec.rbc +0 -4674
- data/spec/rattler/parsers/apply_spec.rbc +0 -851
- data/spec/rattler/parsers/assert_spec.rbc +0 -752
- data/spec/rattler/parsers/back_reference_spec.rbc +0 -1002
- data/spec/rattler/parsers/choice_spec.rbc +0 -1696
- data/spec/rattler/parsers/combinator_parser_spec.rbc +0 -361
- data/spec/rattler/parsers/direct_action_spec.rbc +0 -5222
- data/spec/rattler/parsers/disallow_spec.rbc +0 -752
- data/spec/rattler/parsers/dispatch_action_spec.rbc +0 -3033
- data/spec/rattler/parsers/eof_spec.rbc +0 -728
- data/spec/rattler/parsers/fail_spec.rbc +0 -548
- data/spec/rattler/parsers/label_spec.rbc +0 -1091
- data/spec/rattler/parsers/list0_spec.rb +0 -82
- data/spec/rattler/parsers/list0_spec.rbc +0 -2308
- data/spec/rattler/parsers/list1_spec.rb +0 -82
- data/spec/rattler/parsers/list1_spec.rbc +0 -2287
- data/spec/rattler/parsers/list_spec.rbc +0 -2308
- data/spec/rattler/parsers/match_spec.rbc +0 -780
- data/spec/rattler/parsers/node_code_spec.rbc +0 -1754
- data/spec/rattler/parsers/one_or_more_spec.rb +0 -64
- data/spec/rattler/parsers/one_or_more_spec.rbc +0 -1698
- data/spec/rattler/parsers/optional_spec.rb +0 -64
- data/spec/rattler/parsers/optional_spec.rbc +0 -1717
- data/spec/rattler/parsers/parser_dsl_spec.rbc +0 -10150
- data/spec/rattler/parsers/rule_set_spec.rbc +0 -1060
- data/spec/rattler/parsers/sequence_spec.rbc +0 -2899
- data/spec/rattler/parsers/skip_spec.rbc +0 -753
- data/spec/rattler/parsers/token_spec.rbc +0 -1511
- data/spec/rattler/parsers/zero_or_more_spec.rb +0 -64
- data/spec/rattler/parsers/zero_or_more_spec.rbc +0 -1719
- data/spec/rattler/runtime/extended_packrat_parser_spec.rbc +0 -1341
- data/spec/rattler/runtime/packrat_parser_spec.rbc +0 -210
- data/spec/rattler/runtime/parse_failure_spec.rbc +0 -2244
- data/spec/rattler/runtime/parse_node_spec.rbc +0 -2008
- data/spec/rattler/runtime/parser_spec.rbc +0 -2757
- data/spec/rattler/runtime/recursive_descent_parser_spec.rbc +0 -210
- data/spec/rattler/runtime/shared_parser_examples.rbc +0 -2567
- data/spec/rattler/util/graphviz/node_builder_spec.rbc +0 -3439
- data/spec/rattler/util/line_counter_spec.rbc +0 -2272
- data/spec/rattler/util/node_spec.rbc +0 -15023
- data/spec/rattler_spec.rbc +0 -1591
- data/spec/spec_helper.rbc +0 -336
- data/spec/support/combinator_parser_spec_helper.rbc +0 -1284
- data/spec/support/compiler_spec_helper.rbc +0 -1941
- data/spec/support/parser_generator_spec_helper.rbc +0 -718
- data/spec/support/runtime_parser_spec_helper.rbc +0 -313
| @@ -0,0 +1,152 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            shared_examples_for 'a compiled parser with a positive semantic predicate' do
         | 
| 4 | 
            +
              include CompilerSpecHelper
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              subject { compiled_parser }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let(:reference_parser) { combinator_parser grammar }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              context 'with a nested match rule' do
         | 
| 11 | 
            +
                let(:grammar) { define_grammar do
         | 
| 12 | 
            +
                  rule(:num) { semantic_assert(/\d+/, '_.to_i > 200') }
         | 
| 13 | 
            +
                end }
         | 
| 14 | 
            +
                it { should parse('451a').succeeding.like reference_parser }
         | 
| 15 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 16 | 
            +
                it { should parse('123a').failing.like reference_parser }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                context 'with a label' do
         | 
| 19 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 20 | 
            +
                    rule(:digits) { semantic_assert(label(:num, /\d+/), 'num.to_i > 200') }
         | 
| 21 | 
            +
                  end }
         | 
| 22 | 
            +
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 23 | 
            +
                  it { should parse('    ').failing.like reference_parser }
         | 
| 24 | 
            +
                  it { should parse('123a').failing.like reference_parser }
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              context 'with a nested apply rule' do
         | 
| 29 | 
            +
                let(:grammar) { define_grammar do
         | 
| 30 | 
            +
                  rule(:foo) { semantic_assert :digit, '_.to_i > 200' }
         | 
| 31 | 
            +
                  rule(:digit) { match(/\d+/) }
         | 
| 32 | 
            +
                end }
         | 
| 33 | 
            +
                it { should parse('451a').succeeding.like reference_parser }
         | 
| 34 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 35 | 
            +
                it { should parse('123a').failing.like reference_parser }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                context 'with a label' do
         | 
| 38 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 39 | 
            +
                    rule(:num) { semantic_assert(label(:num, :digits), 'num.to_i > 200') }
         | 
| 40 | 
            +
                    rule(:digits) { match(/\d+/) }
         | 
| 41 | 
            +
                  end }
         | 
| 42 | 
            +
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 43 | 
            +
                  it { should parse('    ').failing.like reference_parser }
         | 
| 44 | 
            +
                  it { should parse('123a').failing.like reference_parser }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              context 'with a nested choice rule' do
         | 
| 49 | 
            +
                let(:grammar) { define_grammar do
         | 
| 50 | 
            +
                  rule :foo do
         | 
| 51 | 
            +
                    semantic_assert(
         | 
| 52 | 
            +
                      match(/[[:alpha:]]+/) | match(/[[:digit:]]+/),
         | 
| 53 | 
            +
                      '_.size > 2'
         | 
| 54 | 
            +
                    )
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                end }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it { should parse('abc123').succeeding.like reference_parser }
         | 
| 59 | 
            +
                it { should parse('12abc').failing.like reference_parser }
         | 
| 60 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              context 'with a nested sequence rule' do
         | 
| 64 | 
            +
                let(:grammar) { define_grammar do
         | 
| 65 | 
            +
                  rule :assignment do
         | 
| 66 | 
            +
                    semantic_assert(
         | 
| 67 | 
            +
                      match(/\w+/) & match('=') & match(/\w+/),
         | 
| 68 | 
            +
                      '|l,_,r| l == r'
         | 
| 69 | 
            +
                    )
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end }
         | 
| 72 | 
            +
                it { should parse('451a=451a ').succeeding.like reference_parser }
         | 
| 73 | 
            +
                it { should parse('451a=123a ').failing.like reference_parser }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                context 'with labels' do
         | 
| 76 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 77 | 
            +
                    rule :assignment do
         | 
| 78 | 
            +
                      semantic_assert(
         | 
| 79 | 
            +
                        label(:lt, /\w+/) & match('=') & label(:rt, /\w+/),
         | 
| 80 | 
            +
                        'lt == rt'
         | 
| 81 | 
            +
                      )
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  end }
         | 
| 84 | 
            +
                  it { should parse('451a=451a ').succeeding.like reference_parser }
         | 
| 85 | 
            +
                  it { should parse('451a=123a ').failing.like reference_parser }
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              context 'with a nested optional rule' do
         | 
| 90 | 
            +
                let(:grammar) { define_grammar do
         | 
| 91 | 
            +
                  rule :foo do
         | 
| 92 | 
            +
                    semantic_assert(optional(/\w+/), '|_| _.empty?')
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end }
         | 
| 95 | 
            +
                it { should parse('foo ').failing.like reference_parser }
         | 
| 96 | 
            +
                it { should parse('    ').succeeding.like reference_parser }
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              context 'with a nested zero-or-more rule' do
         | 
| 100 | 
            +
                let(:grammar) { define_grammar do
         | 
| 101 | 
            +
                  rule :foo do
         | 
| 102 | 
            +
                    semantic_assert(zero_or_more(/\w/), '|_| _.size < 4')
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                end }
         | 
| 105 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 106 | 
            +
                it { should parse('food').failing.like reference_parser }
         | 
| 107 | 
            +
                it { should parse('    ').succeeding.like reference_parser }
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
              context 'with a nested one-or-more rule' do
         | 
| 111 | 
            +
                let(:grammar) { define_grammar do
         | 
| 112 | 
            +
                  rule :foo do
         | 
| 113 | 
            +
                    semantic_assert(one_or_more(/\w/), '|_| _.size < 4')
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end }
         | 
| 116 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 117 | 
            +
                it { should parse('food').failing.like reference_parser }
         | 
| 118 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              context 'with a nested list rule' do
         | 
| 122 | 
            +
                let(:grammar) { define_grammar do
         | 
| 123 | 
            +
                  rule :foo do
         | 
| 124 | 
            +
                    semantic_assert(list(/\w+/, /,/, 1, nil), '|_| _.size < 4')
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
                end }
         | 
| 127 | 
            +
                it { should parse('a,bc,d ').succeeding.like reference_parser }
         | 
| 128 | 
            +
                it { should parse('a,b,c,d').failing.like reference_parser }
         | 
| 129 | 
            +
                it { should parse('  ').failing.like reference_parser }
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              context 'with a nested apply rule' do
         | 
| 133 | 
            +
                let(:grammar) { define_grammar do
         | 
| 134 | 
            +
                  rule(:foo) { semantic_assert :digit, '_.to_i > 200' }
         | 
| 135 | 
            +
                  rule(:digit) { match /\d+/ }
         | 
| 136 | 
            +
                end }
         | 
| 137 | 
            +
                it { should parse('451a').succeeding.like reference_parser }
         | 
| 138 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 139 | 
            +
                it { should parse('123a').failing.like reference_parser }
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              context 'with a nested token rule' do
         | 
| 143 | 
            +
                let(:grammar) { define_grammar do
         | 
| 144 | 
            +
                  rule :foo do
         | 
| 145 | 
            +
                    semantic_assert(token(/\w+/), '_.size > 5')
         | 
| 146 | 
            +
                  end
         | 
| 147 | 
            +
                end }
         | 
| 148 | 
            +
                it { should parse('abc123').succeeding.like reference_parser }
         | 
| 149 | 
            +
                it { should parse('      ').failing.like reference_parser }
         | 
| 150 | 
            +
                it { should parse('abc12 ').failing.like reference_parser }
         | 
| 151 | 
            +
              end
         | 
| 152 | 
            +
            end
         | 
| @@ -0,0 +1,152 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            shared_examples_for 'a compiled parser with a negative semantic predicate' do
         | 
| 4 | 
            +
              include CompilerSpecHelper
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              subject { compiled_parser }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let(:reference_parser) { combinator_parser grammar }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              context 'with a nested match rule' do
         | 
| 11 | 
            +
                let(:grammar) { define_grammar do
         | 
| 12 | 
            +
                  rule(:num) { semantic_disallow(/\d+/, '_.to_i > 200') }
         | 
| 13 | 
            +
                end }
         | 
| 14 | 
            +
                it { should parse('123a').succeeding.like reference_parser }
         | 
| 15 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 16 | 
            +
                it { should parse('451a').failing.like reference_parser }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                context 'with a label' do
         | 
| 19 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 20 | 
            +
                    rule(:digits) { semantic_disallow(label(:num, /\d+/), 'num.to_i > 200') }
         | 
| 21 | 
            +
                  end }
         | 
| 22 | 
            +
                  it { should parse('123a').succeeding.like reference_parser }
         | 
| 23 | 
            +
                  it { should parse('    ').failing.like reference_parser }
         | 
| 24 | 
            +
                  it { should parse('451a').failing.like reference_parser }
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              context 'with a nested apply rule' do
         | 
| 29 | 
            +
                let(:grammar) { define_grammar do
         | 
| 30 | 
            +
                  rule(:foo) { semantic_disallow :digit, '_.to_i > 200' }
         | 
| 31 | 
            +
                  rule(:digit) { match(/\d+/) }
         | 
| 32 | 
            +
                end }
         | 
| 33 | 
            +
                it { should parse('123a').succeeding.like reference_parser }
         | 
| 34 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 35 | 
            +
                it { should parse('451a').failing.like reference_parser }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                context 'with a label' do
         | 
| 38 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 39 | 
            +
                    rule(:num) { semantic_disallow(label(:num, :digits), 'num.to_i > 200') }
         | 
| 40 | 
            +
                    rule(:digits) { match(/\d+/) }
         | 
| 41 | 
            +
                  end }
         | 
| 42 | 
            +
                  it { should parse('123a').succeeding.like reference_parser }
         | 
| 43 | 
            +
                  it { should parse('    ').failing.like reference_parser }
         | 
| 44 | 
            +
                  it { should parse('451a').failing.like reference_parser }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              context 'with a nested choice rule' do
         | 
| 49 | 
            +
                let(:grammar) { define_grammar do
         | 
| 50 | 
            +
                  rule :foo do
         | 
| 51 | 
            +
                    semantic_disallow(
         | 
| 52 | 
            +
                      match(/[[:alpha:]]+/) | match(/[[:digit:]]+/),
         | 
| 53 | 
            +
                      '_.size > 2'
         | 
| 54 | 
            +
                    )
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                end }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it { should parse('12abc').succeeding.like reference_parser }
         | 
| 59 | 
            +
                it { should parse('abc123').failing.like reference_parser }
         | 
| 60 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              context 'with a nested sequence rule' do
         | 
| 64 | 
            +
                let(:grammar) { define_grammar do
         | 
| 65 | 
            +
                  rule :assignment do
         | 
| 66 | 
            +
                    semantic_disallow(
         | 
| 67 | 
            +
                      match(/\w+/) & match('=') & match(/\w+/),
         | 
| 68 | 
            +
                      '|l,_,r| l == r'
         | 
| 69 | 
            +
                    )
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end }
         | 
| 72 | 
            +
                it { should parse('451a=123a ').succeeding.like reference_parser }
         | 
| 73 | 
            +
                it { should parse('451a=451a ').failing.like reference_parser }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                context 'with labels' do
         | 
| 76 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 77 | 
            +
                    rule :assignment do
         | 
| 78 | 
            +
                      semantic_disallow(
         | 
| 79 | 
            +
                        label(:lt, /\w+/) & match('=') & label(:rt, /\w+/),
         | 
| 80 | 
            +
                        'lt == rt'
         | 
| 81 | 
            +
                      )
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  end }
         | 
| 84 | 
            +
                  it { should parse('451a=123a ').succeeding.like reference_parser }
         | 
| 85 | 
            +
                  it { should parse('451a=451a ').failing.like reference_parser }
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              context 'with a nested optional rule' do
         | 
| 90 | 
            +
                let(:grammar) { define_grammar do
         | 
| 91 | 
            +
                  rule :foo do
         | 
| 92 | 
            +
                    semantic_disallow(optional(/\w+/), '|_| _.empty?')
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end }
         | 
| 95 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 96 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              context 'with a nested zero-or-more rule' do
         | 
| 100 | 
            +
                let(:grammar) { define_grammar do
         | 
| 101 | 
            +
                  rule :foo do
         | 
| 102 | 
            +
                    semantic_disallow(zero_or_more(/\w/), '|_| _.size > 3')
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                end }
         | 
| 105 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 106 | 
            +
                it { should parse('food').failing.like reference_parser }
         | 
| 107 | 
            +
                it { should parse('    ').succeeding.like reference_parser }
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
              context 'with a nested one-or-more rule' do
         | 
| 111 | 
            +
                let(:grammar) { define_grammar do
         | 
| 112 | 
            +
                  rule :foo do
         | 
| 113 | 
            +
                    semantic_disallow(one_or_more(/\w/), '|_| _.size > 3')
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end }
         | 
| 116 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 117 | 
            +
                it { should parse('food').failing.like reference_parser }
         | 
| 118 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              context 'with a nested list rule' do
         | 
| 122 | 
            +
                let(:grammar) { define_grammar do
         | 
| 123 | 
            +
                  rule :foo do
         | 
| 124 | 
            +
                    semantic_disallow(list(/\w+/, /,/, 1, nil), '|_| _.size > 3')
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
                end }
         | 
| 127 | 
            +
                it { should parse('a,bc,d ').succeeding.like reference_parser }
         | 
| 128 | 
            +
                it { should parse('a,b,c,d').failing.like reference_parser }
         | 
| 129 | 
            +
                it { should parse('  ').failing.like reference_parser }
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              context 'with a nested apply rule' do
         | 
| 133 | 
            +
                let(:grammar) { define_grammar do
         | 
| 134 | 
            +
                  rule(:foo) { semantic_disallow :digit, '_.to_i > 200' }
         | 
| 135 | 
            +
                  rule(:digit) { match /\d+/ }
         | 
| 136 | 
            +
                end }
         | 
| 137 | 
            +
                it { should parse('123a').succeeding.like reference_parser }
         | 
| 138 | 
            +
                it { should parse('    ').failing.like reference_parser }
         | 
| 139 | 
            +
                it { should parse('451a').failing.like reference_parser }
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              context 'with a nested token rule' do
         | 
| 143 | 
            +
                let(:grammar) { define_grammar do
         | 
| 144 | 
            +
                  rule :foo do
         | 
| 145 | 
            +
                    semantic_disallow(token(/\w+/), '_.size > 5')
         | 
| 146 | 
            +
                  end
         | 
| 147 | 
            +
                end }
         | 
| 148 | 
            +
                it { should parse('abc12 ').succeeding.like reference_parser }
         | 
| 149 | 
            +
                it { should parse('      ').failing.like reference_parser }
         | 
| 150 | 
            +
                it { should parse('abc123').failing.like reference_parser }
         | 
| 151 | 
            +
              end
         | 
| 152 | 
            +
            end
         | 
| @@ -1,6 +1,27 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
         | 
| 2 | 
            +
            require File.expand_path('assert_compiler_examples', File.dirname(__FILE__))
         | 
| 3 | 
            +
            require File.expand_path('disallow_compiler_examples', File.dirname(__FILE__))
         | 
| 4 | 
            +
            require File.expand_path('dispatch_action_compiler_examples', File.dirname(__FILE__))
         | 
| 5 | 
            +
            require File.expand_path('direct_action_compiler_examples', File.dirname(__FILE__))
         | 
| 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__))
         | 
| 9 | 
            +
            require File.expand_path('token_compiler_examples', File.dirname(__FILE__))
         | 
| 10 | 
            +
            require File.expand_path('skip_compiler_examples', File.dirname(__FILE__))
         | 
| 11 | 
            +
             | 
| 1 12 | 
             
            shared_examples_for 'a compiled parser' do
         | 
| 2 13 | 
             
              include CompilerSpecHelper
         | 
| 3 14 |  | 
| 15 | 
            +
              it_behaves_like 'a compiled parser with an assert'
         | 
| 16 | 
            +
              it_behaves_like 'a compiled parser with a disallow'
         | 
| 17 | 
            +
              it_behaves_like 'a compiled parser with a dispatch action'
         | 
| 18 | 
            +
              it_behaves_like 'a compiled parser with a direct action'
         | 
| 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'
         | 
| 22 | 
            +
              it_behaves_like 'a compiled parser with a token'
         | 
| 23 | 
            +
              it_behaves_like 'a compiled parser with a skip'
         | 
| 24 | 
            +
             | 
| 4 25 | 
             
              subject { compiled_parser }
         | 
| 5 26 |  | 
| 6 27 | 
             
              let(:reference_parser) { combinator_parser grammar }
         | 
| @@ -23,6 +44,16 @@ shared_examples_for 'a compiled parser' do | |
| 23 44 | 
             
                it { should parse('abc123').succeeding.twice.like reference_parser }
         | 
| 24 45 | 
             
                it { should parse('==').failing.like reference_parser }
         | 
| 25 46 |  | 
| 47 | 
            +
                context 'with non-capturing parsers' do
         | 
| 48 | 
            +
                  let(:grammar) { define_grammar do
         | 
| 49 | 
            +
                    rule :foo do
         | 
| 50 | 
            +
                      skip(/\s+/) | skip(/\{[^\}]*\}/)
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                  end }
         | 
| 53 | 
            +
                  it { should parse('   foo').succeeding.like reference_parser }
         | 
| 54 | 
            +
                  it { should parse('{foo}').succeeding.like reference_parser }
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 26 57 | 
             
                context 'with nested choices' do
         | 
| 27 58 | 
             
                  let(:grammar) { define_grammar do
         | 
| 28 59 | 
             
                    rule(:foo) do
         | 
| @@ -169,711 +200,135 @@ shared_examples_for 'a compiled parser' do | |
| 169 200 | 
             
                end
         | 
| 170 201 | 
             
              end
         | 
| 171 202 |  | 
| 172 | 
            -
              ##########  | 
| 173 | 
            -
              context ' | 
| 203 | 
            +
              ########## repeat ##########
         | 
| 204 | 
            +
              context 'with a repeat rule' do
         | 
| 174 205 | 
             
                let(:grammar) { define_grammar do
         | 
| 175 206 | 
             
                  rule :foo do
         | 
| 176 | 
            -
                     | 
| 207 | 
            +
                    repeat(/\w/, 2, 4)
         | 
| 177 208 | 
             
                  end
         | 
| 178 209 | 
             
                end }
         | 
| 179 | 
            -
                it { should parse(' | 
| 180 | 
            -
                it { should parse(' | 
| 181 | 
            -
                it { should parse(' | 
| 182 | 
            -
                it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 183 | 
            -
             | 
| 184 | 
            -
                context 'with a non-capturing parser' do
         | 
| 185 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 186 | 
            -
                    rule :foo do
         | 
| 187 | 
            -
                      list(skip(/\w+/), /[,;]/)
         | 
| 188 | 
            -
                    end
         | 
| 189 | 
            -
                  end }
         | 
| 190 | 
            -
                  it { should parse('  ').succeeding.like reference_parser }
         | 
| 191 | 
            -
                  it { should parse('foo  ').succeeding.like reference_parser }
         | 
| 192 | 
            -
                  it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 193 | 
            -
                  it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 194 | 
            -
                end
         | 
| 195 | 
            -
              end
         | 
| 196 | 
            -
             | 
| 197 | 
            -
              ########## list1 ##########
         | 
| 198 | 
            -
              context 'given a list1 rule' do
         | 
| 199 | 
            -
                let(:grammar) { define_grammar do
         | 
| 200 | 
            -
                  rule :foo do
         | 
| 201 | 
            -
                    list1(/\w+/, /[,;]/)
         | 
| 202 | 
            -
                  end
         | 
| 203 | 
            -
                end }
         | 
| 204 | 
            -
                it { should parse('  ').failing.like reference_parser }
         | 
| 205 | 
            -
                it { should parse('foo  ').succeeding.like reference_parser }
         | 
| 206 | 
            -
                it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 207 | 
            -
                it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 208 | 
            -
             | 
| 209 | 
            -
                context 'with a non-capturing parser' do
         | 
| 210 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 211 | 
            -
                    rule :foo do
         | 
| 212 | 
            -
                      list1(skip(/\w+/), /[,;]/)
         | 
| 213 | 
            -
                    end
         | 
| 214 | 
            -
                  end }
         | 
| 215 | 
            -
                  it { should parse('  ').failing.like reference_parser }
         | 
| 216 | 
            -
                  it { should parse('foo  ').succeeding.like reference_parser }
         | 
| 217 | 
            -
                  it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 218 | 
            -
                  it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 219 | 
            -
                end
         | 
| 220 | 
            -
              end
         | 
| 221 | 
            -
             | 
| 222 | 
            -
              ########## apply ##########
         | 
| 223 | 
            -
              context 'given an apply rule' do
         | 
| 224 | 
            -
                let(:grammar) { define_grammar do
         | 
| 225 | 
            -
                  rule(:digit) { match /\d/ }
         | 
| 226 | 
            -
                  rule(:foo) { match :digit }
         | 
| 227 | 
            -
                end }
         | 
| 228 | 
            -
                it { should parse('451 ').twice.succeeding.like reference_parser }
         | 
| 229 | 
            -
                it { should parse('hi').failing.like reference_parser }
         | 
| 230 | 
            -
              end
         | 
| 231 | 
            -
             | 
| 232 | 
            -
              ########## assert ##########
         | 
| 233 | 
            -
              context 'given an assert rule' do
         | 
| 234 | 
            -
             | 
| 235 | 
            -
                context 'with a nested match rule' do
         | 
| 236 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 237 | 
            -
                    rule(:word) { assert /\w+/ }
         | 
| 238 | 
            -
                  end }
         | 
| 239 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 240 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 241 | 
            -
                end
         | 
| 242 | 
            -
             | 
| 243 | 
            -
                context 'with a nested choice rule' do
         | 
| 244 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 245 | 
            -
                    rule(:word) { assert(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/)) }
         | 
| 246 | 
            -
                  end }
         | 
| 247 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 248 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 249 | 
            -
                end
         | 
| 250 | 
            -
             | 
| 251 | 
            -
                context 'with a nested sequence rule' do
         | 
| 252 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 253 | 
            -
                    rule(:word) { assert(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)) }
         | 
| 254 | 
            -
                  end }
         | 
| 255 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 256 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 257 | 
            -
                end
         | 
| 258 | 
            -
             | 
| 259 | 
            -
                context 'with a nested optional rule' do
         | 
| 260 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 261 | 
            -
                    rule(:word) { assert(optional(/\w+/)) }
         | 
| 262 | 
            -
                  end }
         | 
| 263 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 264 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 265 | 
            -
                end
         | 
| 266 | 
            -
             | 
| 267 | 
            -
                context 'with a nested zero_or_more rule' do
         | 
| 268 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 269 | 
            -
                    rule(:word) { assert(zero_or_more(/\w/)) }
         | 
| 270 | 
            -
                  end }
         | 
| 271 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 272 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 273 | 
            -
                end
         | 
| 274 | 
            -
             | 
| 275 | 
            -
                context 'with a nested one_or_more rule' do
         | 
| 276 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 277 | 
            -
                    rule(:word) { assert(one_or_more(/\w/)) }
         | 
| 278 | 
            -
                  end }
         | 
| 279 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 280 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 281 | 
            -
                end
         | 
| 282 | 
            -
             | 
| 283 | 
            -
                context 'with a nested list rule' do
         | 
| 284 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 285 | 
            -
                    rule(:word) { assert(list(/\w+/, /,/)) }
         | 
| 286 | 
            -
                  end }
         | 
| 287 | 
            -
                  it { should parse('abc,123 ').succeeding.like reference_parser }
         | 
| 288 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 289 | 
            -
                end
         | 
| 290 | 
            -
             | 
| 291 | 
            -
                context 'with a nested list1 rule' do
         | 
| 292 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 293 | 
            -
                    rule(:word) { assert(list1(/\w+/, /,/)) }
         | 
| 294 | 
            -
                  end }
         | 
| 295 | 
            -
                  it { should parse('abc,123 ').succeeding.like reference_parser }
         | 
| 296 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 297 | 
            -
                end
         | 
| 298 | 
            -
             | 
| 299 | 
            -
                context 'with a nested apply rule' do
         | 
| 300 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 301 | 
            -
                    rule(:foo) { match :word }
         | 
| 302 | 
            -
                    rule(:word) { assert /\w+/ }
         | 
| 303 | 
            -
                  end }
         | 
| 304 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 305 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 306 | 
            -
                end
         | 
| 307 | 
            -
             | 
| 308 | 
            -
                context 'with a nested dispatch-action rule' do
         | 
| 309 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 310 | 
            -
                    rule(:word) { assert(dispatch_action(/\w+/)) }
         | 
| 311 | 
            -
                  end }
         | 
| 312 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 313 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 314 | 
            -
                end
         | 
| 315 | 
            -
             | 
| 316 | 
            -
                context 'with a nested token rule' do
         | 
| 317 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 318 | 
            -
                    rule(:word) { assert(token(match(/\w+/))) }
         | 
| 319 | 
            -
                  end }
         | 
| 320 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 321 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 322 | 
            -
                end
         | 
| 323 | 
            -
             | 
| 324 | 
            -
                context 'with a nested skip rule' do
         | 
| 325 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 326 | 
            -
                    rule(:word) { assert(skip(/\w+/)) }
         | 
| 327 | 
            -
                  end }
         | 
| 328 | 
            -
                  it { should parse('abc123  ').succeeding.like reference_parser }
         | 
| 329 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 330 | 
            -
                end
         | 
| 331 | 
            -
              end
         | 
| 332 | 
            -
             | 
| 333 | 
            -
              ########## disallow ##########
         | 
| 334 | 
            -
              context 'given a disallow rule' do
         | 
| 335 | 
            -
             | 
| 336 | 
            -
                context 'with a nested match rule' do
         | 
| 337 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 338 | 
            -
                    rule(:word) { disallow /\w+/ }
         | 
| 339 | 
            -
                  end }
         | 
| 340 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 341 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 342 | 
            -
                end
         | 
| 343 | 
            -
             | 
| 344 | 
            -
                context 'with a nested choice rule' do
         | 
| 345 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 346 | 
            -
                    rule(:word) { disallow(match(/[[:alpha:]]/) | match(/[[:digit:]]/)) }
         | 
| 347 | 
            -
                  end }
         | 
| 348 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 349 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 350 | 
            -
                end
         | 
| 351 | 
            -
             | 
| 352 | 
            -
                context 'with a nested sequence rule' do
         | 
| 353 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 354 | 
            -
                    rule(:word) { disallow(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/)) }
         | 
| 355 | 
            -
                  end }
         | 
| 356 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 357 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 358 | 
            -
                end
         | 
| 359 | 
            -
             | 
| 360 | 
            -
                context 'with a nested optional rule' do
         | 
| 361 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 362 | 
            -
                    rule(:word) { disallow(optional(/\w+/)) }
         | 
| 363 | 
            -
                  end }
         | 
| 364 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 365 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 366 | 
            -
                end
         | 
| 367 | 
            -
             | 
| 368 | 
            -
                context 'with a nested zero_or_more rule' do
         | 
| 369 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 370 | 
            -
                    rule(:word) { disallow(zero_or_more(/\w/)) }
         | 
| 371 | 
            -
                  end }
         | 
| 372 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 373 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 374 | 
            -
                end
         | 
| 375 | 
            -
             | 
| 376 | 
            -
                context 'with a nested one_or_more rule' do
         | 
| 377 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 378 | 
            -
                    rule(:word) { disallow(one_or_more(/\w/)) }
         | 
| 379 | 
            -
                  end }
         | 
| 380 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 381 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 382 | 
            -
                end
         | 
| 383 | 
            -
             | 
| 384 | 
            -
                context 'with a nested list rule' do
         | 
| 385 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 386 | 
            -
                    rule(:word) { disallow(list(/\w+/, /,/)) }
         | 
| 387 | 
            -
                  end }
         | 
| 388 | 
            -
                  it { should parse('   ').failing.like reference_parser }
         | 
| 389 | 
            -
                  it { should parse('abc,123 ').failing.like reference_parser }
         | 
| 390 | 
            -
                end
         | 
| 391 | 
            -
             | 
| 392 | 
            -
                context 'with a nested list1 rule' do
         | 
| 393 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 394 | 
            -
                    rule(:word) { disallow(list1(/\w+/, /,/)) }
         | 
| 395 | 
            -
                  end }
         | 
| 396 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 397 | 
            -
                  it { should parse('abc,123 ').failing.like reference_parser }
         | 
| 398 | 
            -
                end
         | 
| 399 | 
            -
             | 
| 400 | 
            -
                context 'with a nested apply rule' do
         | 
| 401 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 402 | 
            -
                    rule(:foo) { match :word }
         | 
| 403 | 
            -
                    rule(:word) { disallow /\w+/ }
         | 
| 404 | 
            -
                  end }
         | 
| 405 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 406 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 407 | 
            -
                end
         | 
| 408 | 
            -
             | 
| 409 | 
            -
                context 'with a nested dispatch-action rule' do
         | 
| 410 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 411 | 
            -
                    rule(:word) { disallow(dispatch_action(/\w+/)) }
         | 
| 412 | 
            -
                  end }
         | 
| 413 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 414 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 415 | 
            -
                end
         | 
| 416 | 
            -
             | 
| 417 | 
            -
                context 'with a nested token rule' do
         | 
| 418 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 419 | 
            -
                    rule(:word) { disallow(token(match(/\w+/))) }
         | 
| 420 | 
            -
                  end }
         | 
| 421 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 422 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 423 | 
            -
                end
         | 
| 424 | 
            -
             | 
| 425 | 
            -
                context 'with a nested skip rule' do
         | 
| 426 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 427 | 
            -
                    rule(:word) { disallow(skip(/\w+/)) }
         | 
| 428 | 
            -
                  end }
         | 
| 429 | 
            -
                  it { should parse('   ').succeeding.like reference_parser }
         | 
| 430 | 
            -
                  it { should parse('abc123  ').failing.like reference_parser }
         | 
| 431 | 
            -
                end
         | 
| 432 | 
            -
              end
         | 
| 433 | 
            -
             | 
| 434 | 
            -
              ########## dispatch_action ##########
         | 
| 435 | 
            -
              context 'given a dispatch-action rule' do
         | 
| 436 | 
            -
             | 
| 437 | 
            -
                context 'with a nested match rule' do
         | 
| 438 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 439 | 
            -
                    rule(:digits) { dispatch_action(/\d+/) }
         | 
| 440 | 
            -
                  end }
         | 
| 441 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 442 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 443 | 
            -
                end
         | 
| 444 | 
            -
             | 
| 445 | 
            -
                context 'with a nested choice rule' do
         | 
| 446 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 447 | 
            -
                    rule :atom do
         | 
| 448 | 
            -
                      dispatch_action(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/))
         | 
| 449 | 
            -
                    end
         | 
| 450 | 
            -
                  end }
         | 
| 451 | 
            -
             | 
| 452 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 453 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 454 | 
            -
                end
         | 
| 455 | 
            -
             | 
| 456 | 
            -
                context 'with a nested sequence rule' do
         | 
| 457 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 458 | 
            -
                    rule :assignment do
         | 
| 459 | 
            -
                      dispatch_action(
         | 
| 460 | 
            -
                        match(/[[:alpha:]]+/) &
         | 
| 461 | 
            -
                        match('=') &
         | 
| 462 | 
            -
                        match(/[[:digit:]]+/)
         | 
| 463 | 
            -
                      )
         | 
| 464 | 
            -
                    end
         | 
| 465 | 
            -
                  end }
         | 
| 466 | 
            -
             | 
| 467 | 
            -
                  it { should parse('val=42 ').succeeding.like reference_parser }
         | 
| 468 | 
            -
                  it { should parse('val=x').failing.like reference_parser }
         | 
| 469 | 
            -
             | 
| 470 | 
            -
                  context 'with labels' do
         | 
| 471 | 
            -
                    let(:grammar) { define_grammar do
         | 
| 472 | 
            -
                      rule :assignment do
         | 
| 473 | 
            -
                        dispatch_action(
         | 
| 474 | 
            -
                          label(:name, /[[:alpha:]]+/) &
         | 
| 475 | 
            -
                          match('=') &
         | 
| 476 | 
            -
                          label(:value, /[[:digit:]]+/)
         | 
| 477 | 
            -
                        )
         | 
| 478 | 
            -
                      end
         | 
| 479 | 
            -
                    end }
         | 
| 480 | 
            -
                    it { should parse('val=42 ').succeeding.like reference_parser }
         | 
| 481 | 
            -
                  end
         | 
| 482 | 
            -
                end
         | 
| 483 | 
            -
             | 
| 484 | 
            -
                context 'with a nested optional rule' do
         | 
| 485 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 486 | 
            -
                    rule :foo do
         | 
| 487 | 
            -
                      dispatch_action(optional(/\w+/))
         | 
| 488 | 
            -
                    end
         | 
| 489 | 
            -
                  end }
         | 
| 490 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 491 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 492 | 
            -
                end
         | 
| 210 | 
            +
                it { should parse('foo ').succeeding.like reference_parser }
         | 
| 211 | 
            +
                it { should parse('abcde ').succeeding.like reference_parser }
         | 
| 212 | 
            +
                it { should parse('a ').failing.like reference_parser }
         | 
| 493 213 |  | 
| 494 | 
            -
                context 'with  | 
| 214 | 
            +
                context 'with no upper bound' do
         | 
| 495 215 | 
             
                  let(:grammar) { define_grammar do
         | 
| 496 216 | 
             
                    rule :foo do
         | 
| 497 | 
            -
                       | 
| 217 | 
            +
                      repeat(/\w/, 2, nil)
         | 
| 498 218 | 
             
                    end
         | 
| 499 219 | 
             
                  end }
         | 
| 500 220 | 
             
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 501 | 
            -
                  it { should parse(' | 
| 221 | 
            +
                  it { should parse('abcde ').succeeding.like reference_parser }
         | 
| 222 | 
            +
                  it { should parse('a ').failing.like reference_parser }
         | 
| 502 223 | 
             
                end
         | 
| 503 224 |  | 
| 504 | 
            -
                context 'with a  | 
| 225 | 
            +
                context 'with a non-capturing parser' do
         | 
| 505 226 | 
             
                  let(:grammar) { define_grammar do
         | 
| 506 227 | 
             
                    rule :foo do
         | 
| 507 | 
            -
                       | 
| 228 | 
            +
                      repeat(skip(/\w/), 2, 4)
         | 
| 508 229 | 
             
                    end
         | 
| 509 230 | 
             
                  end }
         | 
| 510 231 | 
             
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 511 | 
            -
                  it { should parse(' | 
| 512 | 
            -
             | 
| 513 | 
            -
             | 
| 514 | 
            -
                context 'with a nested apply rule' do
         | 
| 515 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 516 | 
            -
                    rule(:digit) { match /\d/ }
         | 
| 517 | 
            -
                    rule(:foo) { dispatch_action :digit }
         | 
| 518 | 
            -
                  end }
         | 
| 519 | 
            -
                  it { should parse('451a').succeeding.twice.like reference_parser }
         | 
| 520 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 521 | 
            -
                end
         | 
| 522 | 
            -
             | 
| 523 | 
            -
                context 'with a nested token rule' do
         | 
| 524 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 525 | 
            -
                    rule :foo do
         | 
| 526 | 
            -
                      dispatch_action(token(match(/\w+/)))
         | 
| 527 | 
            -
                    end
         | 
| 528 | 
            -
                  end }
         | 
| 529 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 530 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 531 | 
            -
                end
         | 
| 532 | 
            -
             | 
| 533 | 
            -
                context 'with a nested skip rule' do
         | 
| 534 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 535 | 
            -
                    rule :foo do
         | 
| 536 | 
            -
                      dispatch_action(skip(/\w+/))
         | 
| 537 | 
            -
                    end
         | 
| 538 | 
            -
                  end }
         | 
| 539 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 540 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 232 | 
            +
                  it { should parse('abcde ').succeeding.like reference_parser }
         | 
| 233 | 
            +
                  it { should parse('a ').failing.like reference_parser }
         | 
| 541 234 | 
             
                end
         | 
| 542 235 | 
             
              end
         | 
| 543 236 |  | 
| 544 | 
            -
              ##########  | 
| 545 | 
            -
              context 'given a  | 
| 546 | 
            -
             | 
| 547 | 
            -
             | 
| 548 | 
            -
             | 
| 549 | 
            -
                    rule(:num) { direct_action(/\d+/, '|_| _.to_i') }
         | 
| 550 | 
            -
                  end }
         | 
| 551 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 552 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 553 | 
            -
                end
         | 
| 554 | 
            -
             | 
| 555 | 
            -
                context 'with a nested choice rule' do
         | 
| 556 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 557 | 
            -
                    rule :foo do
         | 
| 558 | 
            -
                      direct_action(
         | 
| 559 | 
            -
                        match(/[[:alpha:]]+/) | match(/[[:digit:]]+/),
         | 
| 560 | 
            -
                        '|_| _.size'
         | 
| 561 | 
            -
                      )
         | 
| 562 | 
            -
                    end
         | 
| 563 | 
            -
                  end }
         | 
| 564 | 
            -
             | 
| 565 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 566 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 567 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 568 | 
            -
                end
         | 
| 569 | 
            -
             | 
| 570 | 
            -
                context 'with a nested sequence rule' do
         | 
| 571 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 572 | 
            -
                    rule :assignment do
         | 
| 573 | 
            -
                      direct_action(
         | 
| 574 | 
            -
                        match(/[[:alpha:]]+/) & match('=') & match(/[[:digit:]]+/),
         | 
| 575 | 
            -
                        '|l,_,r| "#{r} -> #{l}"'
         | 
| 576 | 
            -
                      )
         | 
| 577 | 
            -
                    end
         | 
| 578 | 
            -
                  end }
         | 
| 579 | 
            -
             | 
| 580 | 
            -
                  it { should parse('val=42 ').succeeding.like reference_parser }
         | 
| 581 | 
            -
                  it { should parse('val=x').failing.like reference_parser }
         | 
| 582 | 
            -
             | 
| 583 | 
            -
                  context 'with labels' do
         | 
| 584 | 
            -
                    let(:grammar) { define_grammar do
         | 
| 585 | 
            -
                      rule :assignment do
         | 
| 586 | 
            -
                        direct_action(
         | 
| 587 | 
            -
                          label(:name, /[[:alpha:]]+/) & match('=') & label(:value, /[[:digit:]]+/),
         | 
| 588 | 
            -
                          '"#{value} -> #{name}"'
         | 
| 589 | 
            -
                        )
         | 
| 590 | 
            -
                      end
         | 
| 591 | 
            -
                    end }
         | 
| 592 | 
            -
                    it { should parse('val=42 ').succeeding.like reference_parser }
         | 
| 237 | 
            +
              ########## list ##########
         | 
| 238 | 
            +
              context 'given a list rule' do
         | 
| 239 | 
            +
                let(:grammar) { define_grammar do
         | 
| 240 | 
            +
                  rule :foo do
         | 
| 241 | 
            +
                    list(/\w+/, /[,;]/, 2, nil)
         | 
| 593 242 | 
             
                  end
         | 
| 594 | 
            -
                end
         | 
| 595 | 
            -
             | 
| 596 | 
            -
                 | 
| 597 | 
            -
             | 
| 598 | 
            -
                    rule :foo do
         | 
| 599 | 
            -
                      direct_action(optional(/\w+/), '|_| _.size')
         | 
| 600 | 
            -
                    end
         | 
| 601 | 
            -
                  end }
         | 
| 602 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 603 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 604 | 
            -
                end
         | 
| 605 | 
            -
             | 
| 606 | 
            -
                context 'with a nested zero-or-more rule' do
         | 
| 607 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 608 | 
            -
                    rule :foo do
         | 
| 609 | 
            -
                      direct_action(zero_or_more(/\w/), '|_| _.size')
         | 
| 610 | 
            -
                    end
         | 
| 611 | 
            -
                  end }
         | 
| 612 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 613 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 614 | 
            -
                end
         | 
| 615 | 
            -
             | 
| 616 | 
            -
                context 'with a nested one-or-more rule' do
         | 
| 617 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 618 | 
            -
                    rule :foo do
         | 
| 619 | 
            -
                      direct_action(one_or_more(/\w/), '|_| _.size')
         | 
| 620 | 
            -
                    end
         | 
| 621 | 
            -
                  end }
         | 
| 622 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 623 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 624 | 
            -
                end
         | 
| 625 | 
            -
             | 
| 626 | 
            -
                context 'with a nested apply rule' do
         | 
| 627 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 628 | 
            -
                    rule(:digit) { match /\d/ }
         | 
| 629 | 
            -
                    rule(:foo) { direct_action :digit, '|_| _.to_i' }
         | 
| 630 | 
            -
                  end }
         | 
| 631 | 
            -
                  it { should parse('451a').succeeding.twice.like reference_parser }
         | 
| 632 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 633 | 
            -
                end
         | 
| 634 | 
            -
             | 
| 635 | 
            -
                context 'with a nested token rule' do
         | 
| 636 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 637 | 
            -
                    rule :foo do
         | 
| 638 | 
            -
                      direct_action(token(/\w+/), '|_| _.size')
         | 
| 639 | 
            -
                    end
         | 
| 640 | 
            -
                  end }
         | 
| 641 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 642 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 643 | 
            -
                end
         | 
| 243 | 
            +
                end }
         | 
| 244 | 
            +
                it { should parse('foo  ').failing.like reference_parser }
         | 
| 245 | 
            +
                it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 246 | 
            +
                it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 644 247 |  | 
| 645 | 
            -
                context 'with  | 
| 248 | 
            +
                context 'with an upper bound' do
         | 
| 646 249 | 
             
                  let(:grammar) { define_grammar do
         | 
| 647 250 | 
             
                    rule :foo do
         | 
| 648 | 
            -
                       | 
| 649 | 
            -
                    end
         | 
| 650 | 
            -
                  end }
         | 
| 651 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 652 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 653 | 
            -
                end
         | 
| 654 | 
            -
              end
         | 
| 655 | 
            -
             | 
| 656 | 
            -
              ########## token ##########
         | 
| 657 | 
            -
              context 'given a token rule' do
         | 
| 658 | 
            -
             | 
| 659 | 
            -
                context 'with a nested match rule' do
         | 
| 660 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 661 | 
            -
                    rule(:digits) { token(match(/\d+/)) }
         | 
| 662 | 
            -
                  end }
         | 
| 663 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 664 | 
            -
                  it { should parse('hi').failing.like reference_parser }
         | 
| 665 | 
            -
                end
         | 
| 666 | 
            -
             | 
| 667 | 
            -
                context 'with a nested choice rule' do
         | 
| 668 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 669 | 
            -
                    rule(:atom) do
         | 
| 670 | 
            -
                      token(match(/[[:alpha:]]+/) | match(/[[:digit:]]+/))
         | 
| 251 | 
            +
                      list(/\w+/, /[,;]/, 2, 4)
         | 
| 671 252 | 
             
                    end
         | 
| 672 253 | 
             
                  end }
         | 
| 673 | 
            -
             | 
| 674 | 
            -
                  it { should parse(' | 
| 675 | 
            -
                  it { should parse(' | 
| 676 | 
            -
             | 
| 677 | 
            -
                  context 'with non-capturing choices' do
         | 
| 678 | 
            -
                    let(:grammar) { define_grammar do
         | 
| 679 | 
            -
                      rule(:atom) do
         | 
| 680 | 
            -
                        token(skip(/[[:alpha:]]+/) | match(/[[:digit:]]+/))
         | 
| 681 | 
            -
                      end
         | 
| 682 | 
            -
                    end }
         | 
| 683 | 
            -
                    it { should parse('abc123 ').succeeding.like reference_parser }
         | 
| 684 | 
            -
                    it { should parse('==').failing.like reference_parser }
         | 
| 685 | 
            -
                  end
         | 
| 686 | 
            -
                end
         | 
| 687 | 
            -
             | 
| 688 | 
            -
                context 'with a nested sequence rule' do
         | 
| 689 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 690 | 
            -
                    rule(:atom) do
         | 
| 691 | 
            -
                      token(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/))
         | 
| 692 | 
            -
                    end
         | 
| 693 | 
            -
                  end }
         | 
| 694 | 
            -
             | 
| 695 | 
            -
                  it { should parse('foo42!').succeeding.like reference_parser }
         | 
| 696 | 
            -
                  it { should parse('val=x').failing.like reference_parser }
         | 
| 697 | 
            -
             | 
| 698 | 
            -
                  context 'with non-capturing parsers' do
         | 
| 699 | 
            -
                    let(:grammar) { define_grammar do
         | 
| 700 | 
            -
                      rule :foo do
         | 
| 701 | 
            -
                        token(match(/[[:alpha:]]+/) & skip(/\s+/) & match(/[[:digit:]]+/))
         | 
| 702 | 
            -
                      end
         | 
| 703 | 
            -
                    end }
         | 
| 704 | 
            -
                    it { should parse('foo 42').succeeding.like reference_parser }
         | 
| 705 | 
            -
                    it { should parse('foo bar').failing.like reference_parser }
         | 
| 706 | 
            -
                  end
         | 
| 254 | 
            +
                  it { should parse('foo  ').failing.like reference_parser }
         | 
| 255 | 
            +
                  it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 256 | 
            +
                  it { should parse('a,b,c,d,e  ').succeeding.like reference_parser }
         | 
| 257 | 
            +
                  it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 707 258 | 
             
                end
         | 
| 708 259 |  | 
| 709 | 
            -
                context 'with a  | 
| 260 | 
            +
                context 'with a non-capturing parser' do
         | 
| 710 261 | 
             
                  let(:grammar) { define_grammar do
         | 
| 711 262 | 
             
                    rule :foo do
         | 
| 712 | 
            -
                       | 
| 263 | 
            +
                      list(skip(/\w+/), /[,;]/, 2, nil)
         | 
| 713 264 | 
             
                    end
         | 
| 714 265 | 
             
                  end }
         | 
| 266 | 
            +
                  it { should parse('foo  ').failing.like reference_parser }
         | 
| 267 | 
            +
                  it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 268 | 
            +
                  it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 715 269 |  | 
| 716 | 
            -
                   | 
| 717 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 718 | 
            -
             | 
| 719 | 
            -
                  context 'with a non-capturing rule' do
         | 
| 270 | 
            +
                  context 'with an upper bound' do
         | 
| 720 271 | 
             
                    let(:grammar) { define_grammar do
         | 
| 721 272 | 
             
                      rule :foo do
         | 
| 722 | 
            -
                         | 
| 273 | 
            +
                        list(skip(/\w+/), /[,;]/, 2, 4)
         | 
| 723 274 | 
             
                      end
         | 
| 724 275 | 
             
                    end }
         | 
| 725 | 
            -
                    it { should parse('foo | 
| 726 | 
            -
                    it { should parse(' | 
| 276 | 
            +
                    it { should parse('foo  ').failing.like reference_parser }
         | 
| 277 | 
            +
                    it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 278 | 
            +
                    it { should parse('a,b,c,d,e  ').succeeding.like reference_parser }
         | 
| 279 | 
            +
                    it { should parse('foo,bar,  ').succeeding.like reference_parser }
         | 
| 727 280 | 
             
                  end
         | 
| 728 | 
            -
                end
         | 
| 729 | 
            -
             | 
| 730 | 
            -
                context 'with a nested zero-or-more rule' do
         | 
| 731 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 732 | 
            -
                    rule :foo do
         | 
| 733 | 
            -
                      token(zero_or_more(/\w/))
         | 
| 734 | 
            -
                    end
         | 
| 735 | 
            -
                  end }
         | 
| 736 281 |  | 
| 737 | 
            -
                   | 
| 738 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 739 | 
            -
             | 
| 740 | 
            -
                  context 'with a non-capturing rule' do
         | 
| 282 | 
            +
                  context 'with "zero-or-more" bounds' do
         | 
| 741 283 | 
             
                    let(:grammar) { define_grammar do
         | 
| 742 284 | 
             
                      rule :foo do
         | 
| 743 | 
            -
                         | 
| 285 | 
            +
                        list(skip(/\w+/), /[,;]/, 0, nil)
         | 
| 744 286 | 
             
                      end
         | 
| 745 287 | 
             
                    end }
         | 
| 746 | 
            -
                    it { should parse(' | 
| 747 | 
            -
                    it { should parse(' | 
| 288 | 
            +
                    it { should parse('  ').succeeding.like reference_parser }
         | 
| 289 | 
            +
                    it { should parse('foo  ').succeeding.like reference_parser }
         | 
| 290 | 
            +
                    it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 748 291 | 
             
                  end
         | 
| 749 | 
            -
                end
         | 
| 750 | 
            -
             | 
| 751 | 
            -
                context 'with a nested one-or-more rule' do
         | 
| 752 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 753 | 
            -
                    rule :foo do
         | 
| 754 | 
            -
                      token(one_or_more(/\w/))
         | 
| 755 | 
            -
                    end
         | 
| 756 | 
            -
                  end }
         | 
| 757 | 
            -
             | 
| 758 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 759 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 760 292 |  | 
| 761 | 
            -
                  context 'with  | 
| 293 | 
            +
                  context 'with "one-or-more" bounds' do
         | 
| 762 294 | 
             
                    let(:grammar) { define_grammar do
         | 
| 763 295 | 
             
                      rule :foo do
         | 
| 764 | 
            -
                         | 
| 296 | 
            +
                        list(skip(/\w+/), /[,;]/, 1, nil)
         | 
| 765 297 | 
             
                      end
         | 
| 766 298 | 
             
                    end }
         | 
| 767 | 
            -
                    it { should parse(' | 
| 768 | 
            -
                    it { should parse(' | 
| 299 | 
            +
                    it { should parse('  ').failing.like reference_parser }
         | 
| 300 | 
            +
                    it { should parse('foo  ').succeeding.like reference_parser }
         | 
| 301 | 
            +
                    it { should parse('foo,bar;baz  ').succeeding.like reference_parser }
         | 
| 769 302 | 
             
                  end
         | 
| 770 303 | 
             
                end
         | 
| 771 | 
            -
             | 
| 772 | 
            -
                context 'with a nested apply rule' do
         | 
| 773 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 774 | 
            -
                    rule(:foo) { token(match(:digits)) }
         | 
| 775 | 
            -
                    rule(:digits) { match(/\d+/) }
         | 
| 776 | 
            -
                  end }
         | 
| 777 | 
            -
             | 
| 778 | 
            -
                  it { should parse('451a').succeeding.like reference_parser }
         | 
| 779 | 
            -
                  it { should parse('hi').failing.like reference_parser }
         | 
| 780 | 
            -
             | 
| 781 | 
            -
                  context 'applying a non-capturing rule' do
         | 
| 782 | 
            -
                    let(:grammar) { define_grammar do
         | 
| 783 | 
            -
                      rule(:foo) { token(match(:digits)) }
         | 
| 784 | 
            -
                      rule(:digits) { skip(/\d+/) }
         | 
| 785 | 
            -
                    end }
         | 
| 786 | 
            -
                    it { should parse('451a').succeeding.like reference_parser }
         | 
| 787 | 
            -
                    it { should parse('hi').failing.like reference_parser }
         | 
| 788 | 
            -
                  end
         | 
| 789 | 
            -
                end
         | 
| 790 | 
            -
             | 
| 791 | 
            -
                context 'with a nested dispatch-action rule' do
         | 
| 792 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 793 | 
            -
                    rule(:foo) { token(dispatch_action(/\w+/)) }
         | 
| 794 | 
            -
                  end }
         | 
| 795 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 796 | 
            -
                  it { should parse('  ').failing.like reference_parser }
         | 
| 797 | 
            -
                end
         | 
| 798 | 
            -
             | 
| 799 | 
            -
                context 'with a nested skip rule' do
         | 
| 800 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 801 | 
            -
                    rule(:foo) { token(skip(/\w+/)) }
         | 
| 802 | 
            -
                  end }
         | 
| 803 | 
            -
                  it { should parse('abc123').succeeding.like reference_parser }
         | 
| 804 | 
            -
                  it { should parse('  ').failing.like reference_parser }
         | 
| 805 | 
            -
                end
         | 
| 806 304 | 
             
              end
         | 
| 807 305 |  | 
| 808 | 
            -
              ##########  | 
| 809 | 
            -
              context 'given  | 
| 810 | 
            -
             | 
| 811 | 
            -
             | 
| 812 | 
            -
                   | 
| 813 | 
            -
             | 
| 814 | 
            -
             | 
| 815 | 
            -
             | 
| 816 | 
            -
             | 
| 817 | 
            -
                end
         | 
| 818 | 
            -
             | 
| 819 | 
            -
                context 'with a nested choice rule' do
         | 
| 820 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 821 | 
            -
                    rule(:ws) do
         | 
| 822 | 
            -
                      skip(match(/\s+/) | match(/\#[^\n]*/))
         | 
| 823 | 
            -
                    end
         | 
| 824 | 
            -
                  end }
         | 
| 825 | 
            -
                  it { should parse('   # hi there ').succeeding.twice.like reference_parser }
         | 
| 826 | 
            -
                  it { should parse('hi').failing.like reference_parser }
         | 
| 827 | 
            -
                end
         | 
| 828 | 
            -
             | 
| 829 | 
            -
                context 'with a nested sequence rule' do
         | 
| 830 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 831 | 
            -
                    rule :foo do
         | 
| 832 | 
            -
                      skip(match(/[[:alpha:]]+/) & match(/[[:digit:]]+/))
         | 
| 833 | 
            -
                    end
         | 
| 834 | 
            -
                  end }
         | 
| 835 | 
            -
                  it { should parse('foo42!').succeeding.like reference_parser }
         | 
| 836 | 
            -
                  it { should parse('val=x').failing.like reference_parser }
         | 
| 837 | 
            -
                end
         | 
| 838 | 
            -
             | 
| 839 | 
            -
                context 'with a nested optional rule' do
         | 
| 840 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 841 | 
            -
                    rule :foo do
         | 
| 842 | 
            -
                      skip(optional(/\w+/))
         | 
| 843 | 
            -
                    end
         | 
| 844 | 
            -
                  end }
         | 
| 845 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 846 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 847 | 
            -
                end
         | 
| 848 | 
            -
             | 
| 849 | 
            -
                context 'with a nested zero-or-more rule' do
         | 
| 850 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 851 | 
            -
                    rule :foo do
         | 
| 852 | 
            -
                      skip(zero_or_more(/\w/))
         | 
| 853 | 
            -
                    end
         | 
| 854 | 
            -
                  end }
         | 
| 855 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 856 | 
            -
                  it { should parse('    ').succeeding.like reference_parser }
         | 
| 857 | 
            -
                end
         | 
| 858 | 
            -
             | 
| 859 | 
            -
                context 'with a nested one-or-more rule' do
         | 
| 860 | 
            -
                  let(:grammar) { define_grammar do
         | 
| 861 | 
            -
                    rule :foo do
         | 
| 862 | 
            -
                      skip(one_or_more(/\w/))
         | 
| 863 | 
            -
                    end
         | 
| 864 | 
            -
                  end }
         | 
| 865 | 
            -
                  it { should parse('foo ').succeeding.like reference_parser }
         | 
| 866 | 
            -
                  it { should parse('    ').failing.like reference_parser }
         | 
| 867 | 
            -
                end
         | 
| 306 | 
            +
              ########## apply ##########
         | 
| 307 | 
            +
              context 'given an apply rule' do
         | 
| 308 | 
            +
                let(:grammar) { define_grammar do
         | 
| 309 | 
            +
                  rule(:digit) { match /\d/ }
         | 
| 310 | 
            +
                  rule(:foo) { match :digit }
         | 
| 311 | 
            +
                end }
         | 
| 312 | 
            +
                it { should parse('451 ').twice.succeeding.like reference_parser }
         | 
| 313 | 
            +
                it { should parse('hi').failing.like reference_parser }
         | 
| 314 | 
            +
              end
         | 
| 868 315 |  | 
| 869 | 
            -
             | 
| 870 | 
            -
             | 
| 871 | 
            -
             | 
| 872 | 
            -
             | 
| 873 | 
            -
             | 
| 874 | 
            -
             | 
| 875 | 
            -
             | 
| 876 | 
            -
                 | 
| 316 | 
            +
              ########## eof ##########
         | 
| 317 | 
            +
              context 'given eof' do
         | 
| 318 | 
            +
                let(:grammar) { define_grammar do
         | 
| 319 | 
            +
                  rule(:foo) { eof }
         | 
| 320 | 
            +
                end }
         | 
| 321 | 
            +
                it { should parse('').succeeding.like reference_parser }
         | 
| 322 | 
            +
                it { should parse('foo').from(3).succeeding.like reference_parser }
         | 
| 323 | 
            +
                it { should parse('foo').failing.like reference_parser }
         | 
| 877 324 | 
             
              end
         | 
| 878 325 |  | 
| 326 | 
            +
              ########## E ##########
         | 
| 327 | 
            +
              context 'given "E" symbol' do
         | 
| 328 | 
            +
                let(:grammar) { define_grammar do
         | 
| 329 | 
            +
                  rule(:foo) { e }
         | 
| 330 | 
            +
                end }
         | 
| 331 | 
            +
                it { should parse('').succeeding.like reference_parser }
         | 
| 332 | 
            +
                it { should parse('foo').succeeding.like reference_parser }
         | 
| 333 | 
            +
              end
         | 
| 879 334 | 
             
            end
         |