1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

scanner performance improvements from Dave Daoust

This commit is contained in:
Andrew Niefer 2004-03-16 22:23:36 +00:00
parent 1661bb8022
commit 4b5850c062
4 changed files with 124 additions and 119 deletions

View file

@ -1,3 +1,8 @@
2004-03-16 Dave Daoust
refactor scanner for performance improvements
-changes to accountForUndo, now named readFromStream
-changes to checking for valid macros
2004-03-15 Andrew Niefer 2004-03-15 Andrew Niefer
Templates: Templates:
- added ISourceElementRequestor.acceptTemplateParameterReference - added ISourceElementRequestor.acceptTemplateParameterReference

View file

@ -82,11 +82,11 @@ public class GCCScannerExtension implements IScannerExtension {
{ {
scannerData.getLogService().traceLog( "GCCScannerExtension handling #include_next directive" ); //$NON-NLS-1$ scannerData.getLogService().traceLog( "GCCScannerExtension handling #include_next directive" ); //$NON-NLS-1$
// figure out the name of the current file and its path // figure out the name of the current file and its path
IScannerContext context = scannerData.getContextStack().getCurrentContext(); // IScannerContext context = scannerData.getContextStack().getCurrentContext();
if( context.getKind() != IScannerContext.ContextKind.INCLUSION ) // if( context.getKind() != IScannerContext.ContextKind.INCLUSION )
{ // {
//handle appropriate error // //handle appropriate error
} // }
// String fullInclusionPath = context.getFilename(); // String fullInclusionPath = context.getFilename();
// IASTInclusion inclusion = context.getExtension(); // IASTInclusion inclusion = context.getExtension();

View file

@ -721,7 +721,7 @@ public class Scanner implements IScanner {
return getChar(); return getChar();
} }
int getChar() throws ScannerException final int getChar() throws ScannerException
{ {
return getChar( false ); return getChar( false );
} }
@ -731,12 +731,14 @@ public class Scanner implements IScanner {
lastContext = scannerData.getContextStack().getCurrentContext(); lastContext = scannerData.getContextStack().getCurrentContext();
if (scannerData.getContextStack().getCurrentContext() == null) if (lastContext == null)
// past the end of file // past the end of file
return c; return c;
c = accountForUndo(c); if (lastContext.undoStackSize() != 0 )
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1; c = lastContext.popUndo();
else
c = readFromStream();
if (enableTrigraphReplacement && (!insideString || enableTrigraphReplacementInStrings)) { if (enableTrigraphReplacement && (!insideString || enableTrigraphReplacementInStrings)) {
// Trigraph processing // Trigraph processing
@ -747,39 +749,39 @@ public class Scanner implements IScanner {
c = getChar(insideString); c = getChar(insideString);
switch (c) { switch (c) {
case '(': case '(':
expandDefinition("??(", "[", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??(", "[", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case ')': case ')':
expandDefinition("??)", "]", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??)", "]", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '<': case '<':
expandDefinition("??<", "{", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??<", "{", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '>': case '>':
expandDefinition("??>", "}", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??>", "}", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '=': case '=':
expandDefinition("??=", "#", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??=", "#", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '/': case '/':
expandDefinition("??/", "\\", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??/", "\\", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '\'': case '\'':
expandDefinition("??\'", "^", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??\'", "^", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '!': case '!':
expandDefinition("??!", "|", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??!", "|", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
case '-': case '-':
expandDefinition("??-", "~", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("??-", "~", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString); c = getChar(insideString);
break; break;
default: default:
@ -805,10 +807,10 @@ public class Scanner implements IScanner {
if (c == '<') { if (c == '<') {
c = getChar(false); c = getChar(false);
if (c == '%') { if (c == '%') {
expandDefinition("<%", "{", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("<%", "{", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false); c = getChar(false);
} else if (c == ':') { } else if (c == ':') {
expandDefinition("<:", "[", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("<:", "[", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false); c = getChar(false);
} else { } else {
// Not a digraph // Not a digraph
@ -818,7 +820,7 @@ public class Scanner implements IScanner {
} else if (c == ':') { } else if (c == ':') {
c = getChar(false); c = getChar(false);
if (c == '>') { if (c == '>') {
expandDefinition(":>", "]", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition(":>", "]", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false); c = getChar(false);
} else { } else {
// Not a digraph // Not a digraph
@ -828,10 +830,10 @@ public class Scanner implements IScanner {
} else if (c == '%') { } else if (c == '%') {
c = getChar(false); c = getChar(false);
if (c == '>') { if (c == '>') {
expandDefinition("%>", "}", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("%>", "}", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false); c = getChar(false);
} else if (c == ':') { } else if (c == ':') {
expandDefinition("%:", "#", baseOffset); //$NON-NLS-1$ //$NON-NLS-2$ expandDefinition("%:", "#", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false); c = getChar(false);
} else { } else {
// Not a digraph // Not a digraph
@ -845,38 +847,29 @@ public class Scanner implements IScanner {
return c; return c;
} }
protected int accountForUndo(int c) protected int readFromStream()
{ {
boolean done; int c;
do {
done = true;
if (scannerData.getContextStack().getCurrentContext().undoStackSize() != 0 ) {
c = scannerData.getContextStack().getCurrentContext().popUndo();
} else {
try { try {
c = scannerData.getContextStack().getCurrentContext().read(); c = scannerData.getContextStack().getCurrentContext().read();
if (c == NOCHAR) { }
if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false) { catch (IOException e) {
c = NOCHAR; c = NOCHAR;
break;
} else {
done = false;
}
}
} catch (IOException e) {
if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false) {
c = NOCHAR;
} else {
done = false;
}
}
}
} while (!done);
return c;
} }
void ungetChar(int c) throws ScannerException{ if (c != NOCHAR)
return c;
if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false)
return NOCHAR;
if (scannerData.getContextStack().getCurrentContext().undoStackSize() != 0 )
return scannerData.getContextStack().getCurrentContext().popUndo();
return readFromStream();
}
final void ungetChar(int c) throws ScannerException{
scannerData.getContextStack().getCurrentContext().pushUndo(c); scannerData.getContextStack().getCurrentContext().pushUndo(c);
try try
{ {
@ -1220,9 +1213,12 @@ public class Scanner implements IScanner {
if (directive == null) { if (directive == null) {
if( scannerExtension.canHandlePreprocessorDirective( token ) ) if( scannerExtension.canHandlePreprocessorDirective( token ) )
scannerExtension.handlePreprocessorDirective( token, getRestOfPreprocessorLine() ); scannerExtension.handlePreprocessorDirective( token, getRestOfPreprocessorLine() );
else
{
StringBuffer buffer = new StringBuffer( "#"); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer( "#"); //$NON-NLS-1$
buffer.append( token ); buffer.append( token );
handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true ); handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
}
return null; return null;
} }
@ -1432,12 +1428,12 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
// do the least expensive tests first!
while ( while (
Character.isUnicodeIdentifierPart( (char)c) ((c >= 'a') && (c <= 'z'))
// ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
// || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'))
// || ((c >= '0') && (c <= '9')) || (c == '_') || Character.isUnicodeIdentifierPart( (char)c)
// || (c == '_')
) { ) {
buff.append((char) c); buff.append((char) c);
c = getChar(); c = getChar();
@ -2545,6 +2541,36 @@ public class Scanner implements IScanner {
return macroReplacementTokens; return macroReplacementTokens;
} }
protected IMacroDescriptor createObjectMacroDescriptor(String key, String value ) {
StringBuffer signatureBuffer = new StringBuffer();
signatureBuffer.append( key );
signatureBuffer.append( ' ' );
signatureBuffer.append( value );
// List macroReplacementTokens;
// if (value.trim().equals( "" ))
// macroReplacementTokens = new ArrayList();
// else
// macroReplacementTokens = tokenizeReplacementString( NO_OFFSET_LIMIT, key, value, null );
List macroReplacementTokens = new ArrayList();
if( !value.trim().equals( "" ) ) //$NON-NLS-1$
{
Token t = new Token(
IToken.tIDENTIFIER,
value,
scannerData.getContextStack().getCurrentContext(),
scannerData.getContextStack().getCurrentLineNumber()
);
macroReplacementTokens.add( t );
}
return new ObjectMacroDescriptor( key,
signatureBuffer.toString(),
macroReplacementTokens,
value);
}
protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException { protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException {
StringBuffer potentialErrorMessage = new StringBuffer( POUND_DEFINE ); StringBuffer potentialErrorMessage = new StringBuffer( POUND_DEFINE );
@ -2636,8 +2662,9 @@ public class Scanner implements IScanner {
} }
else if ((c == '\n') || (c == '\r')) else if ((c == '\n') || (c == '\r'))
{ {
checkValidMacroRedefinition(key, previousDefinition, "", beginning); //$NON-NLS-1$ descriptor = createObjectMacroDescriptor(key, ""); //$NON-NLS-1$
addDefinition( key, "" ); //$NON-NLS-1$ checkValidMacroRedefinition(key, previousDefinition, descriptor, beginning);
addDefinition( key, descriptor );
} }
else if ((c == ' ') || (c == '\t') ) { else if ((c == ' ') || (c == '\t') ) {
// this is a simple definition // this is a simple definition
@ -2646,8 +2673,9 @@ public class Scanner implements IScanner {
// get what we are to map the name to and add it to the definitions list // get what we are to map the name to and add it to the definitions list
String value = getRestOfPreprocessorLine(); String value = getRestOfPreprocessorLine();
checkValidMacroRedefinition(key, previousDefinition, value, beginning); descriptor = createObjectMacroDescriptor(key, value);
addDefinition( key, value ); checkValidMacroRedefinition(key, previousDefinition, descriptor, beginning);
addDefinition( key, descriptor );
} else if (c == '/') { } else if (c == '/') {
// this could be a comment // this could be a comment
@ -2655,20 +2683,23 @@ public class Scanner implements IScanner {
if (c == '/') // one line comment if (c == '/') // one line comment
{ {
skipOverSinglelineComment(); skipOverSinglelineComment();
checkValidMacroRedefinition(key, previousDefinition, "", beginning); //$NON-NLS-1$ descriptor = createObjectMacroDescriptor(key, ""); //$NON-NLS-1$
addDefinition(key, ""); //$NON-NLS-1$ checkValidMacroRedefinition(key, previousDefinition, descriptor, beginning);
addDefinition(key, descriptor);
} else if (c == '*') // multi-line comment } else if (c == '*') // multi-line comment
{ {
if (skipOverMultilineComment()) { if (skipOverMultilineComment()) {
// we have gone over a newline // we have gone over a newline
// therefore, this symbol was defined to an empty string // therefore, this symbol was defined to an empty string
checkValidMacroRedefinition(key, previousDefinition, "", beginning); //$NON-NLS-1$ descriptor = createObjectMacroDescriptor(key, ""); //$NON-NLS-1$
addDefinition(key, ""); //$NON-NLS-1$ checkValidMacroRedefinition(key, previousDefinition, descriptor, beginning);
addDefinition(key, descriptor);
} else { } else {
String value = getRestOfPreprocessorLine(); String value = getRestOfPreprocessorLine();
checkValidMacroRedefinition(key, previousDefinition, "", beginning); //$NON-NLS-1$ descriptor = createObjectMacroDescriptor(key, value);
addDefinition(key, value); checkValidMacroRedefinition(key, previousDefinition, descriptor, beginning);
addDefinition(key, descriptor);
} }
} else { } else {
// this is not a comment // this is not a comment
@ -2699,40 +2730,6 @@ public class Scanner implements IScanner {
} }
} }
protected void checkValidMacroRedefinition(
String key,
IMacroDescriptor previousDefinition,
String newDefinition, int beginningOffset )
throws ScannerException
{
StringBuffer buffer = new StringBuffer(key);
buffer.append( ' ');
buffer.append(newDefinition);
IMacroDescriptor newMacro = new ObjectMacroDescriptor( key, buffer.toString(),
tokenizeReplacementString( NO_OFFSET_LIMIT, key, newDefinition, null ), newDefinition );
checkValidMacroRedefinition( key, previousDefinition, newMacro, beginningOffset );
}
protected void checkValidMacroRedefinition(
String key,
String previousDefinition,
String newDefinition, int beginningOffset )
throws ScannerException
{
StringBuffer oldMacro = new StringBuffer( key );
oldMacro.append( ' ');
StringBuffer newMacro = new StringBuffer( oldMacro.toString() );
oldMacro.append( previousDefinition );
newMacro.append( newDefinition );
IMacroDescriptor prevMacroDescriptor = new ObjectMacroDescriptor( key, oldMacro.toString(),
tokenizeReplacementString( NO_OFFSET_LIMIT, key, previousDefinition, null ), previousDefinition );
IMacroDescriptor newMacroDescriptor = new ObjectMacroDescriptor( key, newMacro.toString(),
tokenizeReplacementString( NO_OFFSET_LIMIT, key, newDefinition, null ), newDefinition );
checkValidMacroRedefinition( key, prevMacroDescriptor, newMacroDescriptor, beginningOffset );
}
protected void checkValidMacroRedefinition( protected void checkValidMacroRedefinition(
String key, String key,
IMacroDescriptor previousDefinition, IMacroDescriptor previousDefinition,

View file

@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.Stack;
import org.eclipse.cdt.core.parser.ast.IASTInclusion; import org.eclipse.cdt.core.parser.ast.IASTInclusion;
@ -24,7 +23,6 @@ public class ScannerContext implements IScannerContext
private int macroLength = -1; private int macroLength = -1;
private int line = 1; private int line = 1;
private int offset; private int offset;
private Stack undo = new Stack();
private ContextKind kind; private ContextKind kind;
/* (non-Javadoc) /* (non-Javadoc)
@ -108,18 +106,15 @@ public class ScannerContext implements IScannerContext
return line; return line;
} }
/** /* there are never more than 2 elements in the unget stack!
* Returns the reader. * trigraphs may involve 2, but in general there is a single element
* @return Reader * I have made room for 10 -- just in case :-)
*/ */
public final Reader getReader() private int pos = 0;
{ private int undo[] = new int[10];
return reader;
}
public final int undoStackSize() public final int undoStackSize()
{ {
return undo.size(); return pos;
} }
/** /**
@ -128,7 +123,7 @@ public class ScannerContext implements IScannerContext
*/ */
public final int popUndo() public final int popUndo()
{ {
int c = ((Integer)undo.pop()).intValue(); int c = undo[--pos];
if ((char)c == '\n') line++; if ((char)c == '\n') line++;
return c; return c;
} }
@ -137,10 +132,18 @@ public class ScannerContext implements IScannerContext
* Sets the undo. * Sets the undo.
* @param undo The undo to set * @param undo The undo to set
*/ */
public void pushUndo(int undo) public final void pushUndo(int c)
{ {
if ((char)undo == '\n') line--; if ((char)c == '\n') line--;
this.undo.push( new Integer( undo )); undo[pos++] = c;
}
/**
* Returns the reader.
* @return Reader
*/
public final Reader getReader()
{
return reader;
} }