/*
* 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);
}