CommonCivlcToken.java
package edu.udel.cis.vsl.abc.token.common;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.Token;
import edu.udel.cis.vsl.abc.token.IF.CivlcToken;
import edu.udel.cis.vsl.abc.token.IF.Formation;
import edu.udel.cis.vsl.abc.token.IF.SourceFile;
import edu.udel.cis.vsl.abc.token.IF.TokenUtils;
import edu.udel.cis.vsl.abc.token.IF.CivlcToken.TokenVocabulary;
/**
* An extension to ANTLR's generic Token implementation that adds fields to
* represent the origin of a token through various preprocessing stages. A
* history of include directives and macro invocations gives detailed
* information on the origin of the token.
*
* Every token originated as some token in a source file. (Ignoring for now
* token creation by the preprocessor using '##'.)
*
* These tokens have a next field, so that they can be given the structure of a
* linked list. Yes, I could have used Java's LinkedList class, but I don't
* think that supported certain operations efficiently, such as splicing one
* list into another in constant time.
*
* @author Stephen F. Siegel, University of Delaware, All rights reserved
*
*/
public class CommonCivlcToken extends CommonToken implements CivlcToken {
// Fields...
/**
* Eclipse made me do it.
*/
private static final long serialVersionUID = -5508021210762735784L;
private Formation formation;
/**
* If this is an identifier node and that identifier is for a macro, setting
* this bit to false means that the macro will not be expanded. This is
* needed for the complex macro expansion policy described in the C99
* Standard.
*/
private boolean expandable = true;
/**
* The CppTokens emanating from a CppTokenSource form a linked list. This is
* the next element in the list.
*/
private CivlcToken next = null;
/**
* Index of this token in the list of tokens emanating from CppTokenSource.
* First token has index 0.
*
* You can't trust CommonToken's index. It gets set to weird values by
* things I don't understand.
*/
private int tokenIndex = -1;
/**
* Created for Fortran parser which derived from OpenFortranParser. It
* requires a field with a type of String.
*/
private String whiteText = "";
/**
* The {@link TokenVocabulary} of <code>this</code> token instance.
*/
private TokenVocabulary tokenVocab = TokenVocabulary.UNKNOWN;
// Constructors...
/**
* Creates new instance by copying fields from old one. The two histories
* are set to the given arguments. Both must be non-null.
*
* @param token
* any kind of Token
*/
public CommonCivlcToken(Token token, Formation formation,
TokenVocabulary tokenVocab) {
super(token);
assert formation != null;
this.formation = formation;
this.tokenVocab = tokenVocab;
}
public CommonCivlcToken(int type, String text, Formation formation,
TokenVocabulary tokenVocab) {
super(type, text);
this.formation = formation;
this.tokenVocab = tokenVocab;
}
public CommonCivlcToken(CharStream input, int type, int channel, int start,
int stop, Formation formation, TokenVocabulary tokenVocab) {
super(input, type, channel, start, stop);
assert formation != null;
this.formation = formation;
this.tokenVocab = tokenVocab;
}
// Methods...
/**
* Returns the more technical string representation used in the parent class
* CommonToken. Useful for debugging, not so good for the end user, and does
* not include the extra information provided in this class, such as macro
* and include histories.
*
* @return technical string representation of the token.
*/
public String toStringOld() {
return super.toString();
}
/**
* Returns a string representation that is appropriate for reporting this
* token and its source to the end user. It includes the text of the token,
* source file, line and character index, history through macro expansion
* and include directives.
*/
@Override
public String toString() {
String result = TokenUtils.summarizeRangeLocation(this, this, false)
+ " " + TokenUtils.quotedText(this);
if (formation != null)
result += formation.suffix();
return result;
}
/**
* Is this token expandable? This is used only for identifiers that could be
* macro invocations. The macro expansion procedure is complex and at a
* certain phase, a macro identifier becomes non-expandable. It is mostly to
* support self-referential macros.
*
* Initially, every token is expandable.
*
* @return value of expandable bit
*/
@Override
public boolean isExpandable() {
return expandable;
}
/**
* Sets this token's expandable bit to false.
*/
@Override
public void makeNonExpandable() {
expandable = false;
}
/**
* Set this token's "next" field to the given token. This is used to give
* tokens the structure of a linked list. Initially, this is null.
*
* @param nextToken
*/
@Override
public void setNext(CivlcToken nextToken) {
this.next = nextToken;
}
/**
* Get this token's "next" field. Could be null.
*
* @return the next token
*/
@Override
public CivlcToken getNext() {
return next;
}
@Override
public void setIndex(int index) {
this.tokenIndex = index;
}
@Override
public int getIndex() {
return tokenIndex;
}
@Override
public SourceFile getSourceFile() {
return formation.getLastFile();
}
@Override
public Formation getFormation() {
return formation;
}
/* Methods for Fortran parser */
@Override
public String getWhiteText() {
return whiteText;
}
@Override
public void setWhiteText(String text) {
whiteText = text == null ? "" : text;
}
/* Methods for Fortran parser */
@Override
public TokenVocabulary getTokenVocab() {
return tokenVocab;
}
@Override
public void setTokenVocab(TokenVocabulary newTokenVocab) {
tokenVocab = newTokenVocab;
}
}