/* * This file is part of the Illarion project. * * Copyright © 2014 - Illarion e.V. * * Illarion is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Illarion is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ package illarion.easynpc.gui.syntax; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.UnbufferedTokenStream; import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker; import org.fife.ui.rsyntaxtextarea.Token; import javax.annotation.Nonnull; import javax.swing.text.Segment; import java.beans.ConstructorProperties; import java.io.CharArrayReader; import java.io.IOException; import java.io.Reader; /** * This token maker is dedicated to handle the lexer tokens generated by ANTLRv4. * * @author Martin Karing <nitram@illarion.org> */ public abstract class AbstractAntlrTokenMaker<T extends Lexer> extends AbstractTokenMaker { /** * The lexer that provides the data. */ @Nonnull private final T lexer; @ConstructorProperties("lexer") protected AbstractAntlrTokenMaker(@Nonnull T lexer) { this.lexer = lexer; } @Override public Token getTokenList(@Nonnull Segment text, int initialTokenType, int startOffset) { try (Reader textReader = new CharArrayReader(text.array, text.offset, text.count)) { lexer.setInputStream(new ANTLRInputStream(textReader)); TokenStream tokenStream = new UnbufferedTokenStream(lexer); resetTokenList(); while (true) { org.antlr.v4.runtime.Token currentToken = tokenStream.LT(1); if (currentToken.getType() == org.antlr.v4.runtime.Token.EOF) { break; } tokenStream.consume(); // convert the ANTLR token to a RSyntaxTextArea token and add it to the linked list int tokenStart = currentToken.getCharPositionInLine() + text.offset; int tokenEnd = (tokenStart + currentToken.getText().length()) - 1; int tokenOffset = startOffset + currentToken.getCharPositionInLine(); addToken(text.array, tokenStart, tokenEnd, convertTokenType(currentToken.getType()), tokenOffset); } // end while // add a null token to indicate end of line; note that the test grammar has no multiline token types addNullToken(); } catch (IOException e) { e.printStackTrace(); } return firstToken; } protected abstract int convertTokenType(int antlrType); }