Package org.jparsec
Class Parser.Reference<T>
- java.lang.Object
-
- java.util.concurrent.atomic.AtomicReference<Parser<T>>
-
- org.jparsec.Parser.Reference<T>
-
- All Implemented Interfaces:
java.io.Serializable
public static final class Parser.Reference<T> extends java.util.concurrent.atomic.AtomicReference<Parser<T>>
An atomic mutable reference toParser
used in recursive grammars.For example, the following is a recursive grammar for a simple calculator:
Terminals terms = Terminals.operators("(", ")", "+", "-"); Parser.Reference<Integer> ref = Parser.newReference(); Parser<Integer> literal = Terminals.IntegerLiteral.PARSER.map(new Function<String, Integer>() { ... return Integer.parseInt(s); }); Parser.Reference<Integer> parenthesized = // recursion in rule E = (E) Parsers.between(terms.token("("), ref.lazy(), terms.token(")")); ref.set(new OperatorTable() .infixl(terms.token("+").retn(plus), 10) .infixl(terms.token("-").retn(minus), 10) .build(literal.or(parenthesized))); return ref.get();
StackOverflowError
. Use appropriate parser built-in parser combinators to avoid left-recursion. For instance, many left recursive grammar rules can be thought as logically equivalent to postfix operator rules. In such case, eitherOperatorTable
orParser.postfix(org.jparsec.Parser<? extends java.util.function.Function<? super T, ? extends T>>)
can be used to work around left recursion. The following is a left recursive parser for array types in the form of "T[]" or "T[][]":Terminals terms = Terminals.operators("[", "]"); Parser.Reference<Type> ref = Parser.newReference(); ref.set(Parsers.or(leafTypeParser, Parsers.sequence(ref.lazy(), terms.phrase("[", "]"), new Unary<Type>() {...}))); return ref.get();
Terminals terms = Terminals.operators("[", "]"); return leafTypeParer.postfix(terms.phrase("[", "]").retn(new Unary<Type>() {...}));
expr ? a : b
ternary operator. It too is a left recursive grammar. And un-intuitively it can also be thought as a postfix operator. Basically, we can parse "? a : b" as a whole into a unary operator that accepts the condition expression as input and outputs the full ternary expression:Parser<Expr> ternary(Parser<Expr> expr) { return expr.postfix( Parsers.sequence( terms.token("?"), expr, terms.token(":"), expr, (unused, then, unused, orelse) -> cond -> new TernaryExpr(cond, then, orelse))); }
- See Also:
- Serialized Form
-
-
Constructor Summary
Constructors Constructor Description Reference()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description Parser<T>
lazy()
AParser
that delegates to the parser object referenced bythis
during parsing time.-
Methods inherited from class java.util.concurrent.atomic.AtomicReference
accumulateAndGet, compareAndExchange, compareAndExchangeAcquire, compareAndExchangeRelease, compareAndSet, get, getAcquire, getAndAccumulate, getAndSet, getAndUpdate, getOpaque, getPlain, lazySet, set, setOpaque, setPlain, setRelease, toString, updateAndGet, weakCompareAndSet, weakCompareAndSetAcquire, weakCompareAndSetPlain, weakCompareAndSetRelease, weakCompareAndSetVolatile
-
-