/** * {@code p.asOptional()} is equivalent to {@code p?} in EBNF. {@code Optional.empty()} * is the result when {@code this} fails with no partial match. Note that {@link Optional} * prohibits nulls so make sure {@code this} does not result in {@code null}. * * @since 3.0 */ public final Parser<Optional<T>> asOptional() { return map(Optional::of).optional(Optional.empty()); }
static Parser<Relation> select( Parser<Expression> expr, Parser<Expression> cond, Parser<Relation> rel) { return Parsers.sequence( SELECT_CLAUSE, list(projection(expr)), fromClause(join(rel, cond)), whereClause(cond).optional(), groupByClause(expr, cond).optional(), orderByClause(expr).optional(), Select::new); }
static Parser<Declaration> classDef(Parser<Modifier> mod, Parser<Member> member) { return Parsers.sequence( mod.many(), term("class").next(Terminals.Identifier.PARSER), TYPE_PARAMETERS.optional(), term("extends").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL).optional(), term("implements").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(), body(member), ClassDef::new); }
static Parser<Statement> switchStatement(Parser<Expression> expr, Parser<Statement> stmt) { return Parsers.sequence( between(phrase("switch ("), expr, phrase(") {")), Parsers.pair(between(term("case"), expr, term(":")), stmt.optional()).many(), phrase("default :").next(stmt.optional()).optional().followedBy(term("}")), SwitchStatement::new); }
static Parser<Declaration> interfaceDef(Parser<Modifier> mod, Parser<Member> member) { return Parsers.sequence( mod.many(), term("interface").next(Terminals.Identifier.PARSER), TYPE_PARAMETERS.optional(), term("extends").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(), body(member), InterfaceDef::new); }
static Parser<Expression> simpleNewExpression(Parser<Expression> arg, Parser<DefBody> body) { return Parsers.sequence( term("new").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL), argumentList(arg), body.optional(), (type, args, defBody) -> new NewExpression(null, type, args, defBody)); }
static Parser<UnaryOperator<Expression>> qualifiedNew(Parser<Expression> arg, Parser<DefBody> body) { return Parsers.sequence( phrase(". new").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL), argumentList(arg), body.optional(), (t, a, b) -> q -> new NewExpression(q, t, a, b)); }
static Parser<List<TypeLiteral>> optionalTypeArgs(Parser<TypeLiteral> parser) { return between(term("<"), parser.sepBy1(term(",")), term(">")) .optional(TypeLiteralParser.EMPTY_TYPE_ARGUMENT_LIST); }
static Parser<Annotation> annotation(Parser<Expression> expr) { Parser<Annotation.Element> element = Parsers.sequence( Terminals.Identifier.PARSER.followedBy(term("=")).atomic().optional(), ExpressionParser.arrayInitializerOrRegularExpression(expr), Annotation.Element::new); return Parsers.sequence( term("@").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL), paren(element.sepBy(term(","))).optional(), Annotation::new); }
static Parser<GroupBy> groupByClause(Parser<Expression> expr, Parser<Expression> cond) { return Parsers.sequence( TerminalParser.phrase("group by").next(list(expr)), TerminalParser.phrase("having").next(cond).optional(), GroupBy::new); }
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<Statement> assertStatement(Parser<Expression> expr) { return Parsers.sequence( term("assert").next(expr), term(":").next(expr).optional().followedBy(term(";")), AssertStatement::new); }
static Parser<Member> fieldDef(Parser<Expression> initializer) { return Parsers.sequence( StatementParser.modifier(initializer).many(), TypeLiteralParser.TYPE_LITERAL, Terminals.Identifier.PARSER, term("=").next(ExpressionParser.arrayInitializerOrRegularExpression(initializer)) .optional(), term(";"), (modifiers, type, name, value, __) -> new FieldDef(modifiers, type, name ,value)); }
static Parser<Expression> simpleCase(Parser<Expression> expr) { return Parsers.sequence( term("case").next(expr), whenThens(expr, expr), term("else").next(expr).optional().followedBy(term("end")), SimpleCaseExpression::new); }
static Parser<Statement> ifStatement(Parser<Expression> expr, Parser<Statement> stmt) { return Parsers.sequence( between(phrase("if ("), expr, term(")")), stmt, Parsers.pair(between(phrase("else if ("), expr, term(")")), stmt).many(), term("else").next(stmt).optional(), IfStatement::new); }
static Parser<Statement> varStatement(Parser<Expression> expr) { Parser<Expression> initializer = term("=").next(ExpressionParser.arrayInitializerOrRegularExpression(expr)); Parser<VarStatement.Var> var = Parsers.sequence( Terminals.Identifier.PARSER, initializer.optional(), VarStatement.Var::new); return Parsers.sequence( modifier(expr).many(), TypeLiteralParser.TYPE_LITERAL, var.sepBy1(term(",")).followedBy(term(";")), VarStatement::new); }
static Parser<Expression> newArrayWithExplicitLength(Parser<Expression> expr) { return Parsers.sequence(term("new").next(TypeLiteralParser.TYPE_LITERAL), expr.between(term("["), term("]")), Parsers.between(term("{"), expr.sepBy(term(",")), term("}")).optional(), NewArrayExpression::new); }
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); }
static Parser<Member> constructorDef(Parser<Modifier> mod, Parser<Statement> stmt) { return Parsers.sequence( mod.many(), Terminals.Identifier.PARSER, term("(").next(StatementParser.parameter(mod).sepBy(term(","))).followedBy(term(")")), term("throws").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(), StatementParser.blockStatement(stmt), ConstructorDef::new); }
static Parser<Statement> tryStatement(Parser<Modifier> mod, Parser<Statement> stmt) { Parser<BlockStatement> block = blockStatement(stmt); return Parsers.sequence( term("try").next(block), Parsers.sequence( term("catch").next(between(term("("), parameter(mod), term(")"))), block, TryStatement.CatchBlock::new).many(), term("finally").next(block).optional(), TryStatement::new); }