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

cleaned up and commented the code in AbstractGNUSourceCodeParser.parseDeclarationOrExpressionStatement()

This commit is contained in:
Mike Kucera 2008-01-31 16:50:44 +00:00
parent bb44d4020d
commit 20a43f994b

View file

@ -1474,16 +1474,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTCastExpression createCastExpression();
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
* There are many ambiguities in C and C++ between expressions and declarations.
* This method will attempt to parse a statement as both an expression and a declaration,
* if both parses succeed then an ambiguity node is returned.
*/
protected IASTStatement parseDeclarationOrExpressionStatement()
throws EndOfFileException, BacktrackException {
// expressionStatement
// Note: the function style cast ambiguity is handled in
// expression
protected IASTStatement parseDeclarationOrExpressionStatement() throws EndOfFileException, BacktrackException {
// First attempt to parse an expressionStatement
// Note: the function style cast ambiguity is handled in expression
// Since it only happens when we are in a statement
IToken mark = mark();
IASTExpressionStatement expressionStatement = null;
@ -1497,14 +1496,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
lastTokenOfExpression = consume(IToken.tSEMI);
expressionStatement = createExpressionStatement();
expressionStatement.setExpression(expression);
((ASTNode) expressionStatement).setOffsetAndLength(
mark.getOffset(), lastTokenOfExpression.getEndOffset() - mark.getOffset());
((ASTNode) expressionStatement).setOffsetAndLength(mark.getOffset(), lastTokenOfExpression.getEndOffset() - mark.getOffset());
} catch (BacktrackException b) {
}
backup(mark);
// declarationStatement
// Now attempt to parse a declarationStatement
IASTDeclarationStatement ds = null;
try {
IASTDeclaration d = declaration();
@ -1516,6 +1514,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
backup(mark);
}
// if not ambiguous then return the appropriate node
if (expressionStatement == null && ds != null) {
return ds;
}
@ -1526,35 +1525,33 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
return expressionStatement;
}
if (expressionStatement == null && ds == null)
throwBacktrack(savedBt);
// resolve ambiguities
// At this point we know we have an ambiguity.
// Attempt to resolve some ambiguities that are easy to detect.
// A * B = C;
// foo() = x;
// These can get parsed as expressions but the lvalue doesn't make sense
if (expressionStatement.getExpression() instanceof IASTBinaryExpression) {
IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement.getExpression();
if (exp.getOperator() == IASTBinaryExpression.op_assign) {
IASTExpression lhs = exp.getOperand1();
if (lhs instanceof IASTBinaryExpression
&& ((IASTBinaryExpression) lhs).getOperator() == IASTBinaryExpression.op_multiply) {
return ds;
}
if (lhs instanceof IASTFunctionCallExpression) {
// lvalue - makes no sense
return ds;
}
}
}
// x = y; // default to int
// valid @ Translation Unit scope
// but not valid as a statement in a function body
if (ds.getDeclaration() instanceof IASTSimpleDeclaration
&& ((IASTSimpleDeclaration) ds.getDeclaration())
.getDeclSpecifier() instanceof IASTSimpleDeclSpecifier
&& ((IASTSimpleDeclSpecifier) ((IASTSimpleDeclaration) ds
.getDeclaration()).getDeclSpecifier()).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
// x = y; // implicit int
// valid at Translation Unit scope but not valid as a statement in a function body
if(isImplicitInt(ds.getDeclaration())) {
backup(mark);
while (true) {
if (consume() == lastTokenOfExpression)
@ -1564,39 +1561,31 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return expressionStatement;
}
if (ds.getDeclaration() instanceof IASTAmbiguousDeclaration )
{
// generalization of the previous check for implicit int
if (ds.getDeclaration() instanceof IASTAmbiguousDeclaration ) {
IASTAmbiguousDeclaration amb = (IASTAmbiguousDeclaration) ds.getDeclaration();
IASTDeclaration [] ambDs = amb.getDeclarations();
int ambCount = 0;
for( int i = 0; i < ambDs.length; ++i )
{
if (ambDs[i] instanceof IASTSimpleDeclaration
&& ((IASTSimpleDeclaration) ambDs[i])
.getDeclSpecifier() instanceof IASTSimpleDeclSpecifier
&& ((IASTSimpleDeclSpecifier) ((IASTSimpleDeclaration) ambDs[i]).getDeclSpecifier()).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
++ambCount;
}
boolean allImplicitInt = true;
for(IASTDeclaration ambD : amb.getDeclarations()) {
if(!isImplicitInt(ambD)) {
allImplicitInt = false;
break;
}
}
if ( ambCount == ambDs.length )
{
if(allImplicitInt) {
backup(mark);
while (true) {
if (consume() == lastTokenOfExpression)
break;
}
return expressionStatement;
}
}
if (ds.getDeclaration() instanceof IASTSimpleDeclaration
&& ((IASTSimpleDeclaration) ds.getDeclaration())
.getDeclSpecifier() instanceof IASTNamedTypeSpecifier)
{
final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds
.getDeclaration()).getDeclarators();
// x;
// a single identifier can be parsed as a named declaration specifier without a declarator
if(ds.getDeclaration() instanceof IASTSimpleDeclaration &&
((IASTSimpleDeclaration) ds.getDeclaration()).getDeclSpecifier() instanceof IASTNamedTypeSpecifier) {
final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds.getDeclaration()).getDeclarators();
if (declarators.length == 0
|| (declarators.length == 1 && (declarators[0].getName()
.toCharArray().length == 0 && declarators[0]
@ -1611,6 +1600,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
// create and return ambiguity node
IASTAmbiguousStatement statement = createAmbiguousStatement();
statement.addStatement(ds);
statement.addStatement(expressionStatement);
@ -1618,6 +1608,23 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return statement;
}
/**
* Returns true if the given declaration has unspecified type,
* in this case the type defaults to int and is know as "implicit int".
*/
protected static boolean isImplicitInt(IASTDeclaration declaration) {
if(declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if(declSpec instanceof IASTSimpleDeclSpecifier &&
((IASTSimpleDeclSpecifier)declSpec).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
return true;
}
}
return false;
}
protected abstract IASTAmbiguousStatement createAmbiguousStatement();
/**