@NotNull @Override public Pair<R, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state) throws ParserException { if (myKey != state.getKey()) { myKey = state.getKey(); myCache.clear(); } final SoftReference<Pair<R, State>> ref = myCache.get(state.getPos()); final Pair<R, State> cached = SoftReference.dereference(ref); if (cached != null) { return cached; } final Pair<R, State> result = myParser.parse(tokens, state); myCache.put(state.getPos(), new SoftReference<Pair<R, State>>(result)); return result; }
@NotNull @Override public Pair<R, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state) throws ParserException { try { return myFirst.parse(tokens, state); } catch (ParserException e) { return mySecond.parse(tokens, new State(state, state.getPos(), e.getState().getMax())); } }
@NotNull @Override public Pair<Object, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state) throws ParserException { final int pos = state.getPos(); if (pos >= tokens.size()) { return Pair.create(null, state); } throw new ParserException( String.format("Expected end of input, found %s", tokens.get(pos)), state); }
@NotNull @Override public Pair<List<R>, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state) throws ParserException { final List<R> list = new ArrayList<R>(); try { //noinspection InfiniteLoopStatement while (true) { final Pair<R, State> result = myParser.parse(tokens, state); state = result.getSecond(); list.add(result.getFirst()); } } catch (ParserException e) { return Pair.create(list, new State(state, state.getPos(), e.getState().getMax())); } }
@NotNull @Override public Pair<Token<T>, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state) throws ParserException { final int pos = state.getPos(); if (pos >= tokens.size()) { throw new ParserException("No tokens left", state); } final Token<T> token = tokens.get(pos); if (token.getType().equals(myType) && (myText == null || token.getText().equals(myText))) { final int newPos = pos + 1; final State newState = new State(state, newPos, Math.max(newPos, state.getMax())); return Pair.create(token, newState); } final String expected = myText != null ? String.format("Token(<%s>, \"%s\")", myType, myText) : String.format("Token(<%s>)", myType); throw new ParserException(String.format("Expected %s, found %s", expected, token), state); }