Lexer.java
package com.hypixel.hytale.server.npc.util.expression.compile;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.text.ParseException;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class Lexer<Token extends Supplier<String>> {
public static final String UNTERMINATED_STRING = "Unterminated string";
public static final String INVALID_NUMBER_FORMAT = "Invalid number format";
public static final String INVALID_CHARACTER_IN_EXPRESSION = "Invalid character in expression :";
private final Token tokenEnd;
private final Token tokenIdent;
private final Token tokenString;
private Token tokenNumber;
CharacterSequenceMatcher<Token> characterSequenceMatcher;
{
.tokenEnd = tokenEnd;
.tokenIdent = tokenIdent;
.tokenString = tokenString;
.tokenNumber = tokenNumber;
.characterSequenceMatcher = <Token>();
operators.forEach((token) -> .characterSequenceMatcher.addToken(token, (String)token.get()));
}
Token ParseException {
context.resetToken();
(!context.eatWhiteSpace()) {
context.setToken(.tokenEnd);
} {
context.currentChar();
(!Character.isLetter(ch) && ch != ) {
(context.isNumber(ch)) {
context.parseNumber(ch);
context.setToken(.tokenNumber);
} (ch != && ch != ) {
CharacterSequenceMatcher<Token> lastTerminal = ;
CharacterSequenceMatcher<Token> matcher = .characterSequenceMatcher.matchLetter(ch);
lastValidPosition;
(lastValidPosition = context.getPosition(); matcher != ; matcher = matcher.matchLetter(ch)) {
(matcher.token != ) {
lastValidPosition = context.getPosition();
lastTerminal = matcher;
}
ch = context.addTokenCharacter(ch);
(!context.haveChar()) {
;
}
}
(lastTerminal != ) {
context.adjustPosition(lastValidPosition + );
context.setToken(lastTerminal.token);
} {
( + ch, context.getTokenPosition());
}
} {
context.parseString(ch);
context.setToken(.tokenString);
}
} {
context.parseIdent(ch);
context.setToken(.tokenIdent);
}
}
}
<Token> {
;
letter;
List<CharacterSequenceMatcher<Token>> children;
{
.letter = ;
.children = ;
}
{
.letter = letter;
.children = ;
}
{
text.charAt(depth);
(.children == ) {
.children = <CharacterSequenceMatcher<Token>>();
.append(token, depth, text, maxDepth, ch);
} {
;
size;
(size = .children.size(); index < size && ((CharacterSequenceMatcher).children.get(index)).letter < ch; ++index) {
}
(index == size) {
.append(token, depth, text, maxDepth, ch);
} {
CharacterSequenceMatcher<Token> child = (CharacterSequenceMatcher).children.get(index);
(child.letter == ch) {
(depth == maxDepth) {
(child.token != ) {
( + text);
}
child.token = token;
} {
child.addToken(token, depth + , text, maxDepth);
}
} {
CharacterSequenceMatcher<Token> lookup = <Token>(ch);
.children.add(index, lookup);
.addTail(token, depth, text, maxDepth, lookup);
}
}
}
}
{
.addToken(token, , text, text.length() - );
}
{
CharacterSequenceMatcher<Token> lookup = <Token>(ch);
.children.add(lookup);
.addTail(token, depth, text, maxDepth, lookup);
}
{
(depth == maxDepth) {
lookup.token = token;
} {
lookup.addToken(token, depth + , text, maxDepth);
}
}
CharacterSequenceMatcher<Token> {
(.children != ) {
;
( .children.size(); index < size; ++index) {
CharacterSequenceMatcher<Token> characterSequenceMatcher = (CharacterSequenceMatcher).children.get(index);
characterSequenceMatcher.letter;
(letter == ch) {
characterSequenceMatcher;
}
(letter > ch) {
;
}
}
}
;
}
}
}