[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] patch for scanner
|
I have put together a patch for the
scanner (for HEAD) as part of some performance analysis that I was doing.
All Junit test have passed on Windows.
My example for performance testing was:
int
abc;
#include
<windows.h> // from cygwin w32api
#include
<stdio.h>
int
main()
{
a ; // do code assist here
}
Note that there are about 7,700,000
Java objects created by this test -- I believe that reducing this
number is essential to optimal performance. The parsing takes about
5.5 seconds (it varies by as much as 1 second either way) on a Pentium
M - 1.6 GHz.
The patch for the scanner includes the
following:
1. Removes the Strings associated
with constant value tokens and keywords -- it looks cleaner, and
reduces the number of objects created (only by 30 to 40 K) (about 2% quicker)
2. Buffered the File I/O associated
with reading inclusions: (about 5% quicker total)
a.
for "windows.h" and associated includes the current implementation
was 280 ms,
b.
the buffered form is 70 ms, and
c.
if we wish to rewrite a lot of supporting code -- a series of memory
mapped files would be 35 ms
3. restructured the scanner into a large
case statement with a few helper functions -- this is the start of removing
the strings (or providing a preallocated buffer for string manipulation)
(about 2% quicker)
a.
This is a major change in structure, but behavior is the same
b.
I removed some of the "state" information that was explicitly
managed by the code
c.
I started combining some of the common code fragments (for easier
maintenance and tuning)
- Dave
Index: parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java
===================================================================
retrieving revision 1.18
diff -u -r1.18 Scanner.java
--- parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java 4 Mar 2004 18:00:20 -0000 1.18
+++ parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java 7 Mar 2004 16:24:35 -0000
@@ -10,6 +10,7 @@
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
@@ -465,6 +466,18 @@
return currentToken;
}
+ protected IToken newConstantToken(int t) {
+ setCurrentToken(
+ new Token(
+ t,
+ scannerData.getContextStack().getCurrentContext(),
+ scannerData.getContextStack().getCurrentLineNumber()
+ )
+ );
+ return currentToken;
+ }
+
+
protected IToken newToken(int t, String i) {
setCurrentToken(new Token(t, i));
return currentToken;
@@ -494,79 +507,59 @@
}
protected void handleInclusion(String fileName, boolean useIncludePaths, int beginOffset, int startLine, int nameOffset, int nameLine, int endOffset, int endLine ) throws ScannerException {
-
- FileReader inclusionReader = null;
- String newPath = null;
-
- totalLoop: for( int i = 0; i < 2; ++i )
- {
- if( useIncludePaths ) // search include paths for this file
- {
- // iterate through the include paths
- Iterator iter = scannerData.getIncludePathNames().iterator();
-
- while (iter.hasNext()) {
-
- String path = (String)iter.next();
- File pathFile = new File(path);
- //TODO assert pathFile.isDirectory();
- StringBuffer buffer = new StringBuffer( pathFile.getPath() );
- buffer.append( File.separatorChar );
- buffer.append( fileName );
- newPath = buffer.toString();
- //TODO remove ".." and "." segments
- File includeFile = new File(newPath);
- if (includeFile.exists() && includeFile.isFile()) {
- try {
- inclusionReader = new FileReader(includeFile);
- break totalLoop;
- } catch (FileNotFoundException fnf) {
- continue;
- }
- }
+// if useIncludePaths is true then
+// #include <foo.h>
+// else
+// #include "foo.h"
+
+ Reader inclusionReader = null;
+ File includeFile = null;
+
+ if( !useIncludePaths ) { // local inclusion is checked first
+ String currentFilename = scannerData.getContextStack().getCurrentContext().getFilename();
+ File currentIncludeFile = new File( currentFilename );
+ String parentDirectory = currentIncludeFile.getParentFile().getAbsolutePath();
+ currentIncludeFile = null;
+
+ //TODO remove ".." and "." segments
+ includeFile = new File( parentDirectory, fileName );
+ if (includeFile.exists() && includeFile.isFile()) {
+ try {
+ inclusionReader = new BufferedReader(new FileReader(includeFile));
+ } catch (FileNotFoundException fnf) {
+ inclusionReader = null;
}
-
- if (inclusionReader == null )
- handleProblem( IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, fileName, beginOffset, false, true );
-
}
- else // local inclusion
- {
- String currentFilename = scannerData.getContextStack().getCurrentContext().getFilename();
- File currentIncludeFile = new File( currentFilename );
- String parentDirectory = currentIncludeFile.getParentFile().getAbsolutePath();
- currentIncludeFile = null;
-
- StringBuffer buffer = new StringBuffer( parentDirectory );
- buffer.append( File.separatorChar );
- buffer.append( fileName );
- newPath = buffer.toString();
- //TODO remove ".." and "." segments
- File includeFile = new File( newPath );
- if (includeFile.exists() && includeFile.isFile()) {
- try {
- inclusionReader = new FileReader(includeFile);
- break totalLoop;
- } catch (FileNotFoundException fnf) {
- useIncludePaths = true;
- continue totalLoop;
- }
- }
- else
- {
- useIncludePaths = true;
- continue totalLoop;
+ }
+
+ // search include paths for this file
+ // iterate through the include paths
+ Iterator iter = scannerData.getIncludePathNames().iterator();
+
+ while ((inclusionReader == null) && iter.hasNext()) {
+ String path = (String)iter.next();
+ //TODO remove ".." and "." segments
+ includeFile = new File (path, fileName);
+ if (includeFile.exists() && includeFile.isFile()) {
+ try {
+ inclusionReader = new BufferedReader(new FileReader(includeFile));
+ } catch (FileNotFoundException fnf) {
+ inclusionReader = null;
}
}
}
- if (inclusionReader != null) {
+
+ if (inclusionReader == null )
+ handleProblem( IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, fileName, beginOffset, false, true );
+
+ else {
IASTInclusion inclusion = null;
try
{
inclusion =
scannerData.getASTFactory().createInclusion(
fileName,
- newPath,
+ includeFile.getPath(),
!useIncludePaths,
beginOffset,
startLine,
@@ -580,7 +573,7 @@
try
{
- scannerData.getContextStack().updateContext(inclusionReader, newPath, ScannerContext.ContextKind.INCLUSION, inclusion, scannerData.getClientRequestor() );
+ scannerData.getContextStack().updateContext(inclusionReader, includeFile.getPath(), ScannerContext.ContextKind.INCLUSION, inclusion, scannerData.getClientRequestor() );
}
catch (ContextException e1)
{
@@ -655,8 +648,7 @@
return c;
c = accountForUndo(c);
-
- int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
+ int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
if (enableTrigraphReplacement && (!insideString || enableTrigraphReplacementInStrings)) {
// Trigraph processing
@@ -719,24 +711,7 @@
if (!insideString)
{
- if (c == '\\') {
- c = getChar(false);
- if (c == '\r') {
- c = getChar(false);
- if (c == '\n')
- {
- c = getChar(false);
- }
- } else if (c == '\n')
- {
- c = getChar(false);
-
- } else // '\' is not the last character on the line
- {
- ungetChar(c);
- c = '\\';
- }
- } else if (enableDigraphReplacement) {
+ if (enableDigraphReplacement) {
enableDigraphReplacement = false;
// Digraph processing
if (c == '<') {
@@ -779,12 +754,9 @@
enableDigraphReplacement = true;
}
}
-
return c;
}
-
-
protected int accountForUndo(int c)
{
boolean done;
@@ -856,14 +828,578 @@
}
public IToken nextToken() throws ScannerException, EndOfFileException {
- return nextToken( true, false );
+ return nextToken( true );
+ }
+
+ public boolean pasteIntoInputStream(StringBuffer buff) throws ScannerException, EndOfFileException
+ {
+ // we have found ## in the input stream -- so save the results
+ if( lookAheadForTokenPasting() )
+ {
+ if( storageBuffer == null )
+ storageBuffer = buff;
+ else
+ storageBuffer.append( buff.toString() );
+ return true;
+ }
+
+ // a previous call has stored information, so we will add to it
+ if( storageBuffer != null )
+ {
+ storageBuffer.append( buff.toString() );
+ try
+ {
+ scannerData.getContextStack().updateContext( new StringReader( storageBuffer.toString()), PASTING, IScannerContext.ContextKind.MACROEXPANSION, null, scannerData.getClientRequestor() );
+ }
+ catch (ContextException e)
+ {
+ handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true );
+ }
+ storageBuffer = null;
+ return true;
+ }
+
+ // there is no need to save the results -- we will not concatenate
+ return false;
+ }
+
+ public int consumeNewlineAfterSlash() throws ScannerException
+ {
+ int c;
+ c = getChar(false);
+ if (c == '\r')
+ {
+ c = getChar(false);
+ if (c == '\n')
+ {
+ // consume \ \r \n and then continue
+ return getChar(true);
+ }
+ else
+ {
+ // consume the \ \r and then continue
+ return c;
+ }
+ }
+
+ if (c == '\n')
+ {
+ // consume \ \n and then continue
+ return getChar(true);
+ }
+
+ // '\' is not the last character on the line
+ ungetChar(c);
+ return '\\';
+ }
+
+ public IToken processStringLiteral(boolean wideLiteral) throws ScannerException, EndOfFileException
+ {
+ int beginOffset = getCurrentOffset();
+ StringBuffer buff = new StringBuffer();
+ int beforePrevious = NOCHAR;
+ int previous = '"';
+ int c = getChar(true);
+
+ for( ; ; ) {
+ if (c == '\\')
+ c = consumeNewlineAfterSlash();
+
+
+ if ( ( c == '"' ) && ( previous != '\\' || beforePrevious == '\\') ) break;
+ if ( ( c == NOCHAR ) || (( c == '\n' ) && ( previous != '\\' || beforePrevious == '\\')) )
+ {
+ // TODO : we could probably return the partial string -- it might cause
+ // the parse to get by...
+
+ handleProblem( IProblem.SCANNER_UNBOUNDED_STRING, null, beginOffset, false, true );
+ return null;
+ }
+
+ buff.append((char) c);
+ beforePrevious = previous;
+ previous = c;
+ c = getChar(true);
+ }
+
+ int type = wideLiteral ? IToken.tLSTRING : IToken.tSTRING;
+
+ //If the next token is going to be a string as well, we need to concatenate
+ //it with this token. This will be recursive for as many strings as need to be concatenated
+
+ IToken returnToken = newToken( type, buff.toString(), scannerData.getContextStack().getCurrentContext());
+
+ IToken next = null;
+ try{
+ next = nextToken( true );
+ if ( next != null &&
+ (next.getType() == IToken.tSTRING ||
+ next.getType() == IToken.tLSTRING )) {
+ StringBuffer buffer = new StringBuffer( returnToken.getImage() );
+ buffer.append( next.getImage() );
+ returnToken.setImage( buffer.toString() );
+ }
+ else
+ cachedToken = next;
+ } catch( EndOfFileException e ){
+ next = null;
+ }
+
+ currentToken = returnToken;
+ returnToken.setNext( null );
+ return returnToken;
+ }
+ public IToken processNumber(int c, boolean pasting) throws ScannerException, EndOfFileException
+ {
+ // pasting happens when a macro appears in the middle of a number
+ // we will "store" the first part of the number in the "pasting" buffer
+ // until we have the full monty to evaluate
+ // for example
+ // #define F1 3
+ // #define F2 F1##F1
+ // int x = F2;
+
+ int beginOffset = getCurrentOffset();
+ StringBuffer buff = new StringBuffer();
+
+ boolean hex = false;
+ boolean floatingPoint = ( c == '.' ) ? true : false;
+ boolean firstCharZero = ( c== '0' )? true : false;
+
+ buff.append((char) c);
+
+ c = getChar();
+
+ if( ! firstCharZero && floatingPoint && !(c >= '0' && c <= '9') ){
+ //if pasting, there could actually be a float here instead of just a .
+ if( buff.toString().equals( "." ) ){ //$NON-NLS-1$
+ if( c == '*' ){
+ return newConstantToken( IToken.tDOTSTAR );
+ } else if( c == '.' ){
+ if( getChar() == '.' )
+ return newConstantToken( IToken.tELLIPSIS );
+ else
+ handleProblem( IProblem.SCANNER_BAD_FLOATING_POINT, null, beginOffset, false, true );
+ } else {
+ ungetChar( c );
+ return newConstantToken( IToken.tDOT );
+ }
+ }
+ } else if (c == 'x') {
+ if( ! firstCharZero )
+ {
+ handleProblem( IProblem.SCANNER_BAD_HEX_FORMAT, null, beginOffset, false, true );
+ return null;
+// c = getChar();
+// continue;
+ }
+ buff.append( (char)c );
+ hex = true;
+ c = getChar();
+ }
+
+ while ((c >= '0' && c <= '9')
+ || (hex
+ && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) {
+ buff.append((char) c);
+ c = getChar();
+ }
+
+ if( c == '.' )
+ {
+ buff.append( (char)c);
+
+ floatingPoint = true;
+ c= getChar();
+ while ((c >= '0' && c <= '9')
+ || (hex
+ && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))))
+ {
+ buff.append((char) c);
+ c = getChar();
+ }
+ }
+
+
+ if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P')))
+ {
+ if( ! floatingPoint ) floatingPoint = true;
+ // exponent type for floating point
+ buff.append((char)c);
+ c = getChar();
+
+ // optional + or -
+ if( c == '+' || c == '-' )
+ {
+ buff.append( (char)c );
+ c = getChar();
+ }
+
+ // digit sequence of exponent part
+ while ((c >= '0' && c <= '9') )
+ {
+ buff.append((char) c);
+ c = getChar();
+ }
+
+ // optional suffix
+ if( c == 'l' || c == 'L' || c == 'f' || c == 'F' )
+ {
+ buff.append( (char)c );
+ c = getChar();
+ }
+ } else {
+ if( floatingPoint ){
+ //floating-suffix
+ if( c == 'l' || c == 'L' || c == 'f' || c == 'F' ){
+ c = getChar();
+ }
+ } else {
+ //integer suffix
+ if( c == 'u' || c == 'U' ){
+ c = getChar();
+ if( c == 'l' || c == 'L')
+ c = getChar();
+ if( c == 'l' || c == 'L')
+ c = getChar();
+ } else if( c == 'l' || c == 'L' ){
+ c = getChar();
+ if( c == 'l' || c == 'L')
+ c = getChar();
+ if( c == 'u' || c == 'U' )
+ c = getChar();
+ }
+ }
+ }
+
+ ungetChar( c );
+
+ if( pasting && pasteIntoInputStream(buff))
+ return null;
+
+ int tokenType;
+ String result = buff.toString();
+
+ if( floatingPoint && result.equals(".") ) //$NON-NLS-1$
+ tokenType = IToken.tDOT;
+ else
+ tokenType = floatingPoint ? IToken.tFLOATINGPT : IToken.tINTEGER;
+
+ return newToken(
+ tokenType,
+ result,
+ scannerData.getContextStack().getCurrentContext());
}
+ public IToken processPreprocessor() throws ScannerException, EndOfFileException
+ {
+ int c;
+ int beginningOffset = scannerData.getContextStack().getCurrentContext().getOffset() - 1;
+ int beginningLine = scannerData.getContextStack().getCurrentLineNumber();
+ // lets prepare for a preprocessor statement
+ StringBuffer buff = new StringBuffer();
+ buff.append('#');
+
+ // we are allowed arbitrary whitespace after the '#' and before the rest of the text
+ boolean skipped = skipOverWhitespace();
+
+ c = getChar();
+
+ if( c == '#' )
+ {
+ if( skipped )
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "# #", beginningOffset, false, true ); //$NON-NLS-1$
+ else
+ return newConstantToken( tPOUNDPOUND ); //$NON-NLS-1$
+ } else if( tokenizingMacroReplacementList ) {
+ ungetChar( c );
+ return newConstantToken( tPOUND ); //$NON-NLS-1$
+ }
+
+ while (((c >= 'a') && (c <= 'z'))
+ || ((c >= 'A') && (c <= 'Z')) || (c == '_') ) {
+ buff.append((char) c);
+ c = getChar();
+ }
+
+ ungetChar(c);
+
+ String token = buff.toString();
+
+ if( isLimitReached() )
+ handleCompletionOnPreprocessorDirective(token);
+
+ Object directive = ppDirectives.get(token);
+ if (directive == null) {
+ if( scannerExtension.canHandlePreprocessorDirective( token ) )
+ scannerExtension.handlePreprocessorDirective( token, getRestOfPreprocessorLine() );
+ StringBuffer buffer = new StringBuffer( "#"); //$NON-NLS-1$
+ buffer.append( token );
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
+ return null;
+ }
+
+ int type = ((Integer) directive).intValue();
+ switch (type) {
+ case PreprocessorDirectives.DEFINE :
+ if ( ! passOnToClient ) {
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+ }
+ poundDefine(beginningOffset, beginningLine);
+ return null;
+
+ case PreprocessorDirectives.INCLUDE :
+ if (! passOnToClient ) {
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+ }
+ poundInclude( beginningOffset, beginningLine );
+ return null;
+
+ case PreprocessorDirectives.UNDEFINE :
+ if (! passOnToClient) {
+
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+ }
+ skipOverWhitespace();
+ removeSymbol(getNextIdentifier());
+ skipOverTextUntilNewline();
+ return null;
+
+ case PreprocessorDirectives.IF :
+ //TODO add in content assist stuff here
+ // get the rest of the line
+ int currentOffset = getCurrentOffset();
+ String expression = getRestOfPreprocessorLine();
+
+
+ if( isLimitReached() )
+ handleCompletionOnExpression( expression );
+
+ if (expression.trim().equals("")) //$NON-NLS-1$
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "#if", beginningOffset, false, true ); //$NON-NLS-1$
+
+ boolean expressionEvalResult = false;
+
+ if( scannerData.getBranchTracker().queryCurrentBranchForIf() )
+ expressionEvalResult = evaluateExpression(expression, currentOffset);
+
+ passOnToClient = scannerData.getBranchTracker().poundIf( expressionEvalResult );
+ return null;
+
+ case PreprocessorDirectives.IFDEF :
+ //TODO add in content assist stuff here
+ skipOverWhitespace();
+
+ String definition = getNextIdentifier();
+ if( isLimitReached() )
+ handleCompletionOnDefinition( definition );
+
+ if (getDefinition(definition) == null) {
+ // not defined
+ passOnToClient = scannerData.getBranchTracker().poundIf( false );
+ skipOverTextUntilNewline();
+ } else
+ // continue along, act like nothing is wrong :-)
+ passOnToClient = scannerData.getBranchTracker().poundIf( true );
+ return null;
+
+ case PreprocessorDirectives.ENDIF :
+ String restOfLine = getRestOfPreprocessorLine().trim();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+
+ if( ! restOfLine.equals( "" ) ) //$NON-NLS-1$
+ {
+ StringBuffer buffer = new StringBuffer("#endif "); //$NON-NLS-1$
+ buffer.append( restOfLine );
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
+ }
+ passOnToClient = scannerData.getBranchTracker().poundEndif();
+ return null;
+
+ case PreprocessorDirectives.IFNDEF :
+ //TODO add in content assist stuff here
+ skipOverWhitespace();
+
+ String definition2 = getNextIdentifier();
+ if( isLimitReached() )
+ handleCompletionOnDefinition( definition2 );
+
+ if (getDefinition(definition2) != null) {
+ // not defined
+ skipOverTextUntilNewline();
+ passOnToClient = scannerData.getBranchTracker().poundIf( false );
+ if( isLimitReached() )
+ handleInvalidCompletion();
+
+ } else
+ // continue along, act like nothing is wrong :-)
+ passOnToClient = scannerData.getBranchTracker().poundIf( true );
+ return null;
+
+ case PreprocessorDirectives.ELSE :
+ try
+ {
+ passOnToClient = scannerData.getBranchTracker().poundElse();
+ }
+ catch( EmptyStackException ese )
+ {
+ handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
+ token,
+ beginningOffset,
+ false, true );
+ }
+
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
- public IToken nextToken(boolean pasting) throws ScannerException, EndOfFileException {
- return nextToken( pasting, false );
+ case PreprocessorDirectives.ELIF :
+ //TODO add in content assist stuff here
+ int co = getCurrentOffset();
+ String elifExpression = getRestOfPreprocessorLine();
+ if( isLimitReached() )
+ handleCompletionOnExpression( elifExpression );
+
+
+ if (elifExpression.equals("")) //$NON-NLS-1$
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "#elif", beginningOffset, false, true ); //$NON-NLS-1$
+
+ boolean elsifResult = false;
+ if( scannerData.getBranchTracker().queryCurrentBranchForElif() )
+ elsifResult = evaluateExpression(elifExpression, co );
+
+ try
+ {
+ passOnToClient = scannerData.getBranchTracker().poundElif( elsifResult );
+ }
+ catch( EmptyStackException ese )
+ {
+ StringBuffer buffer = new StringBuffer( token );
+ buffer.append( ' ' );
+ buffer.append( elifExpression );
+ handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
+ buffer.toString(),
+ beginningOffset,
+ false, true );
+ }
+ return null;
+
+ case PreprocessorDirectives.LINE :
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+
+ case PreprocessorDirectives.ERROR :
+ if (! passOnToClient) {
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+ }
+ handleProblem( IProblem.PREPROCESSOR_POUND_ERROR, getRestOfPreprocessorLine(), beginningOffset, false, true );
+ return null;
+
+ case PreprocessorDirectives.PRAGMA :
+ skipOverTextUntilNewline();
+ if( isLimitReached() )
+ handleInvalidCompletion();
+ return null;
+
+ case PreprocessorDirectives.BLANK :
+ String remainderOfLine =
+ getRestOfPreprocessorLine().trim();
+ if (!remainderOfLine.equals("")) { //$NON-NLS-1$
+ StringBuffer buffer = new StringBuffer( "# "); //$NON-NLS-1$
+ buffer.append( remainderOfLine );
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true);
+ }
+ return null;
+
+ default :
+ StringBuffer buffer = new StringBuffer( "# "); //$NON-NLS-1$
+ buffer.append( token );
+ handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
+ return null;
+ }
}
+
+ public IToken processKeywordOrLiteral(int c, boolean pasting) throws ScannerException, EndOfFileException
+ {
+ int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
+
+ // String buffer is slow, we need a better way such as memory mapped files
+ StringBuffer buff = new StringBuffer();
+ buff.append((char) c);
+
+ c = getChar();
+
+ while (
+ Character.isUnicodeIdentifierPart( (char)c)
+// ((c >= 'a') && (c <= 'z'))
+// || ((c >= 'A') && (c <= 'Z'))
+// || ((c >= '0') && (c <= '9'))
+// || (c == '_')
+ ) {
+ buff.append((char) c);
+ c = getChar();
+ if (c == '\\') {
+ c = consumeNewlineAfterSlash();
+
+ }
+ }
+
+ ungetChar(c);
+
+ String ident = buff. toString();
+
+ if (ident.equals(DEFINED))
+ return newToken(IToken.tINTEGER, handleDefinedMacro());
+
+ if( ident.equals(_PRAGMA) && scannerData.getLanguage() == ParserLanguage.C )
+ {
+ handlePragmaOperator();
+ return null;
+ }
+
+ IMacroDescriptor mapping = getDefinition(ident);
- public IToken nextToken( boolean pasting, boolean lookingForNextAlready ) throws ScannerException, EndOfFileException
+ if (mapping != null) {
+ StringBuffer buffer = new StringBuffer(POUND_DEFINE);
+ buffer.append( ident );
+ if( scannerData.getContextStack().shouldExpandDefinition( buffer.toString() ) ) {
+ expandDefinition(ident, mapping, baseOffset);
+ return null;
+ }
+ }
+
+ if( pasting && pasteIntoInputStream(buff)){
+ return null;
+ }
+
+ Object tokenTypeObject;
+ if( scannerData.getLanguage() == ParserLanguage.CPP )
+ tokenTypeObject = cppKeywords.get(ident);
+ else
+ tokenTypeObject = cKeywords.get(ident);
+
+ if (tokenTypeObject != null)
+ return newConstantToken(((Integer) tokenTypeObject).intValue());
+ else
+ return newToken(IToken.tIDENTIFIER, ident, scannerData.getContextStack().getCurrentContext());
+ }
+
+ public IToken nextToken( boolean pasting ) throws ScannerException, EndOfFileException
{
if( ! initialContextInitialized )
setupInitialContext();
@@ -874,9 +1410,9 @@
return currentToken;
}
+ IToken token;
count++;
- boolean possibleWideLiteral = true;
- boolean wideLiteral = false;
+
int c = getChar();
while (c != NOCHAR) {
@@ -911,936 +1447,339 @@
}
}
- if ((c == ' ') || (c == '\r') || (c == '\t') || (c == '\n')) {
- c = getChar();
- continue;
- } else if (c == 'L' && possibleWideLiteral ) {
- int oldChar = c;
- c = getChar();
- if(!(c == '"' || c == '\'')) {
- // we have made a mistake
- ungetChar(c);
- c = oldChar;
- possibleWideLiteral = false;
- continue;
- }
- wideLiteral = true;
- continue;
- } else if (c == '"') {
- int beginOffset = getCurrentOffset();
- // string
- StringBuffer buff = new StringBuffer();
- int beforePrevious = NOCHAR;
- int previous = c;
- c = getChar(true);
-
- for( ; ; )
- {
- if ( ( c =='"' ) && ( previous != '\\' || beforePrevious == '\\') ) break;
- if ( ( c == '\n' ) && ( previous != '\\' || beforePrevious == '\\') )
- {
- handleProblem( IProblem.SCANNER_UNBOUNDED_STRING, null, beginOffset, false, true );
- }
-
- if( c == NOCHAR) break;
- buff.append((char) c);
- beforePrevious = previous;
- previous = c;
- c = getChar(true);
- }
-
- if (c != NOCHAR )
- {
- int type = wideLiteral ? IToken.tLSTRING : IToken.tSTRING;
-
- //If the next token is going to be a string as well, we need to concatenate
- //it with this token.
- IToken returnToken = newToken( type, buff.toString(), scannerData.getContextStack().getCurrentContext());
-
- if (!lookingForNextAlready) {
- IToken next = null;
- try{
- next = nextToken( true, true );
- } catch( EndOfFileException e ){
- next = null;
- }
-
- while( next != null && ( next.getType() == IToken.tSTRING ||
- next.getType() == IToken.tLSTRING ) ){
- StringBuffer buffer = new StringBuffer( returnToken.getImage() );
- buffer.append( next.getImage() );
- returnToken.setImage( buffer.toString() );
- returnToken.setNext( null );
- currentToken = returnToken;
- try{
- next = nextToken( true, true );
- } catch( EndOfFileException e ){
- next = null;
- }
- }
-
- cachedToken = next;
-
- }
-
- currentToken = returnToken;
- returnToken.setNext( null );
-
- return returnToken;
-
- } else
- handleProblem( IProblem.SCANNER_UNBOUNDED_STRING, null, beginOffset, false, true );
-
-
- } else if (
- // JOHNC - Accept non-ASCII Input
-// ((c >= 'a') && (c <= 'z'))
-// || ((c >= 'A') && (c <= 'Z')) || (c == '_')) {
- Character.isLetter((char)c) || ( c == '_')
- )
- {
-
- int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
-
- // String buffer is slow, we need a better way such as memory mapped files
- StringBuffer buff = new StringBuffer();
- buff.append((char) c);
-
- c = getChar();
-
- while (
- Character.isUnicodeIdentifierPart( (char)c)
-// ((c >= 'a') && (c <= 'z'))
-// || ((c >= 'A') && (c <= 'Z'))
-// || ((c >= '0') && (c <= '9'))
-// || (c == '_')
- ) {
- buff.append((char) c);
+ switch (c) {
+ case ' ' :
+ case '\r' :
+ case '\t' :
+ case '\n' :
c = getChar();
- }
-
- ungetChar(c);
-
- String ident = buff.toString();
-
- if (ident.equals(DEFINED))
- return newToken(IToken.tINTEGER, handleDefinedMacro());
-
- if( ident.equals(_PRAGMA) && scannerData.getLanguage() == ParserLanguage.C )
- {
- handlePragmaOperator();
- c = getChar();
continue;
- }
-
- IMacroDescriptor mapping = getDefinition(ident);
-
- if (mapping != null) {
- StringBuffer buffer = new StringBuffer(POUND_DEFINE);
- buffer.append( ident );
- if( scannerData.getContextStack().shouldExpandDefinition( buffer.toString() ) ) {
- expandDefinition(ident, mapping, baseOffset);
- c = getChar();
- continue;
- }
- }
-
- Object tokenTypeObject;
-
- if( scannerData.getLanguage() == ParserLanguage.CPP )
- tokenTypeObject = cppKeywords.get(ident);
- else
- tokenTypeObject = cKeywords.get(ident);
-
- int tokenType = IToken.tIDENTIFIER;
- if (tokenTypeObject != null)
- tokenType = ((Integer) tokenTypeObject).intValue();
-
- if( pasting )
- {
- if( lookAheadForTokenPasting() )
- {
- if( storageBuffer == null )
- storageBuffer = buff;
- else
- storageBuffer.append( ident );
-
- c = getChar();
- continue;
+ case ':' :
+ c = getChar();
+ switch (c) {
+ case ':' : return newConstantToken(IToken.tCOLONCOLON);
+ // Diagraph
+ case '>' : return newConstantToken(IToken.tRBRACKET);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tCOLON);
}
- else
+ case ';' : return newConstantToken(IToken.tSEMI);
+ case ',' : return newConstantToken(IToken.tCOMMA);
+ case '?' :
+ c = getChar();
+ if (c == '?')
{
- if( storageBuffer != null )
- {
- storageBuffer.append( ident );
- try
- {
- scannerData.getContextStack().updateContext( new StringReader( storageBuffer.toString()), PASTING, IScannerContext.ContextKind.MACROEXPANSION, null, scannerData.getClientRequestor() );
- }
- catch (ContextException e)
- {
- handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true );
- }
- storageBuffer = null;
- c = getChar();
- continue;
+ // trigraph
+ c = getChar();
+ switch (c) {
+ case '=':
+ // this is the same as the # case
+ token = processPreprocessor();
+ if (token == null)
+ {
+ c = getChar();
+ continue;
+ }
+ return token;
+
+// case '/':
+// expandDefinition("??/", "\\", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$
+// c = getChar(insideString);
+// break;
+ default:
+ // Not a trigraph
+ ungetChar(c);
+ ungetChar('?');
+ return newConstantToken(IToken.tQUESTION);
}
- }
- }
+ }
- return newToken(tokenType, ident, scannerData.getContextStack().getCurrentContext());
- } else if ((c >= '0') && (c <= '9') || c == '.' ) {
- int beginOffset = getCurrentOffset();
- StringBuffer buff;
-
- if( pasting )
- {
- if( storageBuffer != null )
- buff = storageBuffer;
- else
- buff = new StringBuffer();
- }
- else
- buff = new StringBuffer();
-
-
- boolean hex = false;
- boolean floatingPoint = ( c == '.' ) ? true : false;
- boolean firstCharZero = ( c== '0' )? true : false;
+ ungetChar(c);
+ return newConstantToken(IToken.tQUESTION);
- buff.append((char) c);
-
- c = getChar();
-
- if( ! firstCharZero && floatingPoint && !(c >= '0' && c <= '9') ){
- //if pasting, there could actually be a float here instead of just a .
- if( buff.toString().equals( "." ) ){ //$NON-NLS-1$
- if( c == '*' ){
- return newToken( IToken.tDOTSTAR, ".*", scannerData.getContextStack().getCurrentContext() ); //$NON-NLS-1$
- } else if( c == '.' ){
- if( getChar() == '.' )
- return newToken( IToken.tELLIPSIS, "...", scannerData.getContextStack().getCurrentContext() ); //$NON-NLS-1$
- else
- handleProblem( IProblem.SCANNER_BAD_FLOATING_POINT, null, beginOffset, false, true );
- } else {
- ungetChar( c );
- return newToken( IToken.tDOT, ".", scannerData.getContextStack().getCurrentContext() ); //$NON-NLS-1$
- }
- }
- } else if (c == 'x') {
- if( ! firstCharZero )
- {
- handleProblem( IProblem.SCANNER_BAD_HEX_FORMAT, null, beginOffset, false, true );
- c = getChar();
- continue;
+ case '(' : return newConstantToken(IToken.tLPAREN);
+ case ')' : return newConstantToken(IToken.tRPAREN);
+ case '[' : return newConstantToken(IToken.tLBRACKET);
+ case ']' : return newConstantToken(IToken.tRBRACKET);
+ case '{' : return newConstantToken(IToken.tLBRACE);
+ case '}' : return newConstantToken(IToken.tRBRACE);
+ case '+' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tPLUSASSIGN);
+ case '+' : return newConstantToken(IToken.tINCR);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tPLUS);
}
- buff.append( (char)c );
- hex = true;
+ case '-' :
c = getChar();
- }
-
- while ((c >= '0' && c <= '9')
- || (hex
- && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) {
- buff.append((char) c);
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tMINUSASSIGN);
+ case '-' : return newConstantToken(IToken.tDECR);
+ case '>' :
+ c = getChar();
+ switch (c) {
+ case '*' : return newConstantToken(IToken.tARROWSTAR);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tARROW);
+ }
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tMINUS);
+ }
+ case '*' :
c = getChar();
- }
-
- if( c == '.' )
- {
- buff.append( (char)c);
-
- floatingPoint = true;
- c= getChar();
- while ((c >= '0' && c <= '9')
- || (hex
- && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))))
- {
- buff.append((char) c);
- c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tSTARASSIGN);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tSTAR);
}
- }
-
-
- if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P')))
- {
- if( ! floatingPoint ) floatingPoint = true;
- // exponent type for floating point
- buff.append((char)c);
- c = getChar();
-
- // optional + or -
- if( c == '+' || c == '-' )
- {
- buff.append( (char)c );
- c = getChar();
+ case '%' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tMODASSIGN);
+
+ // Diagraph
+ case '>' : return newConstantToken(IToken.tRBRACE);
+ case ':' :
+ // this is the same as the # case
+ token = processPreprocessor();
+ if (token == null)
+ {
+ c = getChar();
+ continue;
+ }
+ return token;
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tMOD);
}
-
- // digit sequence of exponent part
- while ((c >= '0' && c <= '9') )
- {
- buff.append((char) c);
- c = getChar();
+ case '^' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tXORASSIGN);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tXOR);
}
-
- // optional suffix
- if( c == 'l' || c == 'L' || c == 'f' || c == 'F' )
- {
- buff.append( (char)c );
- c = getChar();
+ case '&' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tAMPERASSIGN);
+ case '&' : return newConstantToken(IToken.tAND);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tAMPER);
}
- } else {
- if( floatingPoint ){
- //floating-suffix
- if( c == 'l' || c == 'L' || c == 'f' || c == 'F' ){
- c = getChar();
- }
- } else {
- //integer suffix
- if( c == 'u' || c == 'U' ){
- c = getChar();
- if( c == 'l' || c == 'L')
- c = getChar();
- if( c == 'l' || c == 'L')
- c = getChar();
- } else if( c == 'l' || c == 'L' ){
- c = getChar();
- if( c == 'l' || c == 'L')
- c = getChar();
- if( c == 'u' || c == 'U' )
- c = getChar();
- }
+ case '|' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tBITORASSIGN);
+ case '|' : return newConstantToken(IToken.tOR);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tBITOR);
}
- }
-
- ungetChar( c );
-
- if( pasting )
- {
- if( lookAheadForTokenPasting() )
- {
- storageBuffer = buff;
- c = getChar();
- continue;
+ case '~' : return newConstantToken(IToken.tCOMPL);
+ case '!' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tNOTEQUAL);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tNOT);
}
- else
- {
- if( storageBuffer != null )
- {
- try
- {
- scannerData.getContextStack().updateContext( new StringReader( buff.toString()), PASTING, IScannerContext.ContextKind.MACROEXPANSION, null, scannerData.getClientRequestor() );
- }
- catch (ContextException e)
- {
- handleProblem( e.getId(), scannerData.getContextStack().getCurrentContext().getFilename(), getCurrentOffset(), false, true );
- }
- storageBuffer = null;
- c = getChar();
- continue;
- }
+ case '=' :
+ c = getChar();
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tEQUAL);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tASSIGN);
}
- }
-
- int tokenType;
- String result = buff.toString();
-
- if( floatingPoint && result.equals(".") ) //$NON-NLS-1$
- tokenType = IToken.tDOT;
- else
- tokenType = floatingPoint ? IToken.tFLOATINGPT : IToken.tINTEGER;
-
- return newToken(
- tokenType,
- result,
- scannerData.getContextStack().getCurrentContext());
-
- } else if (c == '#') {
-
- int beginningOffset = scannerData.getContextStack().getCurrentContext().getOffset() - 1;
- int beginningLine = scannerData.getContextStack().getCurrentLineNumber();
- // lets prepare for a preprocessor statement
- StringBuffer buff = new StringBuffer();
- buff.append((char) c);
-
- // we are allowed arbitrary whitespace after the '#' and before the rest of the text
- boolean skipped = skipOverWhitespace();
-
- c = getChar();
-
- if( c == '#' )
- {
- if( skipped )
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "# #", beginningOffset, false, true ); //$NON-NLS-1$
- else
- return newToken( tPOUNDPOUND, "##" ); //$NON-NLS-1$
- } else if( tokenizingMacroReplacementList ) {
- ungetChar( c );
- return newToken( tPOUND, "#" ); //$NON-NLS-1$
- }
-
- while (((c >= 'a') && (c <= 'z'))
- || ((c >= 'A') && (c <= 'Z')) || (c == '_') ) {
- buff.append((char) c);
+ case '<' :
c = getChar();
- }
-
- ungetChar(c);
-
- String token = buff.toString();
-
- if( isLimitReached() )
- handleCompletionOnPreprocessorDirective(token);
-
- Object directive = ppDirectives.get(token);
- if (directive == null) {
- if( scannerExtension.canHandlePreprocessorDirective( token ) )
- scannerExtension.handlePreprocessorDirective( token, getRestOfPreprocessorLine() );
- StringBuffer buffer = new StringBuffer( "#"); //$NON-NLS-1$
- buffer.append( token );
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
- } else {
- int type = ((Integer) directive).intValue();
- switch (type) {
- case PreprocessorDirectives.DEFINE :
- if ( ! passOnToClient ) {
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
- c = getChar();
- continue;
- }
-
- poundDefine(beginningOffset, beginningLine);
-
- c = getChar();
- continue;
-
- case PreprocessorDirectives.INCLUDE :
- if (! passOnToClient ) {
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
- c = getChar();
- continue;
- }
-
- poundInclude( beginningOffset, beginningLine );
-
- c = getChar();
- continue;
- case PreprocessorDirectives.UNDEFINE :
- if (! passOnToClient) {
-
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
- c = getChar();
- continue;
- }
- skipOverWhitespace();
- removeSymbol(getNextIdentifier());
- skipOverTextUntilNewline();
- c = getChar();
- continue;
- case PreprocessorDirectives.IF :
- //TODO add in content assist stuff here
- // get the rest of the line
- int currentOffset = getCurrentOffset();
- String expression = getRestOfPreprocessorLine();
-
-
- if( isLimitReached() )
- handleCompletionOnExpression( expression );
-
- if (expression.trim().equals("")) //$NON-NLS-1$
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "#if", beginningOffset, false, true ); //$NON-NLS-1$
-
- boolean expressionEvalResult = false;
-
- if( scannerData.getBranchTracker().queryCurrentBranchForIf() )
- expressionEvalResult = evaluateExpression(expression, currentOffset);
-
- passOnToClient = scannerData.getBranchTracker().poundIf( expressionEvalResult );
+ switch (c) {
+ case '<' :
c = getChar();
- continue;
-
- case PreprocessorDirectives.IFDEF :
- //TODO add in content assist stuff here
- skipOverWhitespace();
-
- String definition = getNextIdentifier();
- if( isLimitReached() )
- handleCompletionOnDefinition( definition );
-
- if (getDefinition(definition) == null) {
- // not defined
- passOnToClient = scannerData.getBranchTracker().poundIf( false );
- skipOverTextUntilNewline();
- } else {
- passOnToClient = scannerData.getBranchTracker().poundIf( true );
- // continue along, act like nothing is wrong :-)
- c = getChar();
- }
- continue;
- case PreprocessorDirectives.ENDIF :
- String restOfLine = getRestOfPreprocessorLine().trim();
- if( isLimitReached() )
- handleInvalidCompletion();
-
- if( ! restOfLine.equals( "" ) ) //$NON-NLS-1$
- {
- StringBuffer buffer = new StringBuffer("#endif "); //$NON-NLS-1$
- buffer.append( restOfLine );
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tSHIFTLASSIGN);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tSHIFTL);
}
- passOnToClient = scannerData.getBranchTracker().poundEndif();
- c = getChar();
- continue;
-
- case PreprocessorDirectives.IFNDEF :
- //TODO add in content assist stuff here
- skipOverWhitespace();
-
- String definition2 = getNextIdentifier();
- if( isLimitReached() )
- handleCompletionOnDefinition( definition2 );
-
- if (getDefinition(definition2) != null) {
- // not defined
- skipOverTextUntilNewline();
- passOnToClient = scannerData.getBranchTracker().poundIf( false );
- if( isLimitReached() )
- handleInvalidCompletion();
+ case '=' : return newConstantToken(IToken.tLTEQUAL);
+
+ // Diagraphs
+ case '%' : return newConstantToken(IToken.tLBRACE);
+ case ':' : return newConstantToken(IToken.tLBRACKET);
- } else {
- passOnToClient = scannerData.getBranchTracker().poundIf( true );
- // continue along, act like nothing is wrong :-)
- c = getChar();
- }
- continue;
-
- case PreprocessorDirectives.ELSE :
- try
- {
- passOnToClient = scannerData.getBranchTracker().poundElse();
- }
- catch( EmptyStackException ese )
- {
- handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
- token,
- beginningOffset,
- false, true );
- }
-
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
-
+ default :
+ ungetChar(c);
+ if( forInclusion )
+ temporarilyReplaceDefinitionsMap();
+ return newConstantToken(IToken.tLT);
+ }
+ case '>' :
+ c = getChar();
+ switch (c) {
+ case '>' :
c = getChar();
- continue;
-
- case PreprocessorDirectives.ELIF :
- //TODO add in content assist stuff here
- int co = getCurrentOffset();
- String elifExpression = getRestOfPreprocessorLine();
- if( isLimitReached() )
- handleCompletionOnExpression( elifExpression );
-
-
- if (elifExpression.equals("")) //$NON-NLS-1$
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, "#elif", beginningOffset, false, true ); //$NON-NLS-1$
-
- boolean elsifResult = false;
- if( scannerData.getBranchTracker().queryCurrentBranchForElif() )
- elsifResult = evaluateExpression(elifExpression, co );
-
- try
- {
- passOnToClient = scannerData.getBranchTracker().poundElif( elsifResult );
- }
- catch( EmptyStackException ese )
- {
- StringBuffer buffer = new StringBuffer( token );
- buffer.append( ' ' );
- buffer.append( elifExpression );
- handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
- buffer.toString(),
- beginningOffset,
- false, true );
+ switch (c) {
+ case '=' : return newConstantToken(IToken.tSHIFTRASSIGN);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tSHIFTR);
}
+ case '=' : return newConstantToken(IToken.tGTEQUAL);
+ default :
+ ungetChar(c);
+ if( forInclusion )
+ restoreDefinitionsMap();
+ return newConstantToken(IToken.tGT);
+ }
+ case '.' :
+ c = getChar();
+ switch (c) {
+ case '.' :
c = getChar();
- continue;
-
- case PreprocessorDirectives.LINE :
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
- c = getChar();
- continue;
- case PreprocessorDirectives.ERROR :
- if (! passOnToClient) {
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
-
- c = getChar();
- continue;
+ switch (c) {
+ case '.' : return newConstantToken(IToken.tELLIPSIS);
+ default :
+ // TODO : there is something missing here!
+ break;
}
- handleProblem( IProblem.PREPROCESSOR_POUND_ERROR, getRestOfPreprocessorLine(), beginningOffset, false, true );
- c = getChar();
- continue;
- case PreprocessorDirectives.PRAGMA :
- skipOverTextUntilNewline();
- if( isLimitReached() )
- handleInvalidCompletion();
-
+ break;
+ case '*' : return newConstantToken(IToken.tDOTSTAR);
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ ungetChar(c);
+ return processNumber('.', pasting);
+ default :
+ ungetChar(c);
+ return newConstantToken(IToken.tDOT);
+ }
+ break;
+
+// The logic around the escape \ is fuzzy. There is code in getChar(boolean) and
+// in consumeNewLineAfterSlash(). It currently works, but is fragile.
+// case '\\' :
+// c = consumeNewlineAfterSlash();
+//
+// // if we are left with the \ we can skip it.
+// if (c == '\\')
+// c = getChar();
+// continue;
+
+ case '/' :
+ c = getChar();
+ switch (c) {
+ case '/' :
+ skipOverSinglelineComment();
c = getChar();
continue;
- case PreprocessorDirectives.BLANK :
- String remainderOfLine =
- getRestOfPreprocessorLine().trim();
- if (!remainderOfLine.equals("")) { //$NON-NLS-1$
- StringBuffer buffer = new StringBuffer( "# "); //$NON-NLS-1$
- buffer.append( remainderOfLine );
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true);
- }
+ case '*' :
+ skipOverMultilineComment();
c = getChar();
continue;
+ case '=' : return newConstantToken(IToken.tDIVASSIGN);
default :
- StringBuffer buffer = new StringBuffer( "# "); //$NON-NLS-1$
- buffer.append( token );
- handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
+ ungetChar(c);
+ return newConstantToken(IToken.tDIV);
}
- }
- } else {
- switch (c) {
- case '\'' :
- return processCharacterLiteral( c, wideLiteral );
- case ':' :
- c = getChar();
- switch (c) {
- case ':' :
- return newToken(
- IToken.tCOLONCOLON,
- "::", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tCOLON,
- ":", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case ';' :
- return newToken(IToken.tSEMI, ";", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case ',' :
- return newToken(IToken.tCOMMA, ",", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '?' :
- return newToken(IToken.tQUESTION, "?", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '(' :
- return newToken(IToken.tLPAREN, "(", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case ')' :
- return newToken(IToken.tRPAREN, ")", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '[' :
- return newToken(IToken.tLBRACKET, "[", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case ']' :
- return newToken(IToken.tRBRACKET, "]", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '{' :
- return newToken(IToken.tLBRACE, "{", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '}' :
- return newToken(IToken.tRBRACE, "}", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '+' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tPLUSASSIGN,
- "+=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- case '+' :
- return newToken(
- IToken.tINCR,
- "++", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tPLUS,
- "+", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '-' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tMINUSASSIGN,
- "-=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- case '-' :
- return newToken(
- IToken.tDECR,
- "--", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- case '>' :
- c = getChar();
- switch (c) {
- case '*' :
- return newToken(
- IToken.tARROWSTAR,
- "->*", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tARROW,
- "->", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- default :
- ungetChar(c);
- return newToken(
- IToken.tMINUS,
- "-", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '*' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tSTARASSIGN,
- "*=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tSTAR,
- "*", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '%' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tMODASSIGN,
- "%=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tMOD,
- "%", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '^' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tXORASSIGN,
- "^=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tXOR,
- "^", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '&' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tAMPERASSIGN,
- "&=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- case '&' :
- return newToken(
- IToken.tAND,
- "&&", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tAMPER,
- "&", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '|' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tBITORASSIGN,
- "|=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- case '|' :
- return newToken(
- IToken.tOR,
- "||", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tBITOR,
- "|", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '~' :
- return newToken(IToken.tCOMPL, "~", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- case '!' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tNOTEQUAL,
- "!=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tNOT,
- "!", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '=' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tEQUAL,
- "==", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tASSIGN,
- "=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '<' :
- c = getChar();
- switch (c) {
- case '<' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tSHIFTLASSIGN,
- "<<=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tSHIFTL,
- "<<", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '=' :
- return newToken(
- IToken.tLTEQUAL,
- "<=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- if( forInclusion )
- temporarilyReplaceDefinitionsMap();
- return newToken(IToken.tLT, "<", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- }
- case '>' :
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ token = processNumber(c, pasting);
+ if (token == null)
+ {
c = getChar();
- switch (c) {
- case '>' :
- c = getChar();
- switch (c) {
- case '=' :
- return newToken(
- IToken.tSHIFTRASSIGN,
- ">>=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tSHIFTR,
- ">>", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- case '=' :
- return newToken(
- IToken.tGTEQUAL,
- ">=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- if( forInclusion )
- restoreDefinitionsMap();
- return newToken(IToken.tGT, ">", scannerData.getContextStack().getCurrentContext()); //$NON-NLS-1$
- }
- case '.' :
+ continue;
+ }
+ return token;
+
+ case 'L' :
+ // check for wide literal
+ c = getChar();
+ if (c == '"')
+ token = processStringLiteral(true);
+ else if (c == '\'')
+ return processCharacterLiteral( c, true );
+ else
+ {
+ // This is not a wide literal -- it must be a token or keyword
+ ungetChar(c);
+ token = processKeywordOrLiteral('L', pasting);
+ }
+ if (token == null)
+ {
c = getChar();
- switch (c) {
- case '.' :
- c = getChar();
- switch (c) {
- case '.' :
- return newToken(
- IToken.tELLIPSIS,
- "...", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- break;
- }
- break;
- case '*' :
- return newToken(
- IToken.tDOTSTAR,
- ".*", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tDOT,
- ".", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- break;
- case '/' :
+ continue;
+ }
+ return token;
+ case '"' :
+ token = processStringLiteral(false);
+ if (token == null)
+ {
c = getChar();
- switch (c) {
- case '/' :
- skipOverSinglelineComment();
- c = getChar();
- continue;
- case '*' :
- skipOverMultilineComment();
- c = getChar();
- continue;
- case '=' :
- return newToken(
- IToken.tDIVASSIGN,
- "/=", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- default :
- ungetChar(c);
- return newToken(
- IToken.tDIV,
- "/", //$NON-NLS-1$
- scannerData.getContextStack().getCurrentContext());
- }
- default :
- handleProblem( IProblem.SCANNER_BAD_CHARACTER, new Character( (char)c ).toString(), getCurrentOffset(), false, true, throwExceptionOnBadCharacterRead );
+ continue;
+ }
+ return token;
+ case '\'' : return processCharacterLiteral( c, false );
+ case '#':
+ // This is a special case -- the preprocessor is integrated into
+ // the scanner. If we get a null token, it means that everything
+ // was handled correctly and we can go on to the next characgter.
+
+ token = processPreprocessor();
+ if (token == null)
+ {
c = getChar();
continue;
- }
-
- throwEOF(null);
+ }
+ return token;
+
+ default:
+ if (
+ // JOHNC - Accept non-ASCII Input
+// ((c >= 'a') && (c <= 'z'))
+// || ((c >= 'A') && (c <= 'Z')) || (c == '_')) {
+ Character.isLetter((char)c) || ( c == '_')
+ )
+ {
+ token = processKeywordOrLiteral(c, pasting);
+ if (token == null)
+ {
+ c = getChar();
+ continue;
+ }
+ return token;
+ }
+
+ handleProblem( IProblem.SCANNER_BAD_CHARACTER, new Character( (char)c ).toString(), getCurrentOffset(), false, true, throwExceptionOnBadCharacterRead );
+ c = getChar();
+ continue;
}
}
-
if (( getDepth() != 0) && !atEOF )
{
atEOF = true;
Index: parser/org/eclipse/cdt/internal/core/parser/token/Token.java
===================================================================
retrieving revision 1.3
diff -u -r1.3 Token.java
--- parser/org/eclipse/cdt/internal/core/parser/token/Token.java 26 Feb 2004 23:10:24 -0000 1.3
+++ parser/org/eclipse/cdt/internal/core/parser/token/Token.java 7 Mar 2004 16:24:36 -0000
@@ -10,16 +10,31 @@
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.token;
+import org.eclipse.cdt.core.parser.Keywords;
+import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.parser.scanner.*;
public class Token implements IToken {
public Token(int t, String i, IScannerContext context, int lineNumber ) {
- type = t;
- image = i;
+ setType(t);
+ setImage(i);
filename = context.getFilename();
- offset = context.getOffset() - image.length() - context.undoStackSize();
+ offset = context.getOffset() - getImage().length() - context.undoStackSize();
+ this.lineNumber = lineNumber;
+ macroOffset = context.getMacroOffset();
+ macroLength = context.getMacroLength();
+
+ if( type == tLSTRING || type == tSTRING || type == tCHAR ){
+ offset--;
+ }
+ }
+ public Token(int t, IScannerContext context, int lineNumber ) {
+ setType(t);
+ setImage(null);
+ filename = context.getFilename();
+ offset = context.getOffset() - getImage().length() - context.undoStackSize();
this.lineNumber = lineNumber;
macroOffset = context.getMacroOffset();
macroLength = context.getMacroLength();
@@ -29,21 +44,301 @@
}
}
+ public Token(int t) {
+ setType(t);
+ setImage(null);
+ }
public Token(int t, String i) {
- type = t;
- image = i;
+ setType(t);
+ setImage(i);
}
public String toString()
{
- return "Token type=" + type + " image =" + image + " offset=" + offset; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ return "Token type=" + type + " image =" + getImage() + " offset=" + offset; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
-
+
public int type;
public int getType() { return type; }
protected String image;
- public String getImage() { return image; }
+
+ public String getImage() {
+ switch ( getType() ) {
+
+ case IToken.tIDENTIFIER :
+ case IToken.tINTEGER :
+ case IToken.tFLOATINGPT :
+ case IToken.tSTRING :
+ case IToken.tLSTRING :
+ case IToken.tCHAR :
+ case IToken.tLCHAR :
+ return image;
+
+ case IToken.tCOLONCOLON :
+ return "::" ; //$NON-NLS-1$
+ case IToken.tCOLON :
+ return ":" ; //$NON-NLS-1$
+ case IToken.tSEMI :
+ return ";" ; //$NON-NLS-1$
+ case IToken.tCOMMA :
+ return "," ; //$NON-NLS-1$
+ case IToken.tQUESTION :
+ return "?" ; //$NON-NLS-1$
+ case IToken.tLPAREN :
+ return "(" ; //$NON-NLS-1$
+ case IToken.tRPAREN :
+ return ")" ; //$NON-NLS-1$
+ case IToken.tLBRACKET :
+ return "[" ; //$NON-NLS-1$
+ case IToken.tRBRACKET :
+ return "]" ; //$NON-NLS-1$
+ case IToken.tLBRACE :
+ return "{" ; //$NON-NLS-1$
+ case IToken.tRBRACE :
+ return "}"; //$NON-NLS-1$
+ case IToken.tPLUSASSIGN :
+ return "+="; //$NON-NLS-1$
+ case IToken.tINCR :
+ return "++" ; //$NON-NLS-1$
+ case IToken.tPLUS :
+ return "+"; //$NON-NLS-1$
+ case IToken.tMINUSASSIGN :
+ return "-=" ; //$NON-NLS-1$
+ case IToken.tDECR :
+ return "--" ; //$NON-NLS-1$
+ case IToken.tARROWSTAR :
+ return "->*" ; //$NON-NLS-1$
+ case IToken.tARROW :
+ return "->" ; //$NON-NLS-1$
+ case IToken.tMINUS :
+ return "-" ; //$NON-NLS-1$
+ case IToken.tSTARASSIGN :
+ return "*=" ; //$NON-NLS-1$
+ case IToken.tSTAR :
+ return "*" ; //$NON-NLS-1$
+ case IToken.tMODASSIGN :
+ return "%=" ; //$NON-NLS-1$
+ case IToken.tMOD :
+ return "%" ; //$NON-NLS-1$
+ case IToken.tXORASSIGN :
+ return "^=" ; //$NON-NLS-1$
+ case IToken.tXOR :
+ return "^" ; //$NON-NLS-1$
+ case IToken.tAMPERASSIGN :
+ return "&=" ; //$NON-NLS-1$
+ case IToken.tAND :
+ return "&&" ; //$NON-NLS-1$
+ case IToken.tAMPER :
+ return "&" ; //$NON-NLS-1$
+ case IToken.tBITORASSIGN :
+ return "|=" ; //$NON-NLS-1$
+ case IToken.tOR :
+ return "||" ; //$NON-NLS-1$
+ case IToken.tBITOR :
+ return "|" ; //$NON-NLS-1$
+ case IToken.tCOMPL :
+ return "~" ; //$NON-NLS-1$
+ case IToken.tNOTEQUAL :
+ return "!=" ; //$NON-NLS-1$
+ case IToken.tNOT :
+ return "!" ; //$NON-NLS-1$
+ case IToken.tEQUAL :
+ return "==" ; //$NON-NLS-1$
+ case IToken.tASSIGN :
+ return "=" ; //$NON-NLS-1$
+ case IToken.tSHIFTL :
+ return "<<" ; //$NON-NLS-1$
+ case IToken.tLTEQUAL :
+ return "<=" ; //$NON-NLS-1$
+ case IToken.tLT :
+ return "<"; //$NON-NLS-1$
+ case IToken.tSHIFTRASSIGN :
+ return ">>=" ; //$NON-NLS-1$
+ case IToken.tSHIFTR :
+ return ">>" ; //$NON-NLS-1$
+ case IToken.tGTEQUAL :
+ return ">=" ; //$NON-NLS-1$
+ case IToken.tGT :
+ return ">" ; //$NON-NLS-1$
+ case IToken.tSHIFTLASSIGN :
+ return "<<=" ; //$NON-NLS-1$
+ case IToken.tELLIPSIS :
+ return "..." ; //$NON-NLS-1$
+ case IToken.tDOTSTAR :
+ return ".*" ; //$NON-NLS-1$
+ case IToken.tDOT :
+ return "." ; //$NON-NLS-1$
+ case IToken.tDIVASSIGN :
+ return "/=" ; //$NON-NLS-1$
+ case IToken.tDIV :
+ return "/" ; //$NON-NLS-1$
+ case IToken.t_and :
+ return Keywords.AND;
+ case IToken.t_and_eq :
+ return Keywords.AND_EQ ;
+ case IToken.t_asm :
+ return Keywords.ASM ;
+ case IToken.t_auto :
+ return Keywords.AUTO ;
+ case IToken.t_bitand :
+ return Keywords.BITAND ;
+ case IToken.t_bitor :
+ return Keywords.BITOR ;
+ case IToken.t_bool :
+ return Keywords.BOOL ;
+ case IToken.t_break :
+ return Keywords.BREAK ;
+ case IToken.t_case :
+ return Keywords.CASE ;
+ case IToken.t_catch :
+ return Keywords.CATCH ;
+ case IToken.t_char :
+ return Keywords.CHAR ;
+ case IToken.t_class :
+ return Keywords.CLASS ;
+ case IToken.t_compl :
+ return Keywords.COMPL ;
+ case IToken.t_const :
+ return Keywords.CONST ;
+ case IToken.t_const_cast :
+ return Keywords.CONST_CAST ;
+ case IToken.t_continue :
+ return Keywords.CONTINUE ;
+ case IToken.t_default :
+ return Keywords.DEFAULT ;
+ case IToken.t_delete :
+ return Keywords.DELETE ;
+ case IToken.t_do :
+ return Keywords.DO;
+ case IToken.t_double :
+ return Keywords.DOUBLE ;
+ case IToken.t_dynamic_cast :
+ return Keywords.DYNAMIC_CAST ;
+ case IToken.t_else :
+ return Keywords.ELSE;
+ case IToken.t_enum :
+ return Keywords.ENUM ;
+ case IToken.t_explicit :
+ return Keywords.EXPLICIT ;
+ case IToken.t_export :
+ return Keywords.EXPORT ;
+ case IToken.t_extern :
+ return Keywords.EXTERN;
+ case IToken.t_false :
+ return Keywords.FALSE;
+ case IToken.t_float :
+ return Keywords.FLOAT;
+ case IToken.t_for :
+ return Keywords.FOR;
+ case IToken.t_friend :
+ return Keywords.FRIEND;
+ case IToken.t_goto :
+ return Keywords.GOTO;
+ case IToken.t_if :
+ return Keywords.IF ;
+ case IToken.t_inline :
+ return Keywords.INLINE ;
+ case IToken.t_int :
+ return Keywords.INT ;
+ case IToken.t_long :
+ return Keywords.LONG ;
+ case IToken.t_mutable :
+ return Keywords.MUTABLE ;
+ case IToken.t_namespace :
+ return Keywords.NAMESPACE ;
+ case IToken.t_new :
+ return Keywords.NEW ;
+ case IToken.t_not :
+ return Keywords.NOT ;
+ case IToken.t_not_eq :
+ return Keywords.NOT_EQ;
+ case IToken.t_operator :
+ return Keywords.OPERATOR ;
+ case IToken.t_or :
+ return Keywords.OR ;
+ case IToken.t_or_eq :
+ return Keywords.OR_EQ;
+ case IToken.t_private :
+ return Keywords.PRIVATE ;
+ case IToken.t_protected :
+ return Keywords.PROTECTED ;
+ case IToken.t_public :
+ return Keywords.PUBLIC ;
+ case IToken.t_register :
+ return Keywords.REGISTER ;
+ case IToken.t_reinterpret_cast :
+ return Keywords.REINTERPRET_CAST ;
+ case IToken.t_return :
+ return Keywords.RETURN ;
+ case IToken.t_short :
+ return Keywords.SHORT ;
+ case IToken.t_sizeof :
+ return Keywords.SIZEOF ;
+ case IToken.t_static :
+ return Keywords.STATIC ;
+ case IToken.t_static_cast :
+ return Keywords.STATIC_CAST ;
+ case IToken.t_signed :
+ return Keywords.SIGNED ;
+ case IToken.t_struct :
+ return Keywords.STRUCT ;
+ case IToken.t_switch :
+ return Keywords.SWITCH ;
+ case IToken.t_template :
+ return Keywords.TEMPLATE ;
+ case IToken.t_this :
+ return Keywords.THIS ;
+ case IToken.t_throw :
+ return Keywords.THROW ;
+ case IToken.t_true :
+ return Keywords.TRUE ;
+ case IToken.t_try :
+ return Keywords.TRY ;
+ case IToken.t_typedef :
+ return Keywords.TYPEDEF ;
+ case IToken.t_typeid :
+ return Keywords.TYPEID ;
+ case IToken.t_typename :
+ return Keywords.TYPENAME ;
+ case IToken.t_union :
+ return Keywords.UNION ;
+ case IToken.t_unsigned :
+ return Keywords.UNSIGNED ;
+ case IToken.t_using :
+ return Keywords.USING ;
+ case IToken.t_virtual :
+ return Keywords.VIRTUAL ;
+ case IToken.t_void :
+ return Keywords.VOID ;
+ case IToken.t_volatile :
+ return Keywords.VOLATILE;
+ case IToken.t_wchar_t :
+ return Keywords.WCHAR_T ;
+ case IToken.t_while :
+ return Keywords.WHILE ;
+ case IToken.t_xor :
+ return Keywords.XOR ;
+ case IToken.t_xor_eq :
+ return Keywords.XOR_EQ ;
+ case IToken.t__Bool :
+ return Keywords._BOOL ;
+ case IToken.t__Complex :
+ return Keywords._COMPLEX ;
+ case IToken.t__Imaginary :
+ return Keywords._IMAGINARY ;
+ case IToken.t_restrict :
+ return Keywords.RESTRICT ;
+ case IScanner.tPOUND:
+ return "#"; //$NON-NLS-1$
+ case IScanner.tPOUNDPOUND:
+ return "##"; //$NON-NLS-1$
+
+ default :
+ // we should never get here!
+ return image;
+ }
+ }
public String filename;
@@ -53,7 +348,9 @@
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
public int getOffset() { return (macroOffset < 0) ? offset : macroOffset; }
- public int getLength() { return (macroLength < 0) ? image.length() : macroLength; }
+
+ public int getLength() { return (macroLength < 0) ? getImage().length() : macroLength; }
+
public int getEndOffset() { return getOffset() + getLength(); }
@@ -156,7 +453,6 @@
image = i;
}
-
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
@@ -165,7 +461,7 @@
if( other == null ) return false;
if( !( other instanceof IToken ) )
return false;
- if( !(((IToken)other).getImage().equals( image )))
+ if( !(((IToken)other).getImage().equals( getImage() )))
return false;
if( ((IToken)other).getType() != type )
return false;