mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Partial fix for
Bug 90618 - [Parser] invalid syntax error for cpp spec 6.4-3 Physical tree is now repaired, moving defect to Andrew.
This commit is contained in:
parent
1325843574
commit
5741db3525
11 changed files with 324 additions and 159 deletions
|
@ -175,8 +175,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
|||
buffer.append("}\n"); //$NON-NLS-1$
|
||||
buffer.append("}\n"); //$NON-NLS-1$
|
||||
try {
|
||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
assertTrue(false);
|
||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0); //Andrew, there should be problem bindings here - 2
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12211,4 +12211,5 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
parse(buffer.toString(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1272,7 +1272,7 @@ public class AST2Tests extends AST2BaseTest {
|
|||
|
||||
IASTIfStatement ifStatement = (IASTIfStatement) compound
|
||||
.getStatements()[2];
|
||||
exp = (IASTBinaryExpression) ifStatement.getCondition();
|
||||
exp = (IASTBinaryExpression) ifStatement.getConditionExpression();
|
||||
ue = (IASTUnaryExpression) exp.getOperand1();
|
||||
id1 = (IASTIdExpression) ue.getOperand();
|
||||
id2 = (IASTIdExpression) exp.getOperand2();
|
||||
|
@ -2599,16 +2599,16 @@ public class AST2Tests extends AST2BaseTest {
|
|||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C);
|
||||
IASTIfStatement if_statement = (IASTIfStatement) ((IASTCompoundStatement) ((IASTFunctionDefinition) tu
|
||||
.getDeclarations()[0]).getBody()).getStatements()[0];
|
||||
assertEquals(((IASTBinaryExpression) if_statement.getCondition())
|
||||
assertEquals(((IASTBinaryExpression) if_statement.getConditionExpression())
|
||||
.getOperator(), IASTBinaryExpression.op_equals);
|
||||
IASTIfStatement second_if_statement = (IASTIfStatement) if_statement
|
||||
.getElseClause();
|
||||
assertEquals(
|
||||
((IASTBinaryExpression) second_if_statement.getCondition())
|
||||
((IASTBinaryExpression) second_if_statement.getConditionExpression())
|
||||
.getOperator(), IASTBinaryExpression.op_lessThan);
|
||||
IASTIfStatement third_if_statement = (IASTIfStatement) second_if_statement
|
||||
.getElseClause();
|
||||
assertEquals(((IASTBinaryExpression) third_if_statement.getCondition())
|
||||
assertEquals(((IASTBinaryExpression) third_if_statement.getConditionExpression())
|
||||
.getOperator(), IASTBinaryExpression.op_greaterThan);
|
||||
}
|
||||
|
||||
|
|
|
@ -992,11 +992,11 @@ public class CompleteParser2Tests extends TestCase {
|
|||
IASTFunctionDefinition foo = (IASTFunctionDefinition) tu.getDeclarations()[1];
|
||||
IASTCompoundStatement compound = (IASTCompoundStatement) foo.getBody();
|
||||
IASTIfStatement ifstmt = (IASTIfStatement) compound.getStatements()[0];
|
||||
assertTrue( ifstmt.getCondition() instanceof IASTIdExpression );
|
||||
assertTrue( ifstmt.getConditionExpression() instanceof IASTIdExpression );
|
||||
assertTrue( ifstmt.getThenClause() instanceof IASTCompoundStatement );
|
||||
assertTrue( ifstmt.getElseClause() instanceof IASTIfStatement );
|
||||
ifstmt = (IASTIfStatement) ifstmt.getElseClause();
|
||||
assertTrue( ifstmt.getCondition() instanceof IASTUnaryExpression );
|
||||
assertTrue( ifstmt.getConditionExpression() instanceof IASTUnaryExpression );
|
||||
assertTrue( ifstmt.getThenClause() instanceof IASTReturnStatement );
|
||||
assertTrue( ifstmt.getElseClause() instanceof IASTCompoundStatement );
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public interface IASTIfStatement extends IASTStatement {
|
|||
*
|
||||
* @return the condition <code>IASTExpression</code>
|
||||
*/
|
||||
public IASTExpression getCondition();
|
||||
public IASTExpression getConditionExpression();
|
||||
|
||||
/**
|
||||
* Set the condition in the if statement.
|
||||
|
@ -51,7 +51,7 @@ public interface IASTIfStatement extends IASTStatement {
|
|||
* @param condition
|
||||
* <code>IASTExpression</code>
|
||||
*/
|
||||
public void setCondition(IASTExpression condition);
|
||||
public void setConditionExpression(IASTExpression condition);
|
||||
|
||||
/**
|
||||
* Get the statement that is executed if the condition is true.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||
|
||||
public interface ICPPASTIfStatement extends IASTIfStatement {
|
||||
|
||||
public IASTDeclaration getConditionDeclaration();
|
||||
public void setConditionDeclaration( IASTDeclaration d );
|
||||
|
||||
}
|
|
@ -1336,11 +1336,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
*/
|
||||
protected abstract IASTSwitchStatement createSwitchStatement();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
protected abstract IASTIfStatement createIfStatement();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
@ -1860,141 +1855,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
return switch_statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws EndOfFileException
|
||||
* @throws BacktrackException
|
||||
*/
|
||||
protected IASTStatement parseIfStatement() throws EndOfFileException,
|
||||
BacktrackException {
|
||||
IASTIfStatement result = null;
|
||||
IASTIfStatement if_statement = null;
|
||||
int start = LA(1).getOffset();
|
||||
if_loop: while (true) {
|
||||
int so = consume(IToken.t_if).getOffset();
|
||||
consume(IToken.tLPAREN);
|
||||
IASTExpression condition = null;
|
||||
try {
|
||||
condition = condition();
|
||||
if (LT(1) == IToken.tEOC) {
|
||||
// Completing in the condition
|
||||
IASTIfStatement new_if = createIfStatement();
|
||||
new_if.setCondition(condition);
|
||||
condition.setParent(new_if);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
|
||||
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;
|
||||
}
|
||||
consume(IToken.tRPAREN);
|
||||
} catch (BacktrackException b) {
|
||||
IASTProblem p = failParse(b);
|
||||
IASTProblemExpression ps = createProblemExpression();
|
||||
ps.setProblem(p);
|
||||
((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(),
|
||||
((ASTNode) p).getLength());
|
||||
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();
|
||||
}
|
||||
|
||||
IASTStatement thenClause = statement();
|
||||
|
||||
IASTIfStatement new_if_statement = createIfStatement();
|
||||
((ASTNode) new_if_statement).setOffset(so);
|
||||
if( condition != null ) // shouldn't be possible but failure in condition() makes it so
|
||||
{
|
||||
new_if_statement.setCondition(condition);
|
||||
condition.setParent(new_if_statement);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
}
|
||||
if (thenClause != null) {
|
||||
new_if_statement.setThenClause(thenClause);
|
||||
thenClause.setParent(new_if_statement);
|
||||
thenClause.setPropertyInParent(IASTIfStatement.THEN);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause)
|
||||
- ((ASTNode) new_if_statement).getOffset());
|
||||
}
|
||||
if (LT(1) == IToken.t_else) {
|
||||
consume(IToken.t_else);
|
||||
if (LT(1) == IToken.t_if) {
|
||||
// an else if, don't recurse, just loop and do another if
|
||||
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement
|
||||
.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
continue if_loop;
|
||||
}
|
||||
IASTStatement elseStatement = statement();
|
||||
new_if_statement.setElseClause(elseStatement);
|
||||
elseStatement.setParent(new_if_statement);
|
||||
elseStatement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
} else {
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
} else {
|
||||
if( thenClause != null )
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause) - start);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- start);
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
break if_loop;
|
||||
}
|
||||
|
||||
reconcileLengths(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param result
|
||||
*/
|
||||
|
|
|
@ -28,14 +28,14 @@ public class CASTIfStatement extends CASTNode implements IASTIfStatement, IASTAm
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#getCondition()
|
||||
*/
|
||||
public IASTExpression getCondition() {
|
||||
public IASTExpression getConditionExpression() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||
*/
|
||||
public void setCondition(IASTExpression condition) {
|
||||
public void setConditionExpression(IASTExpression condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
|
|
|
@ -2599,5 +2599,139 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return new CASTAmbiguousExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws EndOfFileException
|
||||
* @throws BacktrackException
|
||||
*/
|
||||
protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException {
|
||||
IASTIfStatement result = null;
|
||||
IASTIfStatement if_statement = null;
|
||||
int start = LA(1).getOffset();
|
||||
if_loop: while (true) {
|
||||
int so = consume(IToken.t_if).getOffset();
|
||||
consume(IToken.tLPAREN);
|
||||
IASTExpression condition = null;
|
||||
try {
|
||||
condition = condition();
|
||||
if (LT(1) == IToken.tEOC) {
|
||||
// Completing in the condition
|
||||
IASTIfStatement new_if = createIfStatement();
|
||||
new_if.setConditionExpression(condition);
|
||||
condition.setParent(new_if);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
|
||||
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;
|
||||
}
|
||||
consume(IToken.tRPAREN);
|
||||
} catch (BacktrackException b) {
|
||||
IASTProblem p = failParse(b);
|
||||
IASTProblemExpression ps = createProblemExpression();
|
||||
ps.setProblem(p);
|
||||
((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(),
|
||||
((ASTNode) p).getLength());
|
||||
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();
|
||||
}
|
||||
|
||||
IASTStatement thenClause = statement();
|
||||
|
||||
IASTIfStatement new_if_statement = createIfStatement();
|
||||
((ASTNode) new_if_statement).setOffset(so);
|
||||
if( condition != null ) // shouldn't be possible but failure in condition() makes it so
|
||||
{
|
||||
new_if_statement.setConditionExpression(condition);
|
||||
condition.setParent(new_if_statement);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
}
|
||||
if (thenClause != null) {
|
||||
new_if_statement.setThenClause(thenClause);
|
||||
thenClause.setParent(new_if_statement);
|
||||
thenClause.setPropertyInParent(IASTIfStatement.THEN);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause)
|
||||
- ((ASTNode) new_if_statement).getOffset());
|
||||
}
|
||||
if (LT(1) == IToken.t_else) {
|
||||
consume(IToken.t_else);
|
||||
if (LT(1) == IToken.t_if) {
|
||||
// an else if, don't recurse, just loop and do another if
|
||||
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement
|
||||
.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
continue if_loop;
|
||||
}
|
||||
IASTStatement elseStatement = statement();
|
||||
new_if_statement.setElseClause(elseStatement);
|
||||
elseStatement.setParent(new_if_statement);
|
||||
elseStatement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
} else {
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
} else {
|
||||
if( thenClause != null )
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause) - start);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- start);
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
break if_loop;
|
||||
}
|
||||
|
||||
reconcileLengths(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -11,31 +11,33 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IASTAmbiguityParent {
|
||||
public class CPPASTIfStatement extends CPPASTNode implements ICPPASTIfStatement, IASTAmbiguityParent {
|
||||
private IASTExpression condition;
|
||||
private IASTStatement thenClause;
|
||||
private IASTStatement elseClause;
|
||||
private IASTDeclaration condDecl;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#getCondition()
|
||||
*/
|
||||
public IASTExpression getCondition() {
|
||||
public IASTExpression getConditionExpression() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||
*/
|
||||
public void setCondition(IASTExpression condition) {
|
||||
public void setConditionExpression(IASTExpression condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
|
@ -76,8 +78,10 @@ public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IA
|
|||
}
|
||||
}
|
||||
if( condition != null ) if( !condition.accept( action ) ) return false;
|
||||
if( condDecl != null ) if( !condDecl.accept( action )) return false;
|
||||
if( thenClause != null ) if( !thenClause.accept( action ) ) return false;
|
||||
if( elseClause != null ) if( !elseClause.accept( action ) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -95,4 +99,12 @@ public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IA
|
|||
elseClause = (IASTStatement) other;
|
||||
}
|
||||
}
|
||||
|
||||
public IASTDeclaration getConditionDeclaration() {
|
||||
return condDecl;
|
||||
}
|
||||
|
||||
public void setConditionDeclaration(IASTDeclaration d) {
|
||||
condDecl = d;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
|
@ -4820,7 +4821,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
/**
|
||||
* @return
|
||||
*/
|
||||
protected IASTIfStatement createIfStatement() {
|
||||
protected ICPPASTIfStatement createIfStatement() {
|
||||
return new CPPASTIfStatement();
|
||||
}
|
||||
|
||||
|
@ -5000,7 +5001,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
BacktrackException {
|
||||
int startOffset = consume(IToken.t_while).getOffset();
|
||||
consume(IToken.tLPAREN);
|
||||
IASTNode while_condition = whileCondition();
|
||||
IASTNode while_condition = cppStyleCondition();
|
||||
consume(IToken.tRPAREN);
|
||||
IASTStatement while_body = statement();
|
||||
|
||||
|
@ -5029,7 +5030,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
/**
|
||||
* @return
|
||||
*/
|
||||
protected IASTNode whileCondition() throws BacktrackException,
|
||||
protected IASTNode cppStyleCondition() throws BacktrackException,
|
||||
EndOfFileException {
|
||||
IToken mark = mark();
|
||||
try {
|
||||
|
@ -5066,4 +5067,141 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return new CPPASTAmbiguousStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws EndOfFileException
|
||||
* @throws BacktrackException
|
||||
*/
|
||||
protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException {
|
||||
ICPPASTIfStatement result = null;
|
||||
ICPPASTIfStatement if_statement = null;
|
||||
int start = LA(1).getOffset();
|
||||
if_loop: while (true) {
|
||||
int so = consume(IToken.t_if).getOffset();
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
consume(IToken.tRPAREN);
|
||||
} catch (BacktrackException b) {
|
||||
IASTProblem p = failParse(b);
|
||||
IASTProblemExpression ps = createProblemExpression();
|
||||
ps.setProblem(p);
|
||||
((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(),
|
||||
((ASTNode) p).getLength());
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
new_if_statement.setConditionExpression((IASTExpression) condition);
|
||||
condition.setParent(new_if_statement);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
}
|
||||
if (thenClause != null) {
|
||||
new_if_statement.setThenClause(thenClause);
|
||||
thenClause.setParent(new_if_statement);
|
||||
thenClause.setPropertyInParent(IASTIfStatement.THEN);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause)
|
||||
- ((ASTNode) new_if_statement).getOffset());
|
||||
}
|
||||
if (LT(1) == IToken.t_else) {
|
||||
consume(IToken.t_else);
|
||||
if (LT(1) == IToken.t_if) {
|
||||
// an else if, don't recurse, just loop and do another if
|
||||
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement
|
||||
.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
continue if_loop;
|
||||
}
|
||||
IASTStatement elseStatement = statement();
|
||||
new_if_statement.setElseClause(elseStatement);
|
||||
elseStatement.setParent(new_if_statement);
|
||||
elseStatement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- ((ASTNode) if_statement).getOffset());
|
||||
} else {
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
} else {
|
||||
if( thenClause != null )
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(thenClause) - start);
|
||||
if (if_statement != null) {
|
||||
if_statement.setElseClause(new_if_statement);
|
||||
new_if_statement.setParent(if_statement);
|
||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||
((ASTNode) new_if_statement)
|
||||
.setLength(calculateEndOffset(new_if_statement)
|
||||
- start);
|
||||
}
|
||||
if (result == null && if_statement != null)
|
||||
result = if_statement;
|
||||
if (result == null)
|
||||
result = new_if_statement;
|
||||
|
||||
if_statement = new_if_statement;
|
||||
}
|
||||
break if_loop;
|
||||
}
|
||||
|
||||
reconcileLengths(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue