public Scanner(TextMaker textMaker, CharSequence input) { this.input = new ScanString(input, 0); next = 0; this.textMaker = textMaker; symbols = new SymbolStream(); }
@Override public Maybe<Integer> match(ScanString input, SymbolStream symbols, int offset) { int size = 0; while (input.charAt(offset + size) == delimiter) size++; return size > 0 ? new Maybe<>(size) : Maybe.noInteger; } });
public Symbol makeLiteral(SymbolType terminator) { input.setOffset(next); while (!input.isEnd()) { SymbolMatch match = terminator.makeMatch(input, symbols); if (match.isMatch()) { symbols.add(new Symbol(terminator)); Symbol result = new Symbol(SymbolType.Text, input.substringFrom(next), next); next = input.getOffset() + match.getMatchLength(); return result; } input.moveNext(); } Symbol result = new Symbol(SymbolType.Text, input.substringFrom(next), next); next = input.getOffset(); symbols.add(Symbol.emptySymbol); return result; }
public boolean startsWith(String match) { return matches(match, 0); }
private Maybe<String> copyVariableValue(Parser parser, Symbol next) { String fromVariableName = next.getContent(); if (!ScanString.isVariableName(fromVariableName)) return Maybe.noString; return parser.getVariableSource().findVariable(fromVariableName); }
public boolean isEnd() { return isEnd(0); } public boolean isEnd(int startAt) { return offset + startAt >= input.length(); }
@Override public Maybe<Symbol> parse(Symbol current, Parser parser) { List<Symbol> tokens = parser.moveNext(new SymbolType[] {SymbolType.Whitespace, SymbolType.Text}); if (tokens.isEmpty()) return Symbol.nothing; String anchor = tokens.get(1).getContent(); if (!ScanString.isWord(anchor)) return Symbol.nothing; current.add(tokens.get(1)); return new Maybe<>(current); } }
@Override public Maybe<Symbol> parse(Symbol current, Parser parser) { Symbol next = parser.moveNext(1); if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing; String level = current.getContent().substring(1,2); if (ScanString.isDigits(level)) current.putProperty(Level, level); current.add(parser.parseToEnd(SymbolType.Newline)); if (parser.peek().isType(SymbolType.Newline) && !parser.endsOn(SymbolType.Newline)) parser.moveNext(1); return new Maybe<>(current); } }
@Override public SymbolMatch makeMatch(Matchable candidate) { if (input.getOffset() != startPosition || !ignores(candidate)) { SymbolMatch match = candidate.makeMatch(input, symbols); if (match.isMatch()) return match; } return SymbolMatch.noMatch; } });
public void markStart() { input.markStart(next); } public boolean isEnd() { return symbols.isEnd(); }
public Symbol makeLiteral(SymbolType terminator) { input.setOffset(next); while (!input.isEnd()) { SymbolMatch match = terminator.makeMatch(input, symbols); if (match.isMatch()) { symbols.add(new Symbol(terminator)); Symbol result = new Symbol(SymbolType.Text, input.substringFrom(next), next); next = input.getOffset() + match.getMatchLength(); return result; } input.moveNext(); } Symbol result = new Symbol(SymbolType.Text, input.substringFrom(next), next); next = input.getOffset(); symbols.add(Symbol.emptySymbol); return result; }
public boolean startsWith(String match) { return matches(match, 0); }
private Maybe<String> copyVariableValue(Parser parser, Symbol next) { String fromVariableName = next.getContent(); if (!ScanString.isVariableName(fromVariableName)) return Maybe.noString; return parser.getVariableSource().findVariable(fromVariableName); }
public boolean isEnd() { return isEnd(0); } public boolean isEnd(int startAt) { return offset + startAt >= input.length(); }
@Override public Maybe<Symbol> parse(Symbol current, Parser parser) { List<Symbol> tokens = parser.moveNext(new SymbolType[] {SymbolType.Text}); if (tokens.isEmpty()) return Symbol.nothing; String anchor = tokens.get(0).getContent(); if (!ScanString.isWord(anchor)) return Symbol.nothing; return new Maybe<>(current.add(tokens.get(0))); }
@Override public Maybe<Symbol> parse(Symbol current, Parser parser) { Symbol next = parser.moveNext(1); if (!next.isType(SymbolType.Whitespace)) return Symbol.nothing; String level = current.getContent().substring(1,2); if (ScanString.isDigits(level)) current.putProperty(Level, level); current.add(parser.parseToEnd(SymbolType.Newline)); if (parser.peek().isType(SymbolType.Newline) && !parser.endsOn(SymbolType.Newline)) parser.moveNext(1); return new Maybe<>(current); } }
@Override public SymbolMatch makeMatch(Matchable candidate) { if (input.getOffset() != startPosition || !ignores(candidate)) { SymbolMatch match = candidate.makeMatch(input, symbols); if (match.isMatch()) return match; } return SymbolMatch.noMatch; } });
public void markStart() { input.markStart(next); } public boolean isEnd() { return symbols.isEnd(); }
private Step makeNextStep(final ParseSpecification specification, final int startPosition) { input.setOffset(startPosition); int newNext = startPosition; Symbol matchSymbol = null; while (!input.isEnd()) { SymbolMatch match = specification.findMatch(input, startPosition, symbols); if (match.isMatch()) { matchSymbol = match.getSymbol(); newNext = input.getOffset() + match.getMatchLength(); break; } input.moveNext(); } if (input.getOffset() > startPosition) { SymbolMatch match = textMaker.make(specification, startPosition, input.substringFrom(startPosition)); return new Step(match.getSymbol(), startPosition + match.getMatchLength()); } if (input.isEnd()) { return new Step(Symbol.emptySymbol, input.getOffset()); } return new Step(matchSymbol, newNext); }