/** Allows the overloads of "or()" to call the varargs version of "or" with no ambiguity. */ private static Parser<Object> alt(Parser<?>... alternatives) { return or(alternatives); }
/** * {@code p1.or(p2)} is equivalent to {@code p1 | p2} in EBNF. * * @param alternative the alternative parser to run if this fails. */ public final Parser<T> or(Parser<? extends T> alternative) { return Parsers.or(this, alternative); }
private static Parser<?> slice(Operator[] ops, int begin, int end) { Parser<?>[] ps = new Parser<?>[end - begin]; for (int i = 0; i < ps.length; i++) { ps[i] = ops[i + begin].op; } return Parsers.or(ps); }
/** * A {@link Parser} that returns {@code defaultValue} if {@code this} fails with no partial match. */ public final Parser<T> optional(T defaultValue) { return Parsers.or(this, Parsers.constant(defaultValue)); }
/** * A {@link Parser} that tries each alternative parser in {@code alternatives}. */ public static <T> Parser<T> or(Iterable<? extends Parser<? extends T>> alternatives) { return or(toArray(alternatives)); }
static Parser<Modifier> modifier(Parser<Expression> expr) { return Parsers.or(annotation(expr), SYSTEM_MODIFIER); }
/** * {@code p.optional()} is equivalent to {@code p?} in EBNF. {@code null} is the result when * {@code this} fails with no partial match. * * @deprecated since 3.0. Use {@link #optional(null)} or {@link #asOptional} instead. */ @Deprecated public final Parser<T> optional() { return Parsers.or(this, Parsers.<T>always()); }
static Parser<Modifier> systemModifier(SystemModifier... modifiers) { List<Parser<Modifier>> list = new ArrayList<Parser<Modifier>>(modifiers.length); for (Modifier modifier : modifiers) { list.add(term(modifier.toString()).retn(modifier)); } return Parsers.or(list); }
/** * A {@link Parser} that runs {@code this} for 0 ore more times separated and optionally terminated by {@code * delim}. For example: {@code "foo;foo;foo"} and {@code "foo;foo;"} both matches {@code foo.sepEndBy(semicolon)}. * * <p>The return values are collected in a {@link List}. */ public final Parser<List<T>> sepEndBy(Parser<?> delim) { return Parsers.or(sepEndBy1(delim), EmptyListParser.<T>instance()); }
/** * A {@link Parser} that runs {@code this} 0 or more times separated by {@code delim}. * * <p>The return values are collected in a {@link List}. */ public final Parser<List<T>> sepBy(Parser<?> delim) { return Parsers.or(sepBy1(delim), EmptyListParser.<T>instance()); }
/** A {@link Parser} that recognizes a token identified by any of {@code tokenNames}. */ public Parser<Token> token(String... tokenNames) { if (tokenNames.length == 0) return Parsers.never(); @SuppressWarnings("unchecked") Parser<Token>[] ps = new Parser[tokenNames.length]; for(int i = 0; i < tokenNames.length; i++) { ps[i] = Parsers.token(InternalFunctors.tokenWithSameValue(word(tokenNames[i]))); } return Parsers.or(ps); }
/** * A {@link Parser} that greedily runs {@code tokenizer}, and translates line feed characters * ({@code '\n'}) to {@code indent} and {@code outdent} tokens. * Return values are wrapped in {@link Token} objects and collected in a {@link List}. * Patterns recognized by {@code delim} are ignored. */ public Parser<List<Token>> lexer(Parser<?> tokenizer, Parser<?> delim) { Parser<?> lf = Scanners.isChar('\n').retn(Punctuation.LF); return Parsers.or(tokenizer, lf).lexer(delim) .map(tokens -> analyzeIndentations(tokens, Punctuation.LF)); }
static Parser<OrderBy.Item> orderByItem(Parser<Expression> expr) { return Parsers.sequence( expr, Parsers.or(TerminalParser.term("asc").retn(true), TerminalParser.term("desc").retn(false)).optional(true), OrderBy.Item::new); }
static Parser<Rule> rule() { Parser.Reference<Rule> ref = Parser.newReference(); Parser<Rule> atom = Parsers.or(LITERAL, IDENT, unit(ref.lazy())); Parser<Rule> parser = alternative(sequential(atom)); ref.set(parser); return parser; }
static Parser<Rule> unit(Parser<Rule> rule) { return Parsers.or( rule.between(TerminalParser.term("("), TerminalParser.term(")")), rule.between(TerminalParser.INDENTATION.indent(), TerminalParser.INDENTATION.outdent())); }
static Parser<Expression> expression(Parser<Expression> cond) { Parser.Reference<Expression> reference = Parser.newReference(); Parser<Expression> lazyExpr = reference.lazy(); Parser<Expression> atom = Parsers.or( NUMBER, WILDCARD, QUALIFIED_NAME, simpleCase(lazyExpr), fullCase(cond, lazyExpr)); Parser<Expression> expression = arithmetic(atom).label("expression"); reference.set(expression); return expression; }
static Parser<NumberType> numberType(NumberType defaultType) { return Parsers.or( Scanners.among("lL").retn(NumberType.LONG), Scanners.among("fF").retn(NumberType.FLOAT), Scanners.among("dD").retn(NumberType.DOUBLE), Parsers.constant(defaultType) ); } }
static Parser<TypeLiteral> wildcard(Parser<TypeLiteral> type) { return Parsers.or( phrase("? extends").next(type).map(UpperBoundWildcard::new), phrase("? super").next(type).map(LowerBoundWildcard::new), term("?").retn(new UpperBoundWildcard(null))); } }
/************************** boolean expressions ****************************/ static Parser<Expression> compare(Parser<Expression> expr) { return Parsers.or( compare(expr, ">", Op.GT), compare(expr, ">=", Op.GE), compare(expr, "<", Op.LT), compare(expr, "<=", Op.LE), compare(expr, "=", Op.EQ), compare(expr, "<>", Op.NE), nullCheck(expr), like(expr), between(expr)); }
static Parser<Statement> forStatement(Parser<Expression> expr, Parser<Statement> stmt) { return Parsers.sequence( phrase("for (").next(Parsers.or(varStatement(expr), expressionList(expr), NOP)), expr.optional(), between(term(";"), expr.sepBy(term(",")), term(")")), stmt, ForStatement::new); }