/** * 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} for 1 or more times delimited and terminated by {@code delim}. * * <p>The return values are collected in a {@link List}. */ public final Parser<List<T>> endBy1(Parser<?> delim) { return followedBy(delim).many1(); }
/** * A {@link Parser} that succeeds if {@code this} succeeds and the pattern recognized by {@code parser} isn't * following. */ public final Parser<T> notFollowedBy(Parser<?> parser) { return followedBy(parser.not()); }
/** * A {@link Parser} that runs {@code this} for 0 or more times delimited and terminated by * {@code delim}. * * <p>The return values are collected in a {@link List}. */ public final Parser<List<T>> endBy(Parser<?> delim) { return followedBy(delim).many(); }
/** * A {@link Parser} that takes as input the {@link Token} collection returned by {@code lexer}, * and runs {@code this} to parse the tokens. Most parsers should use the simpler * {@link #from(Parser, Parser)} instead. * * <p> {@code this} must be a token level parser. */ public final Parser<T> from(Parser<? extends Collection<Token>> lexer) { return Parsers.nested(Parsers.tokens(lexer), followedBy(Parsers.EOF)); }
@Override <T> T run(Parser<T> parser, CharSequence source) { return new ScannerState(source).run(parser.followedBy(Parsers.EOF)); } },
static Parser<Statement> expression(Parser<Expression> expr) { return expr.followedBy(term(";")).map(ExpressionStatement::new); }
@Override <T> T run(Parser<T> parser, CharSequence source) { ScannerState state = new ScannerState(source); state.enableTrace("root"); return state.run(parser.followedBy(Parsers.EOF)); } }
/** * Parses {@code source}. * * @param source the source string * @param moduleName the name of the module, this name appears in error message * @return the result * @deprecated Please use {@link #parse(CharSequence)} instead. */ @Deprecated public final T parse(CharSequence source, String moduleName) { return new ScannerState(moduleName, source, 0, new SourceLocator(source)) .run(followedBy(Parsers.EOF)); }
/** * 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<Statement> expressionList(Parser<Expression> expr) { return expr.sepBy1(term(",")).followedBy(term(";")).map(ExpressionListStatement::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<Expression> fullCase(Parser<Expression> cond, Parser<Expression> expr) { return Parsers.sequence( term("case").next(whenThens(cond, expr)), term("else").next(expr).optional().followedBy(term("end")), FullCaseExpression::new); }
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> 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<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<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> 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<Member> methodDef( Parser<Modifier> mod, Parser<Expression> defaultValue, Parser<Statement> stmt) { return Parsers.sequence( mod.many(), TYPE_PARAMETERS.optional(), TypeLiteralParser.TYPE_LITERAL, Terminals.Identifier.PARSER, term("(").next(StatementParser.parameter(mod).sepBy(term(","))).followedBy(term(")")), term("throws").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(), term("default").next(ExpressionParser.arrayInitializerOrRegularExpression(defaultValue)) .optional(), Parsers.or( StatementParser.blockStatement(stmt), term(";").retn((BlockStatement) null)), MethodDef::new); }
static Parser<Declaration> enumDef(Parser<Expression> expr, Parser<Member> member) { Parser<EnumDef.Value> enumValue = Parsers.sequence( Terminals.Identifier.PARSER, between(term("("), expr.sepBy(term(",")), term(")")) .optional(), between(term("{"), member.many(), term("}")).optional(), EnumDef.Value::new); return Parsers.sequence( StatementParser.modifier(expr).many(), term("enum").next(Terminals.Identifier.PARSER), term("implements").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(), term("{").next(enumValue.sepBy(term(","))), term(";").next(member.many()).optional().followedBy(term("}")), EnumDef::new); }