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

Patch for David Daoust. <BR>

Refactored the scanner to make Scanner Contexts more specific for macro expansions and inclusions, yielding performance and memory improvements.
This commit is contained in:
John Camelon 2004-05-13 13:15:40 +00:00
parent 3e7939462a
commit 5ba83e3c91
15 changed files with 448 additions and 446 deletions

View file

@ -1153,10 +1153,10 @@ public class QuickParseASTTests extends BaseASTTest
}
}
public void testPreprocessor() throws Exception
{
Writer code = new StringWriter();
code.write( "#include <stdio.h>\n#define DEF VALUE\n"); //$NON-NLS-1$
public void testPreprocessor() throws Exception {
String code = "#include <stdio.h>\n#define DEF VALUE\n"; //$NON-NLS-1$
IASTCompilationUnit tu = parse( code.toString() );
assertFalse( tu.getDeclarations().hasNext());
Iterator inclusions = quickParseCallback.getInclusions();
@ -1173,9 +1173,9 @@ public class QuickParseASTTests extends BaseASTTest
IASTMacro m = (IASTMacro)macros.next();
assertEquals( m.getName(), "DEF" ); //$NON-NLS-1$
assertEquals( m.getStartingOffset(), 19 );
assertEquals( m.getNameOffset(), 27 );
assertEquals( m.getEndingOffset(), 18 + 19);
assertEquals( m.getStartingOffset(), code.indexOf("#define") ); //$NON-NLS-1$
assertEquals( m.getNameOffset(), code.indexOf("DEF") );
assertEquals( m.getEndingOffset(), code.indexOf("VALUE") + 5);
}
public void testTemplateDeclarationOfFunction() throws Exception

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException;
import java.io.Reader;
import org.eclipse.cdt.core.parser.IParserLogService;
@ -30,25 +29,17 @@ import org.eclipse.cdt.internal.core.parser.util.TraceUtil;
public class ContextStack {
private static class SentinelContext implements IScannerContext {
public int read() throws IOException { return '\n'; }
public String getFilename() { return ""; } //$NON-NLS-1$
public int getMacroOffset() { return -1; }
public int getMacroLength() { return -1; }
public int getChar() { return '\n'; }
public String getContextName() { return ""; } //$NON-NLS-1$
public int getOffset() { return 0; }
public int getRelativeOffset() { return 0; }
public Reader getReader() { return null; }
public void pushUndo(int undo) { }
public void ungetChar(int undo) { }
public int getKind() { return IScannerContext.ContextKind.SENTINEL; }
public void setKind(int kind) { }
public IASTInclusion getExtension() { return null; }
public void setExtension(IASTInclusion ext) { }
public int getLine() { return -1; }
public int undoStackSize() { return 0; }
public int popUndo() { return '\n'; }
public int getFilenameIndex() { return -1; }
public void close() { }
}
private final IParserLogService log;
private int current_size = 8;
private int lastFileContext = 0;
private IScannerContext [] cs = new IScannerContext[current_size];
private int cs_pos = 0;
@ -59,7 +50,6 @@ public class ContextStack {
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
public final String getInclusionFilename( int index )
{
try
@ -121,81 +111,62 @@ public class ContextStack {
scanner.setScannerContext(sentinel);
}
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor) throws ContextException {
updateContext(reader, filename, type, inclusion, requestor, -1, -1);
public void updateInclusionContext(Reader reader, String filename, IASTInclusion inclusion, ISourceElementRequestor requestor) throws ContextException {
addInclusionFilename( filename );
ScannerContextInclusion context = new ScannerContextInclusion( reader, filename, inclusion, currentInclusionIndex - 1 );
if( isCircularInclusion( context.getContextName() ) )
throw new ContextException( IProblem.PREPROCESSOR_CIRCULAR_INCLUSION );
TraceUtil.outputTrace(log, "Scanner::ContextStack: entering inclusion ", null, context.getContextName(), null, null ); //$NON-NLS-1$
context.getExtension().enterScope( requestor );
cs_push(context);
lastFileContext++;
}
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ContextException
{
int startLine = 1;
int index = -1;
public void updateMacroContext(String reader, String filename, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ContextException
{
// If we expand a macro within a macro, then keep offsets of the top-level one,
// as only the top level macro identifier is properly positioned
if (type == IScannerContext.ContextKind.MACROEXPANSION) {
if (getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION) {
macroOffset = getCurrentContext().getMacroOffset();
macroLength = getCurrentContext().getMacroLength();
}
startLine = getCurrentContext().getLine();
if (getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION) {
macroOffset = ((ScannerContextMacro)getCurrentContext()).getOffset();
macroLength = ((ScannerContextMacro)getCurrentContext()).getMacroLength();
}
else if( type == IScannerContext.ContextKind.INCLUSION )
{
addInclusionFilename( filename );
index = currentInclusionIndex - 1;
}
IScannerContext context = new ScannerContext( reader, filename, type, null, macroOffset, macroLength, startLine, index );
context.setExtension(inclusion);
push( context, requestor );
cs_push(new ScannerContextMacro(
reader,
filename,
macroOffset, macroLength));
}
protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ContextException
protected void pushInitialContext( IScannerContext context ) throws ContextException
{
if( context.getKind() == IScannerContext.ContextKind.INCLUSION ) {
if( isCircularInclusion( context.getFilename() ) )
throw new ContextException( IProblem.PREPROCESSOR_CIRCULAR_INCLUSION );
TraceUtil.outputTrace(log, "Scanner::ContextStack: entering inclusion ", null, context.getFilename(), null, null ); //$NON-NLS-1$
context.getExtension().enterScope( requestor );
}
else if( context.getKind() == IScannerContext.ContextKind.TOP )
{
addInclusionFilename( context.getFilename() );
}
// This could be replaced with a check for shouldExpandMacro -- but it is called by
// the scanner before this point
// else if( context.getKind() == IScannerContext.ContextKind.MACROEXPANSION )
// {
// if( !defines.add( context.getFilename() ) )
// throw new ContextException( IProblem.PREPROCESSOR_INVALID_MACRO_DEFN );
// }
addInclusionFilename( context.getContextName() );
lastFileContext++;
cs_push(context);
}
public boolean rollbackContext(ISourceElementRequestor requestor) {
IScannerContext context = getCurrentContext();
try {
context.getReader().close();
} catch (IOException ie) {
TraceUtil.outputTrace( log, "ContextStack : Error closing reader "); //$NON-NLS-1$
}
context.close();
if( context.getKind() == IScannerContext.ContextKind.INCLUSION )
{
TraceUtil.outputTrace(log, "Scanner::ContextStack: ending inclusion ", null, context.getFilename(), null, null); //$NON-NLS-1$
context.getExtension().exitScope( requestor );
TraceUtil.outputTrace(log, "Scanner::ContextStack: ending inclusion ", null, context.getContextName(), null, null); //$NON-NLS-1$
((ScannerContextInclusion)context).getExtension().exitScope( requestor );
lastFileContext--;
}
cs_pop();
return cs_pos != 0;
}
public void undoRollback( IScannerContext undoTo, ISourceElementRequestor requestor ) {
IScannerContext context;
while (getCurrentContext() != undoTo ) {
//cs_pos++;
scanner.setScannerContext(cs[cs_pos++]);
context = cs[cs_pos++];
if(context.getKind() == IScannerContext.ContextKind.INCLUSION)
lastFileContext++;
scanner.setScannerContext(context);
}
}
@ -213,7 +184,7 @@ public class ContextStack {
{
for(int i = cs_pos-1; i >= 0; i--)
if (cs[i].getKind() == IScannerContext.ContextKind.MACROEXPANSION
&& cs[i].getFilename().equals(symbol))
&& cs[i].getContextName().equals(symbol))
return false;
return true;
}
@ -222,29 +193,24 @@ public class ContextStack {
{
for(int i = cs_pos-1; i >= 0; i--)
if (cs[i].getKind() == IScannerContext.ContextKind.INCLUSION &&
cs[i].getFilename().equals(symbol))
cs[i].getContextName().equals(symbol))
return true;
return false;
}
public final IScannerContext getCurrentContext(){
//return (cs_pos == 0) ? sentinel : cs[cs_pos -1];
return cs[cs_pos -1];
}
public IScannerContext getMostRelevantFileContext()
public ScannerContextInclusion getMostRelevantFileContext()
{
IScannerContext context = sentinel;
for( int i = cs_pos - 1; i >= 0; --i )
{
context = cs[i];
if( context.getKind() == IScannerContext.ContextKind.INCLUSION
|| context.getKind() == IScannerContext.ContextKind.TOP )
break;
}
return context;
return (ScannerContextInclusion)cs[lastFileContext];
}
public int getMostRelevantFileContextIndex()
{
return getMostRelevantFileContext().getFilenameIndex();
}
public int getCurrentLineNumber()
{
return getMostRelevantFileContext().getLine();

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* Copyright (c) 2002,2004 IBM Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -168,8 +168,8 @@ public class GCCScannerExtension implements IScannerExtension {
if( context == null || context.getKind() != IScannerContext.ContextKind.INCLUSION )
return;
String fullInclusionPath = context.getFilename();
IASTInclusion inclusion = context.getExtension();
String fullInclusionPath = context.getContextName();
IASTInclusion inclusion = ((ScannerContextInclusion)context).getExtension();
Iterator iter = scannerData.getIncludePathNames().iterator();
@ -199,7 +199,7 @@ public class GCCScannerExtension implements IScannerExtension {
{
try
{
scannerData.getContextStack().updateContext(duple.getUnderlyingReader(), duple.getFilename(), ScannerContext.ContextKind.INCLUSION, inclusion, scannerData.getClientRequestor() );
scannerData.getContextStack().updateInclusionContext(duple.getUnderlyingReader(), duple.getFilename(), inclusion, scannerData.getClientRequestor() );
TraceUtil.outputTrace( scannerData.getLogService(), "GCCScannerExtension handling #include_next directive successfully pushed on new include file" ); //$NON-NLS-1$
}
catch (ContextException e1)

View file

@ -1,15 +1,22 @@
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException;
import java.io.Reader;
/*******************************************************************************
* Copyright (c) 2003, 2004 IBM - Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
/**
* @author jcamelon
*
*/
public interface IScannerContext {
public static class ContextKind
{
public static int SENTINEL = 0;
@ -17,58 +24,13 @@ public interface IScannerContext {
public static int INCLUSION = 2;
public static int MACROEXPANSION = 3;
}
/**
* This initializer is used for scanner contexts which are macro expansions.
*
* @param macroOffset Offset of the expanding macro
* @param macroLength Length of the macro identifier
* @return
*/
public int read() throws IOException;
public String getFilename();
/**
* Returns macro offset (the offset of the top expanded macro).
* @return int
*/
public int getMacroOffset();
/**
* Returns macro length (the length of the top expanded macro identifier).
* @return int
*/
public int getMacroLength();
/**
* Returns the offset.
* @return int
*/
public int getOffset();
/**
* Returns relative offset (relative to the beginning of the ScannerContext).
* @return int
*/
public int getRelativeOffset();
public Reader getReader();
public int undoStackSize();
public int popUndo();
public void pushUndo(int undo);
public int getKind();
public void setKind( int kind );
public IASTInclusion getExtension();
public void setExtension( IASTInclusion ext );
public int getFilenameIndex();
/**
* @return
*/
public int getLine();
public int getChar();
public void ungetChar(int undo);
public String getContextName();
public int getOffset();
public void close();
}

View file

@ -1,23 +1,23 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
/*******************************************************************************
* Copyright (c) 2002, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException;
import java.io.Reader;
/**
* @author jcamelon
*/
public class LimitedScannerContext
extends ScannerContext
extends ScannerContextInclusion
implements IScannerContext {
private final int limit;
@ -30,8 +30,8 @@ public class LimitedScannerContext
* @param object
* @param offsetLimit
*/
public LimitedScannerContext(Scanner scanner, Reader reader, String string, int kind, int offsetLimit, int index ) {
super( reader, string, kind, null, index );
public LimitedScannerContext(Scanner scanner, Reader reader, String string, int offsetLimit, int index ) {
super( reader, string, null, index );
this.scanner = scanner;
limit = offsetLimit;
}
@ -41,13 +41,16 @@ public class LimitedScannerContext
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#read()
*/
public int read() throws IOException {
public int getChar() {
if( getOffset() == limit )
{
scanner.setOffsetLimitReached(true);
throw new IOException();
return -1;
}
return super.read();
return super.getChar();
}
public int getKind() {
return ScannerContextInclusion.ContextKind.TOP;
}
}

View file

@ -1,17 +1,17 @@
/*******************************************************************************
* Copyright (c) 2001 Rational Software Corp. and others.
* Copyright (c) 2001, 2004 IBM Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* Rational Software - initial implementation
* IBM - Rational Software
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
@ -202,7 +202,7 @@ public class Scanner implements IScanner {
addDefinition( __FILE__,
new DynamicMacroDescriptor( __FILE__, new DynamicMacroEvaluator() {
public String execute() {
return scannerData.getContextStack().getMostRelevantFileContext().getFilename();
return scannerData.getContextStack().getMostRelevantFileContext().getContextName();
}
} ) );
@ -286,10 +286,10 @@ public class Scanner implements IScanner {
try
{
if( offsetLimit == NO_OFFSET_LIMIT )
context = new ScannerContext(scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, null, 0 );
context = new ScannerContextTop(scannerData.getInitialReader(), resolvedFilename);
else
context = new LimitedScannerContext( this, scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, offsetLimit, 0 );
scannerData.getContextStack().push( context, scannerData.getClientRequestor() );
context = new LimitedScannerContext( this, scannerData.getInitialReader(), resolvedFilename, offsetLimit, 0 );
scannerData.getContextStack().pushInitialContext( context );
} catch( ContextException ce )
{
handleInternalError();
@ -534,7 +534,7 @@ public class Scanner implements IScanner {
}
else // local inclusion
{
duple = ScannerUtility.createReaderDuple( new File( currentContext.getFilename() ).getParentFile().getAbsolutePath(), fileName, scannerData.getClientRequestor(), scannerData.getWorkingCopies() );
duple = ScannerUtility.createReaderDuple( new File( currentContext.getContextName() ).getParentFile().getAbsolutePath(), fileName, scannerData.getClientRequestor(), scannerData.getWorkingCopies() );
if( duple != null )
break totalLoop;
useIncludePaths = true;
@ -563,10 +563,9 @@ public class Scanner implements IScanner {
try
{
scannerData.getContextStack().updateContext(
scannerData.getContextStack().updateInclusionContext(
duple.getUnderlyingReader(),
duple.getFilename(),
ScannerContext.ContextKind.INCLUSION,
duple.getFilename(),
inclusion,
scannerData.getClientRequestor() );
}
@ -715,11 +714,8 @@ public class Scanner implements IScanner {
if (lastContext.getKind() == IScannerContext.ContextKind.SENTINEL)
// past the end of file
return c;
if (lastContext.undoStackSize() != 0 )
c = lastContext.popUndo();
else
c = readFromStream();
c = readFromStream();
if (enableTrigraphReplacement && (!insideString || enableTrigraphReplacementInStrings)) {
// Trigraph processing
@ -730,39 +726,39 @@ public class Scanner implements IScanner {
c = getChar(insideString);
switch (c) {
case '(':
expandDefinition("??(", "[", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??(", "[", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case ')':
expandDefinition("??)", "]", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??)", "]", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '<':
expandDefinition("??<", "{", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??<", "{", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '>':
expandDefinition("??>", "}", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??>", "}", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '=':
expandDefinition("??=", "#", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??=", "#", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '/':
expandDefinition("??/", "\\", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??/", "\\", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '\'':
expandDefinition("??\'", "^", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??\'", "^", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '!':
expandDefinition("??!", "|", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??!", "|", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
case '-':
expandDefinition("??-", "~", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("??-", "~", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(insideString);
break;
default:
@ -788,10 +784,10 @@ public class Scanner implements IScanner {
if (c == '<') {
c = getChar(false);
if (c == '%') {
expandDefinition("<%", "{", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("<%", "{", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false);
} else if (c == ':') {
expandDefinition("<:", "[", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("<:", "[", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false);
} else {
// Not a digraph
@ -801,7 +797,7 @@ public class Scanner implements IScanner {
} else if (c == ':') {
c = getChar(false);
if (c == '>') {
expandDefinition(":>", "]", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition(":>", "]", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false);
} else {
// Not a digraph
@ -811,10 +807,10 @@ public class Scanner implements IScanner {
} else if (c == '%') {
c = getChar(false);
if (c == '>') {
expandDefinition("%>", "}", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("%>", "}", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false);
} else if (c == ':') {
expandDefinition("%:", "#", lastContext.getOffset() - lastContext.undoStackSize() - 1); //$NON-NLS-1$ //$NON-NLS-2$
expandDefinition("%:", "#", lastContext.getOffset() - 1); //$NON-NLS-1$ //$NON-NLS-2$
c = getChar(false);
} else {
// Not a digraph
@ -830,13 +826,7 @@ public class Scanner implements IScanner {
protected int readFromStream()
{
int c;
try {
c = currentContext.read();
}
catch (IOException e) {
c = NOCHAR;
}
int c = currentContext.getChar();
if (c != NOCHAR)
return c;
@ -844,16 +834,13 @@ public class Scanner implements IScanner {
if (scannerData.getContextStack().rollbackContext(scannerData.getClientRequestor()) == false)
return NOCHAR;
if (currentContext.undoStackSize() != 0 )
return currentContext.popUndo();
return readFromStream();
}
final void ungetChar(int c) throws ScannerException{
currentContext.pushUndo(c);
scannerData.getContextStack().undoRollback( lastContext, scannerData.getClientRequestor() );
final void ungetChar(int c) {
currentContext.ungetChar(c);
if( lastContext != currentContext)
scannerData.getContextStack().undoRollback( lastContext, scannerData.getClientRequestor() );
}
protected boolean lookAheadForTokenPasting() throws ScannerException
@ -905,16 +892,14 @@ public class Scanner implements IScanner {
storageBuffer.append( buff.toString() );
try
{
scannerData.getContextStack().updateContext(
new StringReader( storageBuffer.toString()),
PASTING,
IScannerContext.ContextKind.MACROEXPANSION,
null,
scannerData.getClientRequestor() );
scannerData.getContextStack().updateMacroContext(
storageBuffer.toString(),
PASTING,
scannerData.getClientRequestor(), -1, -1 );
}
catch (ContextException e)
{
handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
handleProblem( e.getId(), currentContext.getContextName(), getCurrentOffset(), false, true );
}
storageBuffer = null;
return true;
@ -1482,7 +1467,7 @@ public class Scanner implements IScanner {
protected IToken processKeywordOrIdentifier(StringBuffer buff, boolean pasting) throws ScannerException, EndOfFileException
{
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
int baseOffset = lastContext.getOffset() - 1;
// String buffer is slow, we need a better way such as memory mapped files
int c = getChar();
@ -1917,6 +1902,68 @@ public class Scanner implements IScanner {
continue;
}
return token;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
// 'L' is handled elsewhere
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':
StringBuffer sBuffer = new StringBuffer( );
sBuffer.append( (char) c );
token = processKeywordOrIdentifier(sBuffer, pasting);
if (token == null)
{
c = getChar();
continue;
}
return token;
case '"' :
token = processStringLiteral(false);
if (token == null)
@ -2030,9 +2077,9 @@ public class Scanner implements IScanner {
int completionPoint = expression.length() + 2;
IASTCompletionNode.CompletionKind kind = IASTCompletionNode.CompletionKind.MACRO_REFERENCE;
String prefix = ""; //$NON-NLS-1$
String prefix = EMPTY_STRING;
if( ! expression.trim().equals("")) //$NON-NLS-1$
if( ! expression.trim().equals(EMPTY_STRING))
{
IScanner subScanner = new Scanner(
new StringReader(expression),
@ -2149,7 +2196,7 @@ public class Scanner implements IScanner {
protected String getCurrentFile()
{
return scannerData.getContextStack().getMostRelevantFileContext() != null ? scannerData.getContextStack().getMostRelevantFileContext().getFilename() : ""; //$NON-NLS-1$
return scannerData.getContextStack().getMostRelevantFileContext() != null ? scannerData.getContextStack().getMostRelevantFileContext().getContextName() : ""; //$NON-NLS-1$
}
@ -2530,7 +2577,7 @@ public class Scanner implements IScanner {
protected void poundInclude( int beginningOffset, int startLine ) throws ScannerException, EndOfFileException {
skipOverWhitespace();
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize();
int baseOffset = lastContext.getOffset() ;
int nameLine = scannerData.getContextStack().getCurrentLineNumber();
String includeLine = getRestOfPreprocessorLine();
if( isLimitReached() )
@ -2693,7 +2740,7 @@ public class Scanner implements IScanner {
protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException {
// definition
String key = getNextIdentifier();
int offset = currentContext.getOffset() - key.length() - currentContext.undoStackSize();
int offset = currentContext.getOffset() - key.length();
int nameLine = scannerData.getContextStack().getCurrentLineNumber();
// store the previous definition to check against later
@ -2968,17 +3015,16 @@ public class Scanner implements IScanner {
String replacementValue = expansion.getExpansionSignature();
try
{
scannerData.getContextStack().updateContext(
new StringReader(replacementValue),
symbol, ScannerContext.ContextKind.MACROEXPANSION,
null,
scannerData.getContextStack().updateMacroContext(
replacementValue,
symbol,
scannerData.getClientRequestor(),
symbolOffset,
symbol.length());
}
catch (ContextException e)
{
handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
handleProblem( e.getId(), currentContext.getContextName(), getCurrentOffset(), false, true );
consumeUntilOutOfMacroExpansion();
return;
}
@ -3004,7 +3050,7 @@ public class Scanner implements IScanner {
}
// Position of the closing ')'
int endMacroOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
int endMacroOffset = lastContext.getOffset() - 1;
String betweenTheBrackets = buffer.toString().trim();
@ -3119,18 +3165,16 @@ public class Scanner implements IScanner {
String finalString = buffer.toString();
try
{
scannerData.getContextStack().updateContext(
new StringReader(finalString),
expansion.getName(),
ScannerContext.ContextKind.MACROEXPANSION,
null,
scannerData.getContextStack().updateMacroContext(
finalString,
expansion.getName(),
scannerData.getClientRequestor(),
symbolOffset,
endMacroOffset - symbolOffset + 1 );
}
catch (ContextException e)
{
handleProblem( e.getId(), currentContext.getFilename(), getCurrentOffset(), false, true );
handleProblem( e.getId(), currentContext.getContextName(), getCurrentOffset(), false, true );
consumeUntilOutOfMacroExpansion();
return;
}
@ -3247,10 +3291,8 @@ public class Scanner implements IScanner {
* @see org.eclipse.cdt.core.parser.IFilenameProvider#getCurrentFileIndex()
*/
public int getCurrentFileIndex() {
IScannerContext mostRelevantFileContext = scannerData.getContextStack().getMostRelevantFileContext();
return (( mostRelevantFileContext == null ) ? -1 : mostRelevantFileContext.getFilenameIndex() );
}
return scannerData.getContextStack().getMostRelevantFileContextIndex();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IFilenameProvider#getFilenameForIndex(int)
*/

View file

@ -1,203 +0,0 @@
/*******************************************************************************
* Copyright (c) 2001 Rational Software Corp. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException;
import java.io.Reader;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
public class ScannerContext implements IScannerContext
{
private Reader reader;
private String filename;
private int macroOffset = -1;
private int macroLength = -1;
private int line = 1;
private int offset;
private int kind;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int)
*/
public ScannerContext(Reader r, String f, int k, IASTInclusion i, int mO, int mL, int l, int index)
{
reader = r;
filename = f;
offset = 0;
kind = k;
inc = i;
macroOffset = mO;
macroLength = mL;
line = l;
this.index = index;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion)
*/
public ScannerContext(Reader r, String f, int k, IASTInclusion i, int index)
{
this(r, f, k, i, -1, -1, 1, index);
}
public int read() throws IOException {
++offset;
int c = reader.read();
if ((char)c == '\n') line++;
return c;
}
/**
* Returns the filename.
* @return String
*/
public final String getFilename()
{
return filename;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getExtension()
*/
public final int getMacroOffset()
{
return macroOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getMacroLength()
*/
public final int getMacroLength()
{
return macroLength;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getOffset()
*/
public final int getOffset()
{
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
return (macroOffset < 0) ? offset : macroOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getRelativeOffset()
*/
public final int getRelativeOffset()
{
return offset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getLine()
*/
public final int getLine()
{
return line;
}
/* there are never more than 2 elements in the unget stack!
* trigraphs may involve 2, but in general there is a single element
* I have made room for 10 -- just in case :-)
*/
private int pos = 0;
private int undo[] = new int[10];
public final int undoStackSize()
{
return pos;
}
/**
* Returns the undo.
* @return int
*/
public final int popUndo()
{
int c = undo[--pos];
if ((char)c == '\n') line++;
return c;
}
/**
* Sets the undo.
* @param undo The undo to set
*/
public final void pushUndo(int c)
{
if ((char)c == '\n') line--;
undo[pos++] = c;
}
/**
* Returns the reader.
* @return Reader
*/
public final Reader getReader()
{
return reader;
}
/**
* Returns the kind.
* @return int
*/
public int getKind() {
return kind;
}
/**
* Sets the kind.
* @param kind The kind to set
*/
public void setKind(int kind) {
this.kind = kind;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getExtension()
*/
public IASTInclusion getExtension() {
return inc;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#setExtension(org.eclipse.cdt.core.parser.ast.IASTInclusion)
*/
public void setExtension(IASTInclusion ext) {
inc = ext;
}
private IASTInclusion inc = null;
private final int index;
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append( "file "); //$NON-NLS-1$
buffer.append( getFilename() );
buffer.append( ":"); //$NON-NLS-1$
buffer.append( getLine() );
return buffer.toString();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerContext#getFilenameIndex()
*/
public int getFilenameIndex() {
return index;
}
}

View file

@ -0,0 +1,114 @@
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM - Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.IOException;
import java.io.Reader;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
public class ScannerContextInclusion implements IScannerContext
{
protected Reader reader;
private String filename;
private IASTInclusion inc;
private final int index;
private int line;
protected int offset = 0;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion)
*/
public ScannerContextInclusion(Reader r, String f, IASTInclusion i, int index) {
reader = r;
filename = f;
line = 1;
inc = i;
this.index = index;
}
public final String getContextName()
{
return filename;
}
public int getOffset()
{
return offset - pos;
}
public void close() {
try {
reader.close();
}
catch (IOException ie) {
}
}
protected int pos = 0;
protected int undo[] = new int[2];
public final void ungetChar(int c) {
undo[pos++] = c;
}
public int getChar() {
if (pos > 0)
return undo[--pos];
try {
++offset;
int c = reader.read();
if ((char)c == '\n') line++;
return c;
}
catch (IOException e) {
return -1;
}
}
/**
* Returns the kind.
* @return int
*/
public int getKind() {
return ScannerContextInclusion.ContextKind.INCLUSION;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getExtension()
*/
public IASTInclusion getExtension() {
return inc;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerContext#getFilenameIndex()
*/
public int getFilenameIndex() {
return index;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getLine()
*/
public final int getLine()
{
return line;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append( "file "); //$NON-NLS-1$
buffer.append( getContextName() );
buffer.append( ":"); //$NON-NLS-1$
buffer.append( getLine() );
return buffer.toString();
}
}

View file

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM - Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
public class ScannerContextMacro implements IScannerContext
{
private int macroOffset;
private int macroLength;
int position=0;
int length;
char [] reader;
String macroName;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int)
*/
public ScannerContextMacro(String in, String macro, int mO, int mL)
{
macroName = macro;
reader = in.toCharArray();
length = in.length();
macroOffset = mO;
macroLength = mL;
}
public final String getContextName() {
return macroName;
}
public int getChar() {
if (position < length)
return reader[position++];
return -1;
}
public void close() {
}
public final void ungetChar(int c)
{
position--;
// may want to assert that reader.charAt(position) == c
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getMacroLength()
*/
public final int getMacroLength()
{
return macroLength;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getOffset()
*/
public int getOffset()
{
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
return macroOffset;
}
/**
* Returns the kind.
* @return int
*/
public int getKind() {
return IScannerContext.ContextKind.MACROEXPANSION;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append( "Macro "); //$NON-NLS-1$
buffer.append( getContextName() );
return buffer.toString();
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM - Rational Software and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.Reader;
public class ScannerContextTop extends ScannerContextInclusion
{
ScannerContextTop(Reader r, String f) {
super(r,f,null, 0);
}
public int getKind() {
return ScannerContextInclusion.ContextKind.TOP;
}
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.parser.token;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.parser.scanner.ContextStack;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerContext;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContextMacro;
/**
* @author johnc
@ -34,8 +35,9 @@ public class ImagedExpansionToken extends ImagedToken implements IToken {
* @see org.eclipse.cdt.internal.core.parser.token.SimpleToken#setOffsetAndLength(org.eclipse.cdt.internal.core.parser.scanner.IScannerContext)
*/
protected void setOffsetAndLength(IScannerContext context) {
offset = context.getMacroOffset();
length = context.getMacroLength();
ScannerContextMacro m = (ScannerContextMacro) context;
offset = m.getOffset();
length = m.getMacroLength();
}
/* (non-Javadoc)

View file

@ -55,7 +55,7 @@ public class ImagedToken extends SimpleToken {
*/
protected void setOffsetAndLength(IScannerContext context) {
if( getImage() == null ) return;
offset = context.getOffset() - getImage().length() - context.undoStackSize();
offset = context.getOffset() - getImage().length();
if( getType() == tSTRING || getType() == tCHAR )
offset--;
else if( getType() == tLSTRING || getType() == tLCHAR )

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.parser.token;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.parser.scanner.ContextStack;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerContext;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContextMacro;
/**
* @author johnc
@ -34,8 +35,9 @@ public class SimpleExpansionToken extends SimpleToken implements IToken {
* @see org.eclipse.cdt.internal.core.parser.token.SimpleToken#setOffsetAndLength(org.eclipse.cdt.internal.core.parser.scanner.IScannerContext)
*/
protected void setOffsetAndLength(IScannerContext context) {
offset = context.getMacroOffset();
length = context.getMacroLength();
ScannerContextMacro m = (ScannerContextMacro) context;
offset = m.getOffset();
length = m.getMacroLength();
}

View file

@ -44,7 +44,7 @@ public class SimpleToken extends AbstractToken implements IToken {
* @param context
*/
protected void setOffsetAndLength(IScannerContext context) {
offset = context.getOffset() - getLength() - context.undoStackSize();
offset = context.getOffset() - getLength();
}
public String getImage() {

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.token;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerContext;
import org.eclipse.cdt.internal.core.parser.scanner.IScannerData;
/**
@ -22,7 +23,7 @@ public class TokenFactory {
{
if( value.length() > 15 )
return createUniquelyImagedToken( IToken.tINTEGER, value, scannerData );
if( scannerData.getContextStack().getCurrentContext().getMacroOffset() >= 0 )
if( scannerData.getContextStack().getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION )
return new IntegerExpansionToken( IToken.tINTEGER, Integer.parseInt(value ), scannerData.getContextStack() );
return new IntegerToken( IToken.tINTEGER, Integer.parseInt( value ), scannerData.getContextStack() );
@ -33,7 +34,7 @@ public class TokenFactory {
if( value.length() > 15 )
return createUniquelyImagedToken( IToken.tHEXINT, value, scannerData );
if( scannerData.getContextStack().getCurrentContext().getMacroOffset() >= 0 )
if( scannerData.getContextStack().getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION )
return new HexIntegerExpansionToken( IToken.tHEXINT, value, scannerData.getContextStack() );
return new HexIntegerToken( IToken.tHEXINT, value, scannerData.getContextStack() );
@ -43,7 +44,7 @@ public class TokenFactory {
public static IToken createToken( int tokenType, IScannerData scannerData )
{
if( scannerData.getContextStack().getCurrentContext().getMacroOffset() >= 0 )
if( scannerData.getContextStack().getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION )
return new SimpleExpansionToken( tokenType, scannerData.getContextStack() );
return new SimpleToken( tokenType, scannerData.getContextStack() );
@ -56,7 +57,7 @@ public class TokenFactory {
* @return
*/
public static IToken createUniquelyImagedToken(int type, String image, IScannerData scannerData) {
if( scannerData.getContextStack().getCurrentContext().getMacroOffset() >= 0 )
if( scannerData.getContextStack().getCurrentContext().getKind() == IScannerContext.ContextKind.MACROEXPANSION )
return new ImagedExpansionToken( type, scannerData.getContextStack(), image );
return new ImagedToken(type, scannerData.getContextStack(), image );