1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 11:25:35 +02:00

Patch for John Camelon:

- added quickParse heuristic to Scanner for handling #if conditionals to
avoid throwing ScannerExceptions on undefined preprocessor symbols
- added minimal enum support to Parser (though not to DOM or CModel)
This commit is contained in:
Doug Schaefer 2003-03-07 13:41:26 +00:00
parent a4732cccb3
commit 640ec6e2e6
4 changed files with 134 additions and 43 deletions

View file

@ -10,6 +10,7 @@
******************************************************************************/ ******************************************************************************/
package org.eclipse.cdt.internal.core.parser; package org.eclipse.cdt.internal.core.parser;
import java.util.EmptyStackException;
import java.util.Stack; import java.util.Stack;
public class ExpressionEvaluator extends NullParserCallback { public class ExpressionEvaluator extends NullParserCallback {
@ -104,7 +105,7 @@ public class ExpressionEvaluator extends NullParserCallback {
} }
} }
public Object getResult() { public Object getResult() throws EmptyStackException {
return stack.peek(); return stack.peek();
} }

View file

@ -341,7 +341,7 @@ c, quick);
classSpecifier(decl); classSpecifier(decl);
return; return;
case Token.t_enum: case Token.t_enum:
// enumSpecifier(); enumSpecifier(decl);
break; break;
default: default:
break declSpecifiers; break declSpecifiers;
@ -465,9 +465,6 @@ c, quick);
} }
} }
} }
else
{
}
} }
callback.declaratorEnd( declarator ); callback.declaratorEnd( declarator );
@ -590,6 +587,46 @@ c, quick);
throw backtrack; throw backtrack;
} }
/**
* enumSpecifier
* "enum" (name)? "{" (enumerator-list) "}"
*/
public void enumSpecifier( Object owner ) throws Exception
{
if( LT(1) != Token.t_enum )
throw backtrack;
consume();
// insert beginEnum callback here
if( LT(1) == Token.tIDENTIFIER )
consume();
if( LT(1) == Token.tLBRACE )
{
consume();
// for the time being to get the CModel working ignore the enumerator list
int depth = 1;
while (depth > 0) {
switch (consume().getType()) {
case Token.tRBRACE:
--depth;
break;
case Token.tLBRACE:
++depth;
break;
case Token.tEOF:
// Oops, no match
throw backtrack;
}
}
}
// insert endEnum callback here
}
/** /**
* classSpecifier * classSpecifier
* : classKey name (baseClause)? "{" (memberSpecification)* "}" * : classKey name (baseClause)? "{" (memberSpecification)* "}"
@ -1232,7 +1269,8 @@ c, quick);
} }
public void primaryExpression() throws Exception { public void primaryExpression() throws Exception {
switch (LT(1)) { int type = LT(1);
switch (type) {
// TO DO: we need more literals... // TO DO: we need more literals...
case Token.tINTEGER: case Token.tINTEGER:
callback.expressionTerminal(consume()); callback.expressionTerminal(consume());
@ -1240,6 +1278,9 @@ c, quick);
case Token.tSTRING: case Token.tSTRING:
callback.expressionTerminal(consume()); callback.expressionTerminal(consume());
return; return;
case Token.tIDENTIFIER:
callback.expressionTerminal(consume());
return;
case Token.t_this: case Token.t_this:
consume(); consume();
return; return;

View file

@ -526,14 +526,14 @@ public class Scanner implements IScanner {
case PreprocessorDirectives.IF : case PreprocessorDirectives.IF :
// get the rest of the line // get the rest of the line
String expression = getRestOfPreprocessorLine(); String expression = getRestOfPreprocessorLine();
boolean expressionEvalResult =
evaluateExpression(expression);
boolean expressionEvalResult = evaluateExpression(expression);
passOnToClient = branches.poundif( expressionEvalResult ); passOnToClient = branches.poundif( expressionEvalResult );
c = getChar(); c = getChar();
continue; continue;
case PreprocessorDirectives.IFDEF : case PreprocessorDirectives.IFDEF :
skipOverWhitespace(); skipOverWhitespace();
String definition = getNextIdentifier(); String definition = getNextIdentifier();
@ -588,7 +588,7 @@ public class Scanner implements IScanner {
throw new ScannerException("Malformed #elsif clause"); throw new ScannerException("Malformed #elsif clause");
boolean elsifResult = boolean elsifResult =
evaluateExpression(elsifExpression); evaluateExpression(elsifExpression );
passOnToClient = branches.poundelif( elsifResult ); passOnToClient = branches.poundelif( elsifResult );
c = getChar(); c = getChar();
@ -1089,42 +1089,59 @@ public class Scanner implements IScanner {
return branches.getDepth(); return branches.getDepth();
} }
protected boolean evaluateExpression(String expression) protected boolean evaluateExpression(String expression )
throws ScannerException { throws ScannerException {
Object expressionEvalResult = null;
try { if( quickScan )
ExpressionEvaluator evaluator = new ExpressionEvaluator(); {
Scanner trial = if( expression.trim().equals( "0" ) )
new Scanner( return false;
new StringReader(expression), return true;
EXPRESSION,
definitions);
Parser parser = new Parser(trial, evaluator);
parser.expression();
expressionEvalResult = evaluator.getResult();
} catch (Exception e) {
System.out.println("Exception from Parser : " + e.toString());
} }
else
if (expressionEvalResult == null) {
throw new ScannerException( Object expressionEvalResult = null;
"Expression " try {
+ expression ExpressionEvaluator evaluator = new ExpressionEvaluator();
+ " evaluates to an undefined value"); Scanner trial =
new Scanner(
if (expressionEvalResult.getClass() == java.lang.Integer.class) { new StringReader(expression),
int i = ((Integer) expressionEvalResult).intValue(); EXPRESSION,
if (i == 0) { definitions);
return false; Parser parser = new Parser(trial, evaluator);
parser.expression();
expressionEvalResult = evaluator.getResult();
} catch (Exception e ) {
throw new ScannerException(
"Expression "
+ expression
+ " evaluates to an undefined value");
} finally
{
if (expressionEvalResult == null)
throw new ScannerException(
"Expression "
+ expression
+ " evaluates to an undefined value");
}
if (expressionEvalResult.getClass() == java.lang.Integer.class) {
int i = ((Integer) expressionEvalResult).intValue();
if (i == 0) {
return false;
}
return true;
} else if (
expressionEvalResult.getClass() == java.lang.Boolean.class) {
return ((Boolean) expressionEvalResult).booleanValue();
} else {
throw new ScannerException(
"Unexpected expression type - we do not expect "
+ expressionEvalResult.getClass().getName());
} }
return true;
} else if (
expressionEvalResult.getClass() == java.lang.Boolean.class) {
return ((Boolean) expressionEvalResult).booleanValue();
} else {
throw new ScannerException(
"Unexpected expression type - we do not expect "
+ expressionEvalResult.getClass().getName());
} }
} }

View file

@ -811,6 +811,38 @@ public class ScannerTestCase extends TestCase
} }
} }
public void testQuickScan()
{
try
{
initializeScanner( "#if X + 5 < 7\n int found = 1;\n#endif" );
scanner.setQuickScan( true );
validateToken( Token.t_int );
validateIdentifier( "found" );
validateToken( Token.tASSIGN );
validateInteger( "1");
validateToken( Token.tSEMI );
validateEOF();
}
catch( ScannerException se )
{
fail( EXCEPTION_THROWN + se.getMessage() );
}
try
{
initializeScanner( "#if 0\n int error = 666;\n#endif" );
scanner.setQuickScan( true );
validateEOF();
}
catch( ScannerException se )
{
fail( EXCEPTION_THROWN + se.getMessage() );
}
}
public void testInclusions() public void testInclusions()
{ {
try try