1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 17:35: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;
import java.util.EmptyStackException;
import java.util.Stack;
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();
}

View file

@ -341,7 +341,7 @@ c, quick);
classSpecifier(decl);
return;
case Token.t_enum:
// enumSpecifier();
enumSpecifier(decl);
break;
default:
break declSpecifiers;
@ -465,9 +465,6 @@ c, quick);
}
}
}
else
{
}
}
callback.declaratorEnd( declarator );
@ -590,6 +587,46 @@ c, quick);
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
* : classKey name (baseClause)? "{" (memberSpecification)* "}"
@ -1232,7 +1269,8 @@ c, quick);
}
public void primaryExpression() throws Exception {
switch (LT(1)) {
int type = LT(1);
switch (type) {
// TO DO: we need more literals...
case Token.tINTEGER:
callback.expressionTerminal(consume());
@ -1240,6 +1278,9 @@ c, quick);
case Token.tSTRING:
callback.expressionTerminal(consume());
return;
case Token.tIDENTIFIER:
callback.expressionTerminal(consume());
return;
case Token.t_this:
consume();
return;

View file

@ -526,14 +526,14 @@ public class Scanner implements IScanner {
case PreprocessorDirectives.IF :
// get the rest of the line
String expression = getRestOfPreprocessorLine();
boolean expressionEvalResult =
evaluateExpression(expression);
boolean expressionEvalResult = evaluateExpression(expression);
passOnToClient = branches.poundif( expressionEvalResult );
c = getChar();
continue;
case PreprocessorDirectives.IFDEF :
skipOverWhitespace();
String definition = getNextIdentifier();
@ -588,7 +588,7 @@ public class Scanner implements IScanner {
throw new ScannerException("Malformed #elsif clause");
boolean elsifResult =
evaluateExpression(elsifExpression);
evaluateExpression(elsifExpression );
passOnToClient = branches.poundelif( elsifResult );
c = getChar();
@ -1089,42 +1089,59 @@ public class Scanner implements IScanner {
return branches.getDepth();
}
protected boolean evaluateExpression(String expression)
protected boolean evaluateExpression(String expression )
throws ScannerException {
Object expressionEvalResult = null;
try {
ExpressionEvaluator evaluator = new ExpressionEvaluator();
Scanner trial =
new Scanner(
new StringReader(expression),
EXPRESSION,
definitions);
Parser parser = new Parser(trial, evaluator);
parser.expression();
expressionEvalResult = evaluator.getResult();
} catch (Exception e) {
System.out.println("Exception from Parser : " + e.toString());
if( quickScan )
{
if( expression.trim().equals( "0" ) )
return false;
return true;
}
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;
else
{
Object expressionEvalResult = null;
try {
ExpressionEvaluator evaluator = new ExpressionEvaluator();
Scanner trial =
new Scanner(
new StringReader(expression),
EXPRESSION,
definitions);
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()
{
try