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

View file

@ -121,7 +121,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected ASTCompletionNode completionNode; protected ASTCompletionNode completionNode;
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser#getCompletionNode() * @see org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser#getCompletionNode()
*/ */
public ASTCompletionNode getCompletionNode() { public ASTCompletionNode getCompletionNode() {
@ -134,6 +136,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
completionNode = new ASTCompletionNode(token, getTranslationUnit()); completionNode = new ASTCompletionNode(token, getTranslationUnit());
return completionNode; return completionNode;
} }
/** /**
* Look Ahead in the token list to see what is coming. * Look Ahead in the token list to see what is coming.
* *
@ -267,7 +270,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* *
* @param mark * @param mark
* The point that we wish to restore to. * The point that we wish to restore to.
*
*/ */
protected void backup(IToken mark) { protected void backup(IToken mark) {
currToken = mark; currToken = mark;
@ -417,9 +419,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return result; return result;
} }
protected void resolveAmbiguities() protected void resolveAmbiguities() {
{ getTranslationUnit().accept(createVisitor());
getTranslationUnit().accept( createVisitor() );
} }
protected abstract ASTVisitor createVisitor(); protected abstract ASTVisitor createVisitor();
@ -644,8 +645,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpression multiplicativeExpression() protected abstract IASTExpression multiplicativeExpression()
throws BacktrackException, EndOfFileException; throws BacktrackException, EndOfFileException;
protected abstract IASTTypeId typeId(boolean forNewExpression) throws BacktrackException, protected abstract IASTTypeId typeId(boolean forNewExpression)
EndOfFileException; throws BacktrackException, EndOfFileException;
protected abstract IASTExpression castExpression() protected abstract IASTExpression castExpression()
throws BacktrackException, EndOfFileException; throws BacktrackException, EndOfFileException;
@ -1036,7 +1037,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* Parses a function body. * Parses a function body.
* *
* @return TODO * @return TODO
*
* @throws BacktrackException * @throws BacktrackException
* request a backtrack * request a backtrack
*/ */
@ -1045,8 +1045,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return compoundStatement(); return compoundStatement();
} }
protected abstract IASTDeclarator initDeclarator() throws EndOfFileException, protected abstract IASTDeclarator initDeclarator()
BacktrackException; throws EndOfFileException, BacktrackException;
/** /**
* @param flags * @param flags
* input flags that are used to make our decision * input flags that are used to make our decision
@ -1055,44 +1056,40 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @throws EndOfFileException * @throws EndOfFileException
* we could encounter EOF while looking ahead * we could encounter EOF while looking ahead
*/ */
protected boolean lookAheadForDeclarator(Flags flags) protected boolean lookAheadForDeclarator(Flags flags) {
{ if (flags.typeId)
if( flags.typeId ) return false; return false;
IToken mark = null; IToken mark = null;
try try {
{
mark = mark(); mark = mark();
} } catch (EndOfFileException eof) {
catch( EndOfFileException eof )
{
return false; return false;
} }
try try {
{
IASTDeclarator d = initDeclarator(); IASTDeclarator d = initDeclarator();
IToken la = LA(1); IToken la = LA(1);
backup( mark ); backup(mark);
if( la == null || la.getType() == IToken.tEOC ) if (la == null || la.getType() == IToken.tEOC)
return false; return false;
final ASTNode n = ((ASTNode)d); final ASTNode n = ((ASTNode) d);
final int length = n.getLength(); final int length = n.getLength();
final int offset = n.getOffset(); final int offset = n.getOffset();
if( length == 0 ) if (length == 0)
return false; return false;
if( flags.parm ) if (flags.parm) {
{ ASTNode name = (ASTNode) d.getName();
ASTNode name = (ASTNode)d.getName(); if (name.getOffset() == offset && name.getLength() == length)
if( name.getOffset() == offset && name.getLength() == length )
return false; return false;
if( d.getInitializer() != null ) if (d.getInitializer() != null) {
{
ASTNode init = (ASTNode) d.getInitializer(); 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; return false;
} }
switch( la.getType() ) switch (la.getType()) {
{
case IToken.tCOMMA: case IToken.tCOMMA:
case IToken.tRPAREN: case IToken.tRPAREN:
return true; return true;
@ -1101,28 +1098,29 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
} }
switch( la.getType() ) return checkTokenVsDeclarator(la, d);
{ } catch (BacktrackException bte) {
backup(mark);
return false;
} catch (EndOfFileException e) {
backup(mark);
return false;
}
}
protected boolean checkTokenVsDeclarator(IToken la, IASTDeclarator d) {
switch (la.getType()) {
case IToken.tCOMMA: case IToken.tCOMMA:
case IToken.tLBRACE: case IToken.tLBRACE:
return true; return true;
case IToken.tSEMI: case IToken.tSEMI:
if( d instanceof IASTFieldDeclarator ) if (d instanceof IASTFieldDeclarator)
return false; return false;
return true; return true;
default: default:
return false; return false;
} }
} }
catch( BacktrackException bte )
{
backup( mark );
return false;
} catch (EndOfFileException e) {
backup( mark );
return false;
}
}
public static class Flags { public static class Flags {
private boolean encounteredTypename = false; private boolean encounteredTypename = false;
@ -1135,17 +1133,18 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
// is this for a simpleDeclaration or parameterDeclaration? // is this for a simpleDeclaration or parameterDeclaration?
boolean constructor = false; boolean constructor = false;
boolean typeId = false; boolean typeId = false;
// are we attempting the constructor strategy? // are we attempting the constructor strategy?
public Flags(boolean parm, boolean c, boolean t) { public Flags(boolean parm, boolean c, boolean t) {
this.parm = parm; this.parm = parm;
constructor = c; constructor = c;
typeId =t; typeId = t;
} }
public Flags(boolean parm, boolean typeId ) { public Flags(boolean parm, boolean typeId) {
this(parm, false, 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 & * Parse an enumeration specifier, as according to the ANSI specs in C &
* C++. * C++. enumSpecifier: "enum" (name)? "{" (enumerator-list) "}"
* * enumerator-list: enumerator-definition enumerator-list ,
* enumSpecifier: "enum" (name)? "{" (enumerator-list) "}" enumerator-list: * enumerator-definition enumerator-definition: enumerator enumerator =
* enumerator-definition enumerator-list , enumerator-definition * constant-expression enumerator: identifier
* enumerator-definition: enumerator enumerator = constant-expression
* enumerator: identifier
* *
* @param owner * @param owner
* IParserCallback object that represents the declaration that * IParserCallback object that represents the declaration that
* owns this type specifier. * owns this type specifier.
*
* @throws BacktrackException * @throws BacktrackException
* request a backtrack * request a backtrack
*/ */
@ -1514,10 +1510,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
BacktrackException savedBt = null; BacktrackException savedBt = null;
try { try {
IASTExpression expression = expression(); IASTExpression expression = expression();
if( LT(1) == IToken.tEOC ) if (LT(1) == IToken.tEOC)
lastTokenOfExpression = consume(); lastTokenOfExpression = consume();
else else
lastTokenOfExpression = consume( IToken.tSEMI ); lastTokenOfExpression = consume(IToken.tSEMI);
expressionStatement = createExpressionStatement(); expressionStatement = createExpressionStatement();
expressionStatement.setExpression(expression); expressionStatement.setExpression(expression);
((ASTNode) expressionStatement).setOffsetAndLength( ((ASTNode) expressionStatement).setOffsetAndLength(
@ -1570,9 +1566,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return ds; return ds;
} }
if( lhs instanceof IASTFunctionCallExpression ) if (lhs instanceof IASTFunctionCallExpression) {
{ // lvalue - makes no sense
//lvalue - makes no sense
return ds; return ds;
} }
} }
@ -1597,14 +1592,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (ds.getDeclaration() instanceof IASTSimpleDeclaration if (ds.getDeclaration() instanceof IASTSimpleDeclaration
&& ((IASTSimpleDeclaration) ds.getDeclaration()) && ((IASTSimpleDeclaration) ds.getDeclaration())
.getDeclSpecifier() instanceof IASTNamedTypeSpecifier ) .getDeclSpecifier() instanceof IASTNamedTypeSpecifier)
{ {
final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds.getDeclaration()).getDeclarators(); final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds
if( declarators.length == 0 || .getDeclaration()).getDeclarators();
( declarators.length == 1 && if (declarators.length == 0
( declarators[0].getName().toCharArray().length == 0 && declarators[0].getNestedDeclarator() == null ) ) ) || (declarators.length == 1 && (declarators[0].getName()
{ .toCharArray().length == 0 && declarators[0]
.getNestedDeclarator() == null))) {
backup(mark); backup(mark);
while (true) { while (true) {
if (consume() == lastTokenOfExpression) if (consume() == lastTokenOfExpression)
@ -1615,15 +1611,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
} }
IASTAmbiguousStatement statement = createAmbiguousStatement(); IASTAmbiguousStatement statement = createAmbiguousStatement();
statement.addStatement( ds ); statement.addStatement(ds);
ds.setParent( statement ); ds.setParent(statement);
ds.setPropertyInParent( IASTAmbiguousStatement.STATEMENT ); ds.setPropertyInParent(IASTAmbiguousStatement.STATEMENT);
statement.addStatement( expressionStatement ); statement.addStatement(expressionStatement);
expressionStatement.setParent( statement ); expressionStatement.setParent(statement);
expressionStatement.setPropertyInParent( IASTAmbiguousStatement.STATEMENT ); expressionStatement
((ASTNode)statement).setOffsetAndLength( (ASTNode) ds ); .setPropertyInParent(IASTAmbiguousStatement.STATEMENT);
((ASTNode) statement).setOffsetAndLength((ASTNode) ds);
return statement; return statement;
} }
@ -1896,7 +1892,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
calculateEndOffset(while_body) - startOffset); calculateEndOffset(while_body) - startOffset);
while_statement.setCondition(while_condition); while_statement.setCondition(while_condition);
while_condition.setParent(while_statement); while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION); while_condition
.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
while_statement.setBody(while_body); while_statement.setBody(while_body);
while_condition.setParent(while_statement); while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.BODY); while_condition.setPropertyInParent(IASTWhileStatement.BODY);
@ -1948,9 +1945,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
- r.getOffset()); - r.getOffset());
} else { } else {
ASTNode then_clause = (ASTNode) current.getThenClause(); ASTNode then_clause = (ASTNode) current.getThenClause();
if( then_clause != null ) if (then_clause != null)
r.setLength(then_clause.getOffset() + then_clause.getLength() r.setLength(then_clause.getOffset()
- r.getOffset()); + then_clause.getLength() - r.getOffset());
} }
if (current.getParent() != null if (current.getParent() != null
&& current.getParent() instanceof IASTIfStatement) && current.getParent() instanceof IASTIfStatement)
@ -2017,10 +2014,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @param declarators * @param declarators
* @return * @return
*/ */
protected int figureEndOffset(IASTDeclSpecifier declSpec, IASTDeclarator [] declarators) { protected int figureEndOffset(IASTDeclSpecifier declSpec,
if (declarators.length == 0 ) IASTDeclarator[] declarators) {
if (declarators.length == 0)
return calculateEndOffset(declSpec); 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()); throwBacktrack(token.getOffset(), token.getLength());
} }
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses ) throws EndOfFileException { protected IASTNode[] parseTypeIdOrUnaryExpression(
boolean typeIdWithParentheses) throws EndOfFileException {
IASTTypeId typeId = null; IASTTypeId typeId = null;
IASTExpression unaryExpression = null; IASTExpression unaryExpression = null;
IToken typeIdLA = null, unaryExpressionLA = null; IToken typeIdLA = null, unaryExpressionLA = null;
IToken mark = mark(); IToken mark = mark();
try try {
{ if (typeIdWithParentheses)
if( typeIdWithParentheses ) consume(IToken.tLPAREN);
consume( IToken.tLPAREN ); typeId = typeId(false);
typeId = typeId( false ); if (typeIdWithParentheses) {
if( typeIdWithParentheses )
{
switch (LT(1)) { switch (LT(1)) {
case IToken.tRPAREN: case IToken.tRPAREN:
case IToken.tEOC: case IToken.tEOC:
@ -2065,38 +2062,31 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
typeIdLA = LA(1); typeIdLA = LA(1);
} } catch (BacktrackException bte) {
catch( BacktrackException bte )
{
typeId = null; typeId = null;
} }
backup( mark ); backup(mark);
try try {
{
unaryExpression = unaryExpression(); unaryExpression = unaryExpression();
unaryExpressionLA = LA(1); unaryExpressionLA = LA(1);
} } catch (BacktrackException bte) {
catch( BacktrackException bte )
{
unaryExpression = null; unaryExpression = null;
} }
IASTNode [] result; IASTNode[] result;
if( unaryExpression == null && typeId != null ) if (unaryExpression == null && typeId != null) {
{ backup(typeIdLA);
backup( typeIdLA );
result = new IASTNode[1]; result = new IASTNode[1];
result[0] = typeId; result[0] = typeId;
return result; return result;
} }
if( unaryExpression != null && typeId == null ) if (unaryExpression != null && typeId == null) {
{ backup(unaryExpressionLA);
backup( unaryExpressionLA );
result = new IASTNode[1]; result = new IASTNode[1];
result[0] = unaryExpression; result[0] = unaryExpression;
return result; return result;
} }
if( unaryExpression != null && typeId != null && typeIdLA == unaryExpressionLA ) if (unaryExpression != null && typeId != null
{ && typeIdLA == unaryExpressionLA) {
result = new IASTNode[2]; result = new IASTNode[2];
result[0] = typeId; result[0] = typeId;
result[1] = unaryExpression; result[1] = unaryExpression;
@ -2108,7 +2098,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTAmbiguousExpression createAmbiguousExpression(); protected abstract IASTAmbiguousExpression createAmbiguousExpression();
protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException { protected IASTExpression parseSizeofExpression() throws BacktrackException,
EndOfFileException {
int startingOffset = consume(IToken.t_sizeof).getOffset(); int startingOffset = consume(IToken.t_sizeof).getOffset();
IASTNode[] choice = parseTypeIdOrUnaryExpression(true); IASTNode[] choice = parseTypeIdOrUnaryExpression(true);
switch (choice.length) { switch (choice.length) {

View file

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