Core PEG rule "Choice", here called firstOf. Tries each sub rule in turn, return first match. @param objs rules/string literals/char literals/execs @return rule
(Object... objs)
| 785 | * @return rule |
| 786 | */ |
| 787 | public ParentRule firstOf(Object... objs) { |
| 788 | List<Step> steps = asSteps(objs); |
| 789 | PegLegRule<V> rule; |
| 790 | if (steps.size() == 1 && steps.get(0).isRule()) { |
| 791 | rule = steps.get(0).asRule(); |
| 792 | } else { |
| 793 | rule = () -> { |
| 794 | get().pushFrame("firstOf()"); |
| 795 | SingleNode<V> values = get().saveValues(); |
| 796 | int cnt = get().frameDepth(); |
| 797 | for (Step r : steps) { |
| 798 | if (r.isRule()) { |
| 799 | get().pushFrame(); |
| 800 | RuleReturn<V> ret = r.asRule().rule(); |
| 801 | if (ret.matched()) { |
| 802 | get().trimFramesTo(cnt); |
| 803 | return get().ruleReturn(true, true); |
| 804 | } |
| 805 | get().resetToLastFrame(); |
| 806 | } else { |
| 807 | if (!r.asExec().exec()) { |
| 808 | get().rollback(cnt, values); |
| 809 | return get().ruleReturn(false, false); |
| 810 | } |
| 811 | } |
| 812 | } |
| 813 | get().rollback(cnt, values); |
| 814 | return get().ruleReturn(false, false); |
| 815 | }; |
| 816 | } |
| 817 | return new ParentRule(rule); |
| 818 | } |
| 819 | |
| 820 | /** |
| 821 | * Core PEG Rule, "Test" returns true if sequence of rules matches, but does not consume input. |