Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Kucera2008-01-31 16:50:44 +0000
committerMike Kucera2008-01-31 16:50:44 +0000
commit20a43f994bb740e2d78317de373a483bb19c1909 (patch)
tree2879d109d69a00601a8e48be0f144ac87f4e0702 /core/org.eclipse.cdt.core/parser
parentbb44d4020d5db4b6fcfb946dd160f60b15971dfa (diff)
downloadorg.eclipse.cdt-20a43f994bb740e2d78317de373a483bb19c1909.tar.gz
org.eclipse.cdt-20a43f994bb740e2d78317de373a483bb19c1909.tar.xz
org.eclipse.cdt-20a43f994bb740e2d78317de373a483bb19c1909.zip
cleaned up and commented the code in AbstractGNUSourceCodeParser.parseDeclarationOrExpressionStatement()
Diffstat (limited to 'core/org.eclipse.cdt.core/parser')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java97
1 files changed, 52 insertions, 45 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 249611a7eda..c15335c8b8e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -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,13 +1600,31 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
+ // create and return ambiguity node
IASTAmbiguousStatement statement = createAmbiguousStatement();
statement.addStatement(ds);
statement.addStatement(expressionStatement);
((ASTNode) statement).setOffsetAndLength((ASTNode) ds);
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();
/**

Back to the top