/** * A {@link Parser} that runs {@code this} between {@code before} and {@code after}. The return value of {@code * this} is preserved. * * <p>Equivalent to {@link Parsers#between(Parser, Parser, Parser)}, which preserves the natural order of the * parsers in the argument list, but is a bit more verbose. */ public final Parser<T> between(Parser<?> before, Parser<?> after) { return before.next(followedBy(after)); }
/** * A {@link Parser} that runs {@code this} 1 or more times separated by {@code delim}. * * <p>The return values are collected in a {@link List}. */ public final Parser<List<T>> sepBy1(Parser<?> delim) { final Parser<T> afterFirst = delim.asDelimiter().next(this); return next((Function<T, Parser<List<T>>>) firstValue -> new RepeatAtLeastParser<T>( afterFirst, 0, ListFactory.arrayListFactoryWithFirstElement(firstValue))); }
private static Parser<UnaryOperator<Relation>> joinOn( Parser<JoinType> joinType, Parser<Relation> right, Parser<Expression> cond) { return Parsers.sequence( joinType, right, TerminalParser.term("on").next(cond), (t, r, c) -> l -> new JoinRelation(l, t, r, c)); }
/** * A scanner for a non-nestable block comment that starts with {@code begin} and ends with * {@code end}. * * @param begin begins a block comment * @param end ends a block comment * @param commented the commented pattern. * @return the Scanner for the block comment. */ public static Parser<Void> blockComment(Parser<Void> begin, Parser<Void> end, Parser<?> commented) { return Parsers.sequence(begin, end.not().next(commented).skipMany(), end); }
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); }
/** * A {@link Parser} that matches this parser zero or many times * until the given parser succeeds. The input that matches the given parser * will not be consumed. The input that matches this parser will * be collected in a list that will be returned by this function. * * @since 2.2 */ public final Parser<List<T>> until(Parser<?> parser) { return parser.not().next(this).many().followedBy(parser.peek()); }
static Parser<Declaration> annotationDef(Parser<Modifier> mod, Parser<Member> member) { return Parsers.sequence( mod.many(), phrase("@ interface").next(Terminals.Identifier.PARSER), body(member), AnnotationDef::new); }
static Parser<Expression> notIn(Parser<Expression> expr) { return Parsers.sequence( expr, phrase("not in").next(tuple(expr)), (e, t) -> new BinaryExpression(e, Op.NOT_IN, t)); }
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<Statement> doWhileStatement(Parser<Statement> stmt, Parser<Expression> expr) { return Parsers.sequence( term("do").next(stmt), between(phrase("while ("), expr, phrase(") ;")), DoWhileStatement::new); }
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<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> 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); }