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

Further restructuring of simple declaration grammar.

This commit is contained in:
John Camelon 2005-05-17 19:44:26 +00:00
parent 693f2a4708
commit c1232687c2
3 changed files with 343 additions and 445 deletions

View file

@ -42,7 +42,7 @@ public class BasicCompletionTest extends CompletionTestBase {
ASTCompletionNode node = getGPPCompletionNode(code.toString());
IASTName[] names = node.getNames();
// There are three names, one as an expression, one that isn't connected, one as a declaration
assertEquals(4, names.length);
assertEquals(3, names.length);
// The expression points to our functions
IBinding[] bindings = names[0].resolvePrefix();
// There should be two since they both start with fu
@ -79,9 +79,9 @@ public class BasicCompletionTest extends CompletionTestBase {
// C++
ASTCompletionNode node = getGPPCompletionNode(code.toString());
IASTName[] names = node.getNames();
assertEquals(3, names.length);
assertEquals(2, names.length);
assertNull(names[0].getTranslationUnit());
IBinding[] bindings = names[2].resolvePrefix();
IBinding[] bindings = names[1].resolvePrefix();
assertEquals(1, bindings.length);
assertEquals("blah", ((ITypedef)bindings[0]).getName());

View file

@ -85,9 +85,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final boolean supportAlignOfUnaries;
protected final boolean supportKnRC;
protected final boolean supportKnRC;
protected final boolean supportGCCOtherBuiltinSymbols;
protected final boolean supportGCCOtherBuiltinSymbols;
protected AbstractGNUSourceCodeParser(IScanner scanner,
IParserLogService logService, ParserMode parserMode,
@ -100,8 +100,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
this.supportStatementsInExpressions = supportStatementsInExpressions;
this.supportTypeOfUnaries = supportTypeOfUnaries;
this.supportAlignOfUnaries = supportAlignOfUnaries;
this.supportKnRC = supportKnRC;
this.supportGCCOtherBuiltinSymbols = supportGCCOtherBuiltinSymbols;
this.supportKnRC = supportKnRC;
this.supportGCCOtherBuiltinSymbols = supportGCCOtherBuiltinSymbols;
}
protected boolean parsePassed = true;
@ -121,19 +121,22 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected ASTCompletionNode completionNode;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser#getCompletionNode()
*/
public ASTCompletionNode getCompletionNode() {
return completionNode;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser#getCompletionNode()
*/
public ASTCompletionNode getCompletionNode() {
return completionNode;
}
// Use to create the completion node
protected ASTCompletionNode createCompletionNode(IToken token) {
if (completionNode == null)
completionNode = new ASTCompletionNode(token, getTranslationUnit());
return completionNode;
}
// Use to create the completion node
protected ASTCompletionNode createCompletionNode(IToken token) {
if (completionNode == null)
completionNode = new ASTCompletionNode(token, getTranslationUnit());
return completionNode;
}
/**
* Look Ahead in the token list to see what is coming.
*
@ -267,7 +270,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*
* @param mark
* The point that we wish to restore to.
*
*/
protected void backup(IToken mark) {
currToken = mark;
@ -297,14 +299,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* request a backtrack
*/
protected IToken identifier() throws EndOfFileException, BacktrackException {
switch (LT(1)) {
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
case IToken.tEOC:
return consume();
default:
throw backtrack;
}
switch (LT(1)) {
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
case IToken.tEOC:
return consume();
default:
throw backtrack;
}
}
@ -411,15 +413,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
resolveAmbiguities();
log.traceLog("Ambiguity resolution : " //$NON-NLS-1$
+ (System.currentTimeMillis() - startTime) + "ms" //$NON-NLS-1$
); //$NON-NLS-1$ //$NON-NLS-2$
); //$NON-NLS-1$ //$NON-NLS-2$
IASTTranslationUnit result = getTranslationUnit();
nullifyTranslationUnit();
return result;
}
protected void resolveAmbiguities()
{
getTranslationUnit().accept( createVisitor() );
protected void resolveAmbiguities() {
getTranslationUnit().accept(createVisitor());
}
protected abstract ASTVisitor createVisitor();
@ -467,7 +468,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
--depth;
break;
case IToken.tEOC:
throw new EndOfFileException();
throw new EndOfFileException();
}
if (depth < 0)
return;
@ -506,8 +507,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTCompoundStatement compoundStatement()
throws EndOfFileException, BacktrackException {
IASTCompoundStatement result = createCompoundStatement();
if (LT(1) == IToken.tEOC)
return result;
if (LT(1) == IToken.tEOC)
return result;
int startingOffset = consume(IToken.tLBRACE).getOffset();
@ -644,8 +645,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpression multiplicativeExpression()
throws BacktrackException, EndOfFileException;
protected abstract IASTTypeId typeId(boolean forNewExpression) throws BacktrackException,
EndOfFileException;
protected abstract IASTTypeId typeId(boolean forNewExpression)
throws BacktrackException, EndOfFileException;
protected abstract IASTExpression castExpression()
throws BacktrackException, EndOfFileException;
@ -1036,7 +1037,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* Parses a function body.
*
* @return TODO
*
* @throws BacktrackException
* request a backtrack
*/
@ -1045,8 +1045,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return compoundStatement();
}
protected abstract IASTDeclarator initDeclarator() throws EndOfFileException,
BacktrackException;
protected abstract IASTDeclarator initDeclarator()
throws EndOfFileException, BacktrackException;
/**
* @param flags
* input flags that are used to make our decision
@ -1055,44 +1056,40 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @throws EndOfFileException
* we could encounter EOF while looking ahead
*/
protected boolean lookAheadForDeclarator(Flags flags)
{
if( flags.typeId ) return false;
protected boolean lookAheadForDeclarator(Flags flags) {
if (flags.typeId)
return false;
IToken mark = null;
try
{
try {
mark = mark();
}
catch( EndOfFileException eof )
{
} catch (EndOfFileException eof) {
return false;
}
try
{
try {
IASTDeclarator d = initDeclarator();
IToken la = LA(1);
backup( mark );
if( la == null || la.getType() == IToken.tEOC )
backup(mark);
if (la == null || la.getType() == IToken.tEOC)
return false;
final ASTNode n = ((ASTNode)d);
final ASTNode n = ((ASTNode) d);
final int length = n.getLength();
final int offset = n.getOffset();
if( length == 0 )
if (length == 0)
return false;
if( flags.parm )
{
ASTNode name = (ASTNode)d.getName();
if( name.getOffset() == offset && name.getLength() == length )
if (flags.parm) {
ASTNode name = (ASTNode) d.getName();
if (name.getOffset() == offset && name.getLength() == length)
return false;
if( d.getInitializer() != null )
{
if (d.getInitializer() != null) {
ASTNode init = (ASTNode) d.getInitializer();
if( name.getOffset() == offset && n.getOffset() + n.getLength() == init.getOffset() + init.getLength() )
if (name.getOffset() == offset
&& n.getOffset() + n.getLength() == init
.getOffset()
+ init.getLength())
return false;
}
switch( la.getType() )
{
switch (la.getType()) {
case IToken.tCOMMA:
case IToken.tRPAREN:
return true;
@ -1101,25 +1098,26 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
switch( la.getType() )
{
case IToken.tCOMMA:
case IToken.tLBRACE:
return true;
case IToken.tSEMI:
if( d instanceof IASTFieldDeclarator )
return false;
return true;
default:
return false;
}
}
catch( BacktrackException bte )
{
backup( mark );
return checkTokenVsDeclarator(la, d);
} catch (BacktrackException bte) {
backup(mark);
return false;
} catch (EndOfFileException e) {
backup( mark );
backup(mark);
return false;
}
}
protected boolean checkTokenVsDeclarator(IToken la, IASTDeclarator d) {
switch (la.getType()) {
case IToken.tCOMMA:
case IToken.tLBRACE:
return true;
case IToken.tSEMI:
if (d instanceof IASTFieldDeclarator)
return false;
return true;
default:
return false;
}
}
@ -1135,17 +1133,18 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
// is this for a simpleDeclaration or parameterDeclaration?
boolean constructor = false;
boolean typeId = false;
// are we attempting the constructor strategy?
public Flags(boolean parm, boolean c, boolean t) {
this.parm = parm;
constructor = c;
typeId =t;
typeId = t;
}
public Flags(boolean parm, boolean typeId ) {
this(parm, false, typeId );
public Flags(boolean parm, boolean typeId) {
this(parm, false, typeId);
}
/**
@ -1198,17 +1197,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
/**
* Parse an enumeration specifier, as according to the ANSI specs in C &
* C++.
*
* enumSpecifier: "enum" (name)? "{" (enumerator-list) "}" enumerator-list:
* enumerator-definition enumerator-list , enumerator-definition
* enumerator-definition: enumerator enumerator = constant-expression
* enumerator: identifier
* C++. enumSpecifier: "enum" (name)? "{" (enumerator-list) "}"
* enumerator-list: enumerator-definition enumerator-list ,
* enumerator-definition enumerator-definition: enumerator enumerator =
* constant-expression enumerator: identifier
*
* @param owner
* IParserCallback object that represents the declaration that
* owns this type specifier.
*
* @throws BacktrackException
* request a backtrack
*/
@ -1514,10 +1510,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
BacktrackException savedBt = null;
try {
IASTExpression expression = expression();
if( LT(1) == IToken.tEOC )
lastTokenOfExpression = consume();
if (LT(1) == IToken.tEOC)
lastTokenOfExpression = consume();
else
lastTokenOfExpression = consume( IToken.tSEMI );
lastTokenOfExpression = consume(IToken.tSEMI);
expressionStatement = createExpressionStatement();
expressionStatement.setExpression(expression);
((ASTNode) expressionStatement).setOffsetAndLength(
@ -1570,10 +1566,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return ds;
}
if( lhs instanceof IASTFunctionCallExpression )
{
//lvalue - makes no sense
return ds;
if (lhs instanceof IASTFunctionCallExpression) {
// lvalue - makes no sense
return ds;
}
}
}
@ -1597,14 +1592,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (ds.getDeclaration() instanceof IASTSimpleDeclaration
&& ((IASTSimpleDeclaration) ds.getDeclaration())
.getDeclSpecifier() instanceof IASTNamedTypeSpecifier )
.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].getNestedDeclarator() == null ) ) )
{
final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds
.getDeclaration()).getDeclarators();
if (declarators.length == 0
|| (declarators.length == 1 && (declarators[0].getName()
.toCharArray().length == 0 && declarators[0]
.getNestedDeclarator() == null))) {
backup(mark);
while (true) {
if (consume() == lastTokenOfExpression)
@ -1615,15 +1611,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
IASTAmbiguousStatement statement = createAmbiguousStatement();
statement.addStatement( ds );
ds.setParent( statement );
ds.setPropertyInParent( IASTAmbiguousStatement.STATEMENT );
statement.addStatement( expressionStatement );
expressionStatement.setParent( statement );
expressionStatement.setPropertyInParent( IASTAmbiguousStatement.STATEMENT );
((ASTNode)statement).setOffsetAndLength( (ASTNode) ds );
statement.addStatement(ds);
ds.setParent(statement);
ds.setPropertyInParent(IASTAmbiguousStatement.STATEMENT);
statement.addStatement(expressionStatement);
expressionStatement.setParent(statement);
expressionStatement
.setPropertyInParent(IASTAmbiguousStatement.STATEMENT);
((ASTNode) statement).setOffsetAndLength((ASTNode) ds);
return statement;
}
@ -1728,35 +1724,35 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
startOffset = consume(IToken.t_return).getOffset();
IASTExpression result = null;
// See if there is a return expression
switch (LT(1)) {
case IToken.tEOC:
// We're trying to start one
IASTName name = createName(LA(1));
IASTIdExpression idExpr = createIdExpression();
idExpr.setName(name);
name.setParent(idExpr);
name.setPropertyInParent(IASTIdExpression.ID_NAME);
result = idExpr;
break;
case IToken.tSEMI:
// None
break;
default:
// Yes
// See if there is a return expression
switch (LT(1)) {
case IToken.tEOC:
// We're trying to start one
IASTName name = createName(LA(1));
IASTIdExpression idExpr = createIdExpression();
idExpr.setName(name);
name.setParent(idExpr);
name.setPropertyInParent(IASTIdExpression.ID_NAME);
result = idExpr;
break;
case IToken.tSEMI:
// None
break;
default:
// Yes
result = expression();
break;
break;
}
int lastOffset = 0;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
lastOffset = consume().getEndOffset();
break;
default:
throwBacktrack(LA(1));
}
int lastOffset = 0;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
lastOffset = consume().getEndOffset();
break;
default:
throwBacktrack(LA(1));
}
IASTReturnStatement return_statement = createReturnStatement();
((ASTNode) return_statement).setOffsetAndLength(startOffset, lastOffset
@ -1781,46 +1777,46 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
consume(IToken.tLPAREN);
IASTNode init = forInitStatement();
IASTExpression for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
break;
default:
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
break;
default:
for_condition = condition();
}
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
}
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTExpression iterationExpression = null;
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
break;
default:
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
break;
default:
iterationExpression = expression();
}
switch (LT(1)) {
case IToken.tRPAREN:
consume(IToken.tRPAREN);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
}
switch (LT(1)) {
case IToken.tRPAREN:
consume(IToken.tRPAREN);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTForStatement for_statement = createForStatement();
IASTStatement for_body = null;
if (LT(1) != IToken.tEOC) {
for_body = statement();
((ASTNode) for_statement).setOffsetAndLength(startOffset,
calculateEndOffset(for_body) - startOffset);
}
IASTStatement for_body = null;
if (LT(1) != IToken.tEOC) {
for_body = statement();
((ASTNode) for_statement).setOffsetAndLength(startOffset,
calculateEndOffset(for_body) - startOffset);
}
if (init instanceof IASTDeclaration) {
for_statement.setInit((IASTDeclaration) init);
@ -1843,11 +1839,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
iterationExpression.setParent(for_statement);
iterationExpression.setPropertyInParent(IASTForStatement.ITERATION);
}
if (for_body != null) {
for_statement.setBody(for_body);
for_body.setParent(for_statement);
for_body.setPropertyInParent(IASTForStatement.BODY);
}
if (for_body != null) {
for_statement.setBody(for_body);
for_body.setParent(for_statement);
for_body.setPropertyInParent(IASTForStatement.BODY);
}
return for_statement;
}
@ -1896,7 +1892,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
calculateEndOffset(while_body) - startOffset);
while_statement.setCondition(while_condition);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
while_condition
.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
while_statement.setBody(while_body);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.BODY);
@ -1948,9 +1945,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
- r.getOffset());
} else {
ASTNode then_clause = (ASTNode) current.getThenClause();
if( then_clause != null )
r.setLength(then_clause.getOffset() + then_clause.getLength()
- r.getOffset());
if (then_clause != null)
r.setLength(then_clause.getOffset()
+ then_clause.getLength() - r.getOffset());
}
if (current.getParent() != null
&& current.getParent() instanceof IASTIfStatement)
@ -2017,10 +2014,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @param declarators
* @return
*/
protected int figureEndOffset(IASTDeclSpecifier declSpec, IASTDeclarator [] declarators) {
if (declarators.length == 0 )
protected int figureEndOffset(IASTDeclSpecifier declSpec,
IASTDeclarator[] declarators) {
if (declarators.length == 0)
return calculateEndOffset(declSpec);
return calculateEndOffset(declarators[ declarators.length - 1 ] );
return calculateEndOffset(declarators[declarators.length - 1]);
}
/**
@ -2042,18 +2040,17 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(token.getOffset(), token.getLength());
}
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses ) throws EndOfFileException {
protected IASTNode[] parseTypeIdOrUnaryExpression(
boolean typeIdWithParentheses) throws EndOfFileException {
IASTTypeId typeId = null;
IASTExpression unaryExpression = null;
IToken typeIdLA = null, unaryExpressionLA = null;
IToken mark = mark();
try
{
if( typeIdWithParentheses )
consume( IToken.tLPAREN );
typeId = typeId( false );
if( typeIdWithParentheses )
{
try {
if (typeIdWithParentheses)
consume(IToken.tLPAREN);
typeId = typeId(false);
if (typeIdWithParentheses) {
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
@ -2065,38 +2062,31 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
typeIdLA = LA(1);
}
catch( BacktrackException bte )
{
} catch (BacktrackException bte) {
typeId = null;
}
backup( mark );
try
{
backup(mark);
try {
unaryExpression = unaryExpression();
unaryExpressionLA = LA(1);
}
catch( BacktrackException bte )
{
} catch (BacktrackException bte) {
unaryExpression = null;
}
IASTNode [] result;
if( unaryExpression == null && typeId != null )
{
backup( typeIdLA );
IASTNode[] result;
if (unaryExpression == null && typeId != null) {
backup(typeIdLA);
result = new IASTNode[1];
result[0] = typeId;
return result;
}
if( unaryExpression != null && typeId == null )
{
backup( unaryExpressionLA );
if (unaryExpression != null && typeId == null) {
backup(unaryExpressionLA);
result = new IASTNode[1];
result[0] = unaryExpression;
return result;
}
if( unaryExpression != null && typeId != null && typeIdLA == unaryExpressionLA )
{
if (unaryExpression != null && typeId != null
&& typeIdLA == unaryExpressionLA) {
result = new IASTNode[2];
result[0] = typeId;
result[1] = unaryExpression;
@ -2108,7 +2098,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTAmbiguousExpression createAmbiguousExpression();
protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException {
protected IASTExpression parseSizeofExpression() throws BacktrackException,
EndOfFileException {
int startingOffset = consume(IToken.t_sizeof).getOffset();
IASTNode[] choice = parseTypeIdOrUnaryExpression(true);
switch (choice.length) {

View file

@ -159,8 +159,6 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
*/
public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private static final String COMPL = "~"; //$NON-NLS-1$
private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
@ -544,13 +542,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) {
try {
nameDuple = name();
if( nameDuple.length() == 1 )
{
if (nameDuple.length() == 1) {
backup(mark);
return;
}
if( nameDuple.getLastToken().getType() != IToken.tCOLONCOLON )
{
if (nameDuple.getLastToken().getType() != IToken.tCOLONCOLON) {
backup(mark);
return;
}
@ -945,10 +941,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTDeclarator declarator = null;
try {
declSpecifier = declSpecifierSeq(true, true, true);
declSpecifier = declSpecifierSeq(true, true);
if (LT(1) != IToken.tEOC)
declarator = declarator(
SimpleDeclarationStrategy.TRY_CONSTRUCTOR, forNewExpression);
SimpleDeclarationStrategy.TRY_FUNCTION,
forNewExpression);
} catch (BacktrackException bt) {
backup(mark);
throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
@ -1926,8 +1923,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IParserLogService log, ICPPParserExtensionConfiguration config) {
super(scanner, log, mode, config.supportStatementsInExpressions(),
config.supportTypeofUnaryExpressions(), config
.supportAlignOfUnaryExpression(), config.
supportKnRC(), config.supportGCCOtherBuiltinSymbols());
.supportAlignOfUnaryExpression(), config.supportKnRC(),
config.supportGCCOtherBuiltinSymbols());
allowCPPRestrict = config.allowRestrictPointerOperators();
supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax();
supportMinAndMaxOperators = config.supportMinAndMaxOperators();
@ -2430,51 +2427,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected IASTDeclaration simpleDeclarationStrategyUnion()
throws EndOfFileException, BacktrackException {
simpleDeclarationMark = mark();
IASTProblem firstFailure = null;
IASTProblem secondFailure = null;
try {
IASTDeclaration d = simpleDeclaration(
SimpleDeclarationStrategy.TRY_CONSTRUCTOR, false);
SimpleDeclarationStrategy.TRY_FUNCTION, false);
throwAwayMarksForInitializerClause();
return d;
} catch (BacktrackException bt) {
if (simpleDeclarationMark == null)
throwBacktrack(bt);
firstFailure = bt.getProblem();
// did not work
backup(simpleDeclarationMark);
try {
IASTDeclaration d = simpleDeclaration(
SimpleDeclarationStrategy.TRY_FUNCTION, false);
throwAwayMarksForInitializerClause();
return d;
} catch (BacktrackException bt2) {
if (simpleDeclarationMark == null) {
if (firstFailure != null && (bt2.getProblem() == null))
throwBacktrack(firstFailure);
else
throwBacktrack(bt2);
}
secondFailure = bt2.getProblem();
backup(simpleDeclarationMark);
throwAwayMarksForInitializerClause();
try {
return simpleDeclaration(
SimpleDeclarationStrategy.TRY_VARIABLE, false);
} catch (BacktrackException b3) {
backup(simpleDeclarationMark); // TODO - necessary?
if (firstFailure != null)
throwBacktrack(firstFailure);
else if (secondFailure != null)
throwBacktrack(secondFailure);
else
throwBacktrack(b3);
return null;
}
}
IASTDeclaration d = simpleDeclaration(
SimpleDeclarationStrategy.TRY_VARIABLE, false);
throwAwayMarksForInitializerClause();
return d;
}
}
@ -2758,8 +2725,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throwBacktrack(firstOffset, firstToken.getLength());
firstToken = null; // necessary for scalability
ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false,
strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR, false);
ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false, false);
IASTDeclarator[] declarators = new IASTDeclarator[2];
if (LT(1) != IToken.tSEMI && LT(1) != IToken.tEOC) {
declarators = (IASTDeclarator[]) ArrayUtil
@ -3023,7 +2989,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected ICPPASTParameterDeclaration parameterDeclaration()
throws BacktrackException, EndOfFileException {
IToken current = LA(1);
IASTDeclSpecifier declSpec = declSpecifierSeq(true, false, false);
IASTDeclSpecifier declSpec = declSpecifierSeq(true, false);
IASTDeclarator declarator = null;
if (LT(1) != IToken.tSEMI)
declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
@ -3054,83 +3020,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTParameterDeclaration();
}
/**
* @param flags
* input flags that are used to make our decision
* @return whether or not this looks like a constructor (true or false)
* @throws EndOfFileException
* we could encounter EOF while looking ahead
*/
protected boolean lookAheadForConstructorOrOperator(Flags flags)
throws EndOfFileException {
if (flags.isForParameterDeclaration())
return false;
if (LT(2) == IToken.tLPAREN && flags.isForConstructor())
return true;
IToken mark = mark();
IASTName name = null;
try {
name = consumeTemplatedOperatorName();
} catch (BacktrackException e) {
backup(mark);
return false;
} catch (EndOfFileException eof) {
backup(mark);
return false;
}
if (name == null) {
backup(mark);
return false;
}
// constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be
// defined for the global scope)
if (name instanceof ICPPASTQualifiedName) {
IASTName[] segments = ((ICPPASTQualifiedName) name).getNames();
int len = segments.length;
if (len >= 2) {
if (segments[0].toString().length() == 0) {
backup(mark);
return false;
}
if (((ICPPASTQualifiedName) name).isConversionOrOperator()) { // conversion
// or
// operator
backup(mark);
return true;
}
if (segments[len - 1].toString().equals(
segments[len - 2].toString())) { // constructor
backup(mark);
return true;
}
StringBuffer destructorName = new StringBuffer();
destructorName.append(COMPL);
destructorName.append(segments[len - 2]);
if (segments[len - 1].toString().equals(
destructorName.toString())) { // destructor
backup(mark);
return true;
}
} else {
backup(mark);
return false;
}
} else {
backup(mark);
return false;
}
backup(mark);
return false;
}
/**
* This function parses a declaration specifier sequence, as according to
* the ANSI C++ spec. declSpecifier : "auto" | "register" | "static" |
@ -3141,22 +3030,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* enumSpecifier Notes: - folded in storageClassSpecifier, typeSpecifier,
* functionSpecifier - folded elaboratedTypeSpecifier into classSpecifier
* and enumSpecifier - find template names in name
*
* @param parm
* Is this for a parameter declaration (true) or simple
* declaration (false)
* @param tryConstructor
* true for constructor, false for pointer to function strategy
* @param forTypeId TODO
*
* @param forTypeId
* TODO
* @return TODO
* @throws BacktrackException
* request a backtrack
*/
protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm,
boolean tryConstructor, boolean forTypeId) throws BacktrackException,
EndOfFileException {
boolean forTypeId) throws BacktrackException, EndOfFileException {
IToken firstToken = LA(1);
Flags flags = new Flags(parm, tryConstructor, forTypeId );
Flags flags = new Flags(parm, false, forTypeId);
IToken last = null;
boolean isInline = false, isVirtual = false, isExplicit = false, isFriend = false;
@ -3318,16 +3205,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOLONCOLON:
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
// TODO - Kludgy way to handle constructors/destructors
if (flags.haveEncounteredRawType())
break declSpecifiers;
if (flags.haveEncounteredTypename())
break declSpecifiers;
if (lookAheadForConstructorOrOperator(flags))
break declSpecifiers;
if (lookAheadForDeclarator(flags))
break declSpecifiers;
@ -3548,9 +3431,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTElaboratedTypeSpecifier();
}
protected IASTDeclarator initDeclarator() throws EndOfFileException, BacktrackException {
return initDeclarator( SimpleDeclarationStrategy.TRY_FUNCTION );
protected IASTDeclarator initDeclarator() throws EndOfFileException,
BacktrackException {
return initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
}
/**
* Parses the initDeclarator construct of the ANSI C++ spec. initDeclarator :
* declarator ("=" initializerClause | "(" expressionList ")")?
@ -3698,18 +3583,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* (constantExpression)? "]" | "(" declarator")" | directDeclarator "("
* parameterDeclarationClause ")" (oldKRParameterDeclaration)* declaratorId :
* name
*
* @param forNewTypeId
* TODO
* @param container
* IParserCallback object that represents the owner declaration.
*
* @return declarator that this parsing produced.
* @throws BacktrackException
* request a backtrack
*/
protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy,
boolean forNewTypeId)
throws EndOfFileException, BacktrackException {
boolean forNewTypeId) throws EndOfFileException, BacktrackException {
IToken la = LA(1);
int startingOffset = la.getOffset();
@ -3760,33 +3644,33 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
switch (LT(1)) {
case IToken.tLPAREN:
// boolean failed = false;
//
// // temporary fix for initializer/function declaration
// // ambiguity
// if (!LA(2).looksLikeExpression()
// && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) {
// if (LT(2) == IToken.tIDENTIFIER) {
// IToken newMark = mark();
// consume(IToken.tLPAREN);
// try {
// name();
// // TODO - we need to lookup/resolve this name
// // see if its a type ...
// // if it is a type, failed = false
// // else failed = true
// failed = false;
// } catch (BacktrackException b) {
// failed = true;
// }
//
// backup(newMark);
// }
// }
// boolean failed = false;
//
// // temporary fix for initializer/function declaration
// // ambiguity
// if (!LA(2).looksLikeExpression()
// && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) {
// if (LT(2) == IToken.tIDENTIFIER) {
// IToken newMark = mark();
// consume(IToken.tLPAREN);
// try {
// name();
// // TODO - we need to lookup/resolve this name
// // see if its a type ...
// // if it is a type, failed = false
// // else failed = true
// failed = false;
// } catch (BacktrackException b) {
// failed = true;
// }
//
// backup(newMark);
// }
// }
if ((!LA(2).looksLikeExpression()
&& strategy != SimpleDeclarationStrategy.TRY_VARIABLE
// && !failed
&& !forNewTypeId)) {
// && !failed
&& !forNewTypeId)) {
// parameterDeclarationClause
isFunction = true;
// TODO need to create a temporary scope object here
@ -4501,15 +4385,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
try {
translationUnit = createTranslationUnit();
// add built-in names to the scope
if (supportGCCOtherBuiltinSymbols) {
IScope tuScope = translationUnit.getScope();
// add built-in names to the scope
if (supportGCCOtherBuiltinSymbols) {
IScope tuScope = translationUnit.getScope();
IBinding[] bindings = new GCCBuiltinSymbolProvider(translationUnit.getScope(), ParserLanguage.CPP).getBuiltinBindings();
for(int i=0; i<bindings.length; i++) {
tuScope.addBinding(bindings[i]);
}
}
IBinding[] bindings = new GCCBuiltinSymbolProvider(
translationUnit.getScope(), ParserLanguage.CPP)
.getBuiltinBindings();
for (int i = 0; i < bindings.length; i++) {
tuScope.addBinding(bindings[i]);
}
}
} catch (Exception e2) {
logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$
return;
@ -5095,7 +4981,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException {
protected IASTStatement parseIfStatement() throws EndOfFileException,
BacktrackException {
ICPPASTIfStatement result = null;
ICPPASTIfStatement if_statement = null;
int start = LA(1).getOffset();
@ -5104,24 +4991,27 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tLPAREN);
IASTNode condition = null;
try {
condition = cppStyleCondition(); //TODO should be while condition
if (LT(1) == IToken.tEOC) {
// Completing in the condition
ICPPASTIfStatement new_if = createIfStatement();
if( condition instanceof IASTExpression )
new_if.setConditionExpression((IASTExpression) condition);
else if( condition instanceof IASTDeclaration )
new_if.setConditionDeclaration((IASTDeclaration) condition);
condition.setParent(new_if);
condition.setPropertyInParent(IASTIfStatement.CONDITION);
condition = cppStyleCondition(); // TODO should be while
// condition
if (LT(1) == IToken.tEOC) {
// Completing in the condition
ICPPASTIfStatement new_if = createIfStatement();
if (condition instanceof IASTExpression)
new_if
.setConditionExpression((IASTExpression) condition);
else if (condition instanceof IASTDeclaration)
new_if
.setConditionDeclaration((IASTDeclaration) condition);
condition.setParent(new_if);
condition.setPropertyInParent(IASTIfStatement.CONDITION);
if (if_statement != null) {
if (if_statement != null) {
if_statement.setElseClause(new_if);
new_if.setParent(if_statement);
new_if.setPropertyInParent(IASTIfStatement.ELSE);
}
return result != null ? result : new_if;
}
}
return result != null ? result : new_if;
}
consume(IToken.tRPAREN);
} catch (BacktrackException b) {
IASTProblem p = failParse(b);
@ -5132,24 +5022,32 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
p.setParent(ps);
p.setPropertyInParent(IASTProblemHolder.PROBLEM);
condition = ps;
if( LT(1) == IToken.tRPAREN )
consume();
else if( LT(2) == IToken.tRPAREN )
{
consume();
consume();
}
else
failParseWithErrorHandling();
if (LT(1) == IToken.tRPAREN)
consume();
else if (LT(2) == IToken.tRPAREN) {
consume();
consume();
} else
failParseWithErrorHandling();
}
IASTStatement thenClause = statement();
ICPPASTIfStatement new_if_statement = createIfStatement();
((ASTNode) new_if_statement).setOffset(so);
if( condition != null && condition instanceof IASTExpression ) // shouldn't be possible but failure in condition() makes it so
if (condition != null && condition instanceof IASTExpression) // shouldn't
// be
// possible
// but
// failure
// in
// condition()
// makes
// it
// so
{
new_if_statement.setConditionExpression((IASTExpression) condition);
new_if_statement
.setConditionExpression((IASTExpression) condition);
condition.setParent(new_if_statement);
condition.setPropertyInParent(IASTIfStatement.CONDITION);
}
@ -5202,7 +5100,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if_statement = new_if_statement;
}
} else {
if( thenClause != null )
if (thenClause != null)
((ASTNode) new_if_statement)
.setLength(calculateEndOffset(thenClause) - start);
if (if_statement != null) {
@ -5227,4 +5125,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return result;
}
protected boolean checkTokenVsDeclarator(IToken la, IASTDeclarator d) {
switch (la.getType()) {
case IToken.tCOLON:
case IToken.t_try:
return true;
default:
return super.checkTokenVsDeclarator(la, d);
}
}
}