package de.plugh.compositeparse.parsers; import de.plugh.compositeparse.Block; import de.plugh.compositeparse.Pair; import de.plugh.compositeparse.ParseException; import de.plugh.compositeparse.Parser; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Function; /** * Decide which parser to use from a list of "body" parsers and their "head"s. *

* If a "head" parses successfully, the corresponding "body" parser must be successful, otherwise a parse exception is * raised. If no "head" is successful, the {@link Decision} parser fails too. * * @param return type of the parser */ public class Decision implements Parser { private final List, Parser>> pairs; /** * Create a new {@link Decision} parser from all passed arguments, which are "head"-"body" pairs. * * @param pairs multiple "head"-"body" pairs */ @SafeVarargs public Decision(Pair, Parser>... pairs) { this.pairs = new ArrayList<>(); Collections.addAll(this.pairs, pairs); } /** * Create a new {@link Decision} parser from a list of "head"-"body" pairs. * * @param pairs a list of "head"-"body" pairs */ public Decision(List, Parser>> pairs) { this.pairs = new ArrayList<>(pairs); } @Override public Function, String> getNamingScheme() { return Block::alternative; } @Override public T read(Block block) throws ParseException { for (Pair, Parser> pair : pairs) { try { pair.getFirst().parse(block); } catch (ParseException e) { continue; } return pair.getSecond().parse(block); } throw new ParseException(block); } }