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

Refactored statement() to share more code between C/C++.

Added in ambiguity resolution code for expression statements vs. declarations statements.
This commit is contained in:
John Camelon 2004-11-26 16:09:44 +00:00
parent 7877aedb36
commit 21a1814cc5
4 changed files with 545 additions and 543 deletions

View file

@ -848,5 +848,27 @@ public class AST2Tests extends AST2BaseTest {
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d.getPointerOperators().get(0);
assertEquals( po.getName().toString(), "X::"); //$NON-NLS-1$
}
public void testAmbiguity() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { };\n"); //$NON-NLS-1$
buffer.append( "int f() { \n"); //$NON-NLS-1$
buffer.append( " A * b = 0;\n"); //$NON-NLS-1$
buffer.append( " A & c = 0;\n"); //$NON-NLS-1$
buffer.append( "}"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
IASTSimpleDeclaration A = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTFunctionDefinition f = (IASTFunctionDefinition) tu.getDeclarations()[1];
IASTCompoundStatement body = (IASTCompoundStatement) f.getBody();
for( int i = 0; i < 2; ++i )
{
IASTDeclarationStatement ds = (IASTDeclarationStatement) body.getStatements()[i];
String s1 = ((IASTNamedTypeSpecifier)((IASTSimpleDeclaration)ds.getDeclaration()).getDeclSpecifier()).getName().toString();
String s2 = ((IASTCompositeTypeSpecifier)A.getDeclSpecifier()).getName().toString();
assertEquals( s1, s2);
}
}
}

View file

@ -37,6 +37,8 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -1323,4 +1325,464 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*/
protected abstract IASTCastExpression createCastExpression();
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseDeclarationOrExpressionStatement() throws EndOfFileException, BacktrackException {
// expressionStatement
// Note: the function style cast ambiguity is handled in
// expression
// Since it only happens when we are in a statement
IToken mark = mark();
IASTExpressionStatement expressionStatement = null;
IToken lastTokenOfExpression = null;
BacktrackException savedBt = null;
try {
IASTExpression expression = expression();
lastTokenOfExpression = consume(IToken.tSEMI);
expressionStatement = createExpressionStatement();
expressionStatement.setExpression( expression );
expression.setParent( expressionStatement );
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
} catch (BacktrackException b) {
}
backup( mark );
// declarationStatement
IASTDeclarationStatement ds = null;
try
{
IASTDeclaration d = declaration();
ds = createDeclarationStatement();
ds.setDeclaration(d);
d.setParent( ds );
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
}
catch( BacktrackException b )
{
savedBt = b;
backup( mark );
}
if( expressionStatement == null && ds != null )
{
cleanupLastToken();
return ds;
}
if( expressionStatement != null && ds == null )
{
while( true )
{
if( consume() == lastTokenOfExpression )
break;
}
cleanupLastToken();
return expressionStatement;
}
if( expressionStatement == null && ds == null )
throwBacktrack(savedBt);
//resolve ambiguities
//A * B = C;
//A & B = C;
if( expressionStatement.getExpression() instanceof IASTBinaryExpression )
{
IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement.getExpression();
if( exp.getOperator() == IASTBinaryExpression.op_assign )
{
IASTExpression lhs = exp.getOperand1();
if( lhs instanceof IASTBinaryExpression && ((IASTBinaryExpression)lhs).getOperator() == IASTBinaryExpression.op_multiply )
{
cleanupLastToken();
return ds;
}
if( lhs instanceof IASTBinaryExpression && ((IASTBinaryExpression)lhs).getOperator() == IASTBinaryExpression.op_binaryAnd )
{
cleanupLastToken();
return ds;
}
}
}
if( ds.getDeclaration() instanceof IASTSimpleDeclaration &&
((IASTSimpleDeclaration)ds.getDeclaration()).getDeclSpecifier() instanceof IASTSimpleDeclSpecifier &&
((IASTSimpleDeclSpecifier)((IASTSimpleDeclaration)ds.getDeclaration()).getDeclSpecifier() ).getType() == IASTSimpleDeclSpecifier.t_unspecified)
{
backup( mark );
while( true )
{
if( consume() == lastTokenOfExpression )
break;
}
cleanupLastToken();
return expressionStatement;
}
backup( mark );
while( true )
{
if( consume() == lastTokenOfExpression )
break;
}
cleanupLastToken();
return expressionStatement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException {
IToken labelName = consume(IToken.tIDENTIFIER);
consume(IToken.tCOLON);
IASTLabelStatement label_statement = createLabelStatement();
((ASTNode)label_statement).setOffset( labelName.getOffset() );
IASTName name = createName( labelName );
label_statement.setName( name );
name.setParent( label_statement );
name.setPropertyInParent( IASTLabelStatement.NAME );
return label_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseNullStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.tSEMI ).getOffset();
cleanupLastToken();
IASTNullStatement null_statement = createNullStatement();
((ASTNode)null_statement).setOffset( startOffset );
return null_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_goto).getOffset();
IToken identifier = consume(IToken.tIDENTIFIER);
consume(IToken.tSEMI);
cleanupLastToken();
IASTName goto_label_name = createName( identifier );
IASTGotoStatement goto_statement = createGoToStatement();
((ASTNode)goto_statement).setOffset( startOffset );
goto_statement.setName( goto_label_name );
goto_label_name.setParent( goto_statement );
goto_label_name.setPropertyInParent( IASTGotoStatement.NAME );
return goto_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseBreakStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_break).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTBreakStatement break_statement = createBreakStatement();
((ASTNode)break_statement).setOffset( startOffset );
return break_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseContinueStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_continue).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTContinueStatement continue_statement = createContinueStatement();
((ASTNode)continue_statement).setOffset( startOffset );
return continue_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseReturnStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_return).getOffset();
IASTExpression result = null;
if (LT(1) != IToken.tSEMI) {
result = expression();
cleanupLastToken();
}
consume(IToken.tSEMI);
cleanupLastToken();
IASTReturnStatement return_statement = createReturnStatement();
((ASTNode)return_statement).setOffset( startOffset );
if( result != null )
{
return_statement.setReturnValue( result );
result.setParent( return_statement );
result.setPropertyInParent( IASTReturnStatement.RETURNVALUE );
}
return return_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume( IToken.t_for ).getOffset();
consume(IToken.tLPAREN);
IASTNode init = forInitStatement();
IASTExpression for_condition = null;
if (LT(1) != IToken.tSEMI)
for_condition = condition();
consume(IToken.tSEMI);
IASTExpression iterationExpression = null;
if (LT(1) != IToken.tRPAREN) {
iterationExpression = expression();
cleanupLastToken();
}
consume(IToken.tRPAREN);
IASTStatement for_body = statement();
cleanupLastToken();
IASTForStatement for_statement = createForStatement();
((ASTNode)for_statement).setOffset( startOffset );
if( init instanceof IASTDeclaration )
{
for_statement.setInit((IASTDeclaration) init);
((IASTDeclaration) init).setParent( for_statement );
((IASTDeclaration) init).setPropertyInParent( IASTForStatement.INITDECLARATION );
}
else if( init instanceof IASTExpression )
{
for_statement.setInit((IASTExpression) init);
((IASTExpression) init).setParent( for_statement );
((IASTExpression) init).setPropertyInParent( IASTForStatement.INITEXPRESSION );
}
if( for_condition != null )
{
for_statement.setCondition( for_condition );
for_condition.setParent( for_statement );
for_condition.setPropertyInParent( IASTForStatement.CONDITION );
}
if( iterationExpression != null )
{
for_statement.setIterationExpression( iterationExpression );
iterationExpression.setParent( for_statement );
iterationExpression.setPropertyInParent( IASTForStatement.ITERATION );
}
for_statement.setBody( for_body );
for_body.setParent( for_statement );
for_body.setPropertyInParent( IASTForStatement.BODY );
return for_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseDoStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_do).getOffset();
IASTStatement do_body = statement();
consume(IToken.t_while);
consume(IToken.tLPAREN);
IASTExpression do_condition = condition();
consume(IToken.tRPAREN);
cleanupLastToken();
IASTDoStatement do_statement = createDoStatement();
((ASTNode)do_statement).setOffset( startOffset );
do_statement.setBody( do_body );
do_body.setParent( do_statement );
do_body.setPropertyInParent( IASTDoStatement.BODY );
do_statement.setCondition( do_condition );
do_condition.setParent( do_statement );
do_condition.setPropertyInParent( IASTDoStatement.CONDITION );
return do_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseWhileStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN);
IASTExpression while_condition = condition();
consume(IToken.tRPAREN);
IASTStatement while_body = statement();
cleanupLastToken();
IASTWhileStatement while_statement = createWhileStatement();
((ASTNode)while_statement).setOffset( startOffset );
while_statement.setCondition( while_condition );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.CONDITION );
while_statement.setBody( while_body );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.BODY );
while_body.setParent( while_statement );
return while_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseSwitchStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume( IToken.t_switch ).getOffset();
consume(IToken.tLPAREN);
IASTExpression switch_condition = condition();
consume(IToken.tRPAREN);
IASTStatement switch_body = statement();
cleanupLastToken();
IASTSwitchStatement switch_statement = createSwitchStatement();
((ASTNode)switch_statement).setOffset( startOffset );
switch_statement.setController( switch_condition );
switch_condition.setParent( switch_statement );
switch_condition.setPropertyInParent( IASTSwitchStatement.CONTROLLER );
switch_statement.setBody( switch_body );
switch_body.setParent( switch_statement );
switch_body.setPropertyInParent( IASTSwitchStatement.BODY );
return switch_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException {
IASTIfStatement if_statement = null;
if_loop: while( true ){
int so = consume(IToken.t_if).getOffset();
consume(IToken.tLPAREN);
IToken start = LA(1);
boolean passedCondition = true;
IASTExpression condition = null;
try {
condition = condition();
consume(IToken.tRPAREN);
} catch (BacktrackException b) {
//if the problem has no offset info, make a new one that does
if( b.getProblem() != null && b.getProblem().getSourceLineNumber() == -1 ){
IProblem p = b.getProblem();
IProblem p2 = problemFactory.createProblem( p.getID(), start.getOffset(),
lastToken != null ? lastToken.getEndOffset() : start.getEndOffset(),
start.getLineNumber(), p.getOriginatingFileName(),
p.getArguments() != null ? p.getArguments().toCharArray() : null,
p.isWarning(), p.isError() );
b.initialize( p2 );
}
failParse(b);
failParseWithErrorHandling();
passedCondition = false;
}
IASTStatement thenClause = null;
if( passedCondition ){
thenClause = statement();
}
IASTIfStatement new_if_statement = createIfStatement();
((ASTNode)new_if_statement).setOffset( 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 );
}
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
cleanupLastToken();
if( if_statement != null )
{
if_statement.setElseClause( new_if_statement );
new_if_statement.setParent( if_statement );
new_if_statement.setPropertyInParent( IASTIfStatement.ELSE );
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_statement = new_if_statement;
}
else
if_statement = new_if_statement;
break if_loop;
}
cleanupLastToken();
return if_statement;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseCompoundStatement() throws EndOfFileException, BacktrackException {
IASTCompoundStatement compound = compoundStatement();
cleanupLastToken();
return compound;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseDefaultStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_default).getOffset();
consume(IToken.tCOLON);
cleanupLastToken();
IASTDefaultStatement df = createDefaultStatement();
((ASTNode)df).setOffset( startOffset );
return df;
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseCaseStatement() throws EndOfFileException, BacktrackException {
int startOffset = consume(IToken.t_case).getOffset();
IASTExpression case_exp = constantExpression();
consume(IToken.tCOLON);
cleanupLastToken();
IASTCaseStatement cs = createCaseStatement();
((ASTNode)cs).setOffset( startOffset );
cs.setExpression( case_exp );
case_exp.setParent( cs );
case_exp.setPropertyInParent( IASTCaseStatement.EXPRESSION );
return cs;
}
}

View file

@ -82,7 +82,6 @@ import org.eclipse.cdt.core.parser.BacktrackException;
import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IGCCToken;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ParseError;
@ -2058,290 +2057,46 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
protected IASTStatement statement() throws EndOfFileException, BacktrackException {
switch (LT(1)) {
// labeled statements
case IToken.t_case:
int startOffset = consume(IToken.t_case).getOffset();
IASTExpression case_exp = constantExpression();
consume(IToken.tCOLON);
cleanupLastToken();
IASTCaseStatement cs = createCaseStatement();
((ASTNode)cs).setOffset( startOffset );
cs.setExpression( case_exp );
case_exp.setParent( cs );
case_exp.setPropertyInParent( IASTCaseStatement.EXPRESSION );
return cs;
return parseCaseStatement();
case IToken.t_default:
startOffset = consume(IToken.t_default).getOffset();
consume(IToken.tCOLON);
cleanupLastToken();
IASTDefaultStatement df = createDefaultStatement();
((ASTNode)df).setOffset( startOffset );
return df;
return parseDefaultStatement();
// compound statement
case IToken.tLBRACE:
IASTCompoundStatement compound = compoundStatement();
cleanupLastToken();
return compound;
return parseCompoundStatement();
// selection statement
case IToken.t_if:
IASTIfStatement if_statement = null;
if_loop: while( true ){
int so = consume(IToken.t_if).getOffset();
consume(IToken.tLPAREN);
IToken start = LA(1);
boolean passedCondition = true;
IASTExpression condition = null;
try {
condition = condition();
consume(IToken.tRPAREN);
} catch (BacktrackException b) {
//if the problem has no offset info, make a new one that does
if( b.getProblem() != null && b.getProblem().getSourceLineNumber() == -1 ){
IProblem p = b.getProblem();
IProblem p2 = problemFactory.createProblem( p.getID(), start.getOffset(),
lastToken != null ? lastToken.getEndOffset() : start.getEndOffset(),
start.getLineNumber(), p.getOriginatingFileName(),
p.getArguments() != null ? p.getArguments().toCharArray() : null,
p.isWarning(), p.isError() );
b.initialize( p2 );
}
failParse(b);
failParseWithErrorHandling();
passedCondition = false;
}
IASTStatement thenClause = null;
if( passedCondition ){
thenClause = statement();
}
IASTIfStatement new_if_statement = createIfStatement();
((ASTNode)new_if_statement).setOffset( 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 );
}
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
cleanupLastToken();
if( if_statement != null )
{
if_statement.setElseClause( new_if_statement );
new_if_statement.setParent( if_statement );
new_if_statement.setPropertyInParent( IASTIfStatement.ELSE );
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_statement = new_if_statement;
}
else
if_statement = new_if_statement;
break if_loop;
}
cleanupLastToken();
return if_statement;
return parseIfStatement();
case IToken.t_switch:
startOffset = consume( IToken.t_switch ).getOffset();
consume(IToken.tLPAREN);
IASTExpression switch_condition = condition();
consume(IToken.tRPAREN);
IASTStatement switch_body = statement();
cleanupLastToken();
IASTSwitchStatement switch_statement = createSwitchStatement();
((ASTNode)switch_statement).setOffset( startOffset );
switch_statement.setController( switch_condition );
switch_condition.setParent( switch_statement );
switch_condition.setPropertyInParent( IASTSwitchStatement.CONTROLLER );
switch_statement.setBody( switch_body );
switch_body.setParent( switch_statement );
switch_body.setPropertyInParent( IASTSwitchStatement.BODY );
return switch_statement;
return parseSwitchStatement();
//iteration statements
case IToken.t_while:
startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN);
IASTExpression while_condition = condition();
consume(IToken.tRPAREN);
IASTStatement while_body = statement();
cleanupLastToken();
IASTWhileStatement while_statement = createWhileStatement();
((ASTNode)while_statement).setOffset( startOffset );
while_statement.setCondition( while_condition );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.CONDITION );
while_statement.setBody( while_body );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.BODY );
while_body.setParent( while_statement );
return while_statement;
return parseWhileStatement();
case IToken.t_do:
startOffset = consume(IToken.t_do).getOffset();
IASTStatement do_body = statement();
consume(IToken.t_while);
consume(IToken.tLPAREN);
IASTExpression do_condition = condition();
consume(IToken.tRPAREN);
cleanupLastToken();
IASTDoStatement do_statement = createDoStatement();
((ASTNode)do_statement).setOffset( startOffset );
do_statement.setBody( do_body );
do_body.setParent( do_statement );
do_body.setPropertyInParent( IASTDoStatement.BODY );
do_statement.setCondition( do_condition );
do_condition.setParent( do_statement );
do_condition.setPropertyInParent( IASTDoStatement.CONDITION );
return do_statement;
return parseDoStatement();
case IToken.t_for:
startOffset = consume( IToken.t_for ).getOffset();
consume(IToken.tLPAREN);
IASTNode init = forInitStatement();
IASTExpression for_condition = null;
if (LT(1) != IToken.tSEMI)
for_condition = condition();
consume(IToken.tSEMI);
IASTExpression iterationExpression = null;
if (LT(1) != IToken.tRPAREN) {
iterationExpression = expression();
cleanupLastToken();
}
consume(IToken.tRPAREN);
IASTStatement for_body = statement();
cleanupLastToken();
IASTForStatement for_statement = createForStatement();
((ASTNode)for_statement).setOffset( startOffset );
if( init instanceof IASTDeclaration )
{
for_statement.setInit((IASTDeclaration) init);
((IASTDeclaration) init).setParent( for_statement );
((IASTDeclaration) init).setPropertyInParent( IASTForStatement.INITDECLARATION );
}
else if( init instanceof IASTExpression )
{
for_statement.setInit((IASTExpression) init);
((IASTExpression) init).setParent( for_statement );
((IASTExpression) init).setPropertyInParent( IASTForStatement.INITEXPRESSION );
}
if( for_condition != null )
{
for_statement.setCondition( for_condition );
for_condition.setParent( for_statement );
for_condition.setPropertyInParent( IASTForStatement.CONDITION );
}
if( iterationExpression != null )
{
for_statement.setIterationExpression( iterationExpression );
iterationExpression.setParent( for_statement );
iterationExpression.setPropertyInParent( IASTForStatement.ITERATION );
}
for_statement.setBody( for_body );
for_body.setParent( for_statement );
for_body.setPropertyInParent( IASTForStatement.BODY );
return for_statement;
return parseForStatement();
//jump statement
case IToken.t_break:
startOffset = consume(IToken.t_break).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTBreakStatement break_statement = createBreakStatement();
((ASTNode)break_statement).setOffset( startOffset );
return break_statement;
return parseBreakStatement();
case IToken.t_continue:
startOffset = consume(IToken.t_continue).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTContinueStatement continue_statement = createContinueStatement();
((ASTNode)continue_statement).setOffset( startOffset );
return continue_statement;
return parseContinueStatement();
case IToken.t_return:
startOffset = consume(IToken.t_return).getOffset();
IASTExpression result = null;
if (LT(1) != IToken.tSEMI) {
result = expression();
cleanupLastToken();
}
consume(IToken.tSEMI);
cleanupLastToken();
IASTReturnStatement return_statement = createReturnStatement();
((ASTNode)return_statement).setOffset( startOffset );
if( result != null )
{
return_statement.setReturnValue( result );
result.setParent( return_statement );
result.setPropertyInParent( IASTReturnStatement.RETURNVALUE );
}
return return_statement;
return parseReturnStatement();
case IToken.t_goto:
startOffset = consume(IToken.t_goto).getOffset();
IToken identifier = consume(IToken.tIDENTIFIER);
consume(IToken.tSEMI);
cleanupLastToken();
IASTName goto_label_name = createName( identifier );
IASTGotoStatement goto_statement = createGoToStatement();
((ASTNode)goto_statement).setOffset( startOffset );
goto_statement.setName( goto_label_name );
goto_label_name.setParent( goto_statement );
goto_label_name.setPropertyInParent( IASTGotoStatement.NAME );
return goto_statement;
return parseGotoStatement();
case IToken.tSEMI:
startOffset = consume(IToken.tSEMI ).getOffset();
cleanupLastToken();
IASTNullStatement null_statement = createNullStatement();
((ASTNode)null_statement).setOffset( startOffset );
return null_statement;
return parseNullStatement();
default:
// can be many things:
// label
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
IToken labelName = consume(IToken.tIDENTIFIER);
consume(IToken.tCOLON);
IASTLabelStatement label_statement = createLabelStatement();
((ASTNode)label_statement).setOffset( labelName.getOffset() );
IASTName name = createName( labelName );
label_statement.setName( name );
name.setParent( label_statement );
name.setPropertyInParent( IASTLabelStatement.NAME );
return label_statement;
return parseLabelStatement();
}
// expressionStatement
// Note: the function style cast ambiguity is handled in
// expression
// Since it only happens when we are in a statement
IToken mark = mark();
try {
IASTExpression expression = expression();
consume(IToken.tSEMI);
IASTExpressionStatement expressionStatement = createExpressionStatement();
expressionStatement.setExpression( expression );
expression.setParent( expressionStatement );
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
cleanupLastToken();
return expressionStatement;
} catch (BacktrackException b) {
backup(mark);
}
// declarationStatement
IASTDeclaration d = declaration();
IASTDeclarationStatement ds = createDeclarationStatement();
ds.setDeclaration(d);
d.setParent( ds );
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
cleanupLastToken();
return ds;
return parseDeclarationOrExpressionStatement();
}
}

View file

@ -4412,310 +4412,73 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
switch (LT(1)) {
// labeled statements
case IToken.t_case:
int startOffset = consume(IToken.t_case).getOffset();
IASTExpression case_exp = constantExpression();
consume(IToken.tCOLON);
cleanupLastToken();
IASTCaseStatement cs = createCaseStatement();
((ASTNode)cs).setOffset( startOffset );
cs.setExpression( case_exp );
case_exp.setParent( cs );
case_exp.setPropertyInParent( IASTCaseStatement.EXPRESSION );
return cs;
return parseCaseStatement();
case IToken.t_default:
startOffset = consume(IToken.t_default).getOffset();
consume(IToken.tCOLON);
cleanupLastToken();
IASTDefaultStatement df = createDefaultStatement();
((ASTNode)df).setOffset( startOffset );
return df;
return parseDefaultStatement();
// compound statement
case IToken.tLBRACE:
IASTCompoundStatement compound = compoundStatement();
cleanupLastToken();
return compound;
return parseCompoundStatement();
// selection statement
case IToken.t_if:
IASTIfStatement if_statement = null;
if_loop: while( true ){
int so = consume(IToken.t_if).getOffset();
consume(IToken.tLPAREN);
IToken start = LA(1);
boolean passedCondition = true;
IASTExpression condition = null;
try {
condition = condition();
consume(IToken.tRPAREN);
} catch (BacktrackException b) {
//if the problem has no offset info, make a new one that does
if( b.getProblem() != null && b.getProblem().getSourceLineNumber() == -1 ){
IProblem p = b.getProblem();
IProblem p2 = problemFactory.createProblem( p.getID(), start.getOffset(),
lastToken != null ? lastToken.getEndOffset() : start.getEndOffset(),
start.getLineNumber(), p.getOriginatingFileName(),
p.getArguments() != null ? p.getArguments().toCharArray() : null,
p.isWarning(), p.isError() );
b.initialize( p2 );
}
failParse(b);
failParseWithErrorHandling();
passedCondition = false;
}
IASTStatement thenClause = null;
if( passedCondition ){
thenClause = statement();
}
IASTIfStatement new_if_statement = createIfStatement();
((ASTNode)new_if_statement).setOffset( 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 );
}
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
cleanupLastToken();
if( if_statement != null )
{
if_statement.setElseClause( new_if_statement );
new_if_statement.setParent( if_statement );
new_if_statement.setPropertyInParent( IASTIfStatement.ELSE );
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_statement = new_if_statement;
}
else
if_statement = new_if_statement;
break if_loop;
}
cleanupLastToken();
return if_statement;
case IToken.t_switch:
startOffset = consume( IToken.t_switch ).getOffset();
consume(IToken.tLPAREN);
IASTExpression switch_condition = condition();
consume(IToken.tRPAREN);
IASTStatement switch_body = statement();
cleanupLastToken();
IASTSwitchStatement switch_statement = createSwitchStatement();
((ASTNode)switch_statement).setOffset( startOffset );
switch_statement.setController( switch_condition );
switch_condition.setParent( switch_statement );
switch_condition.setPropertyInParent( IASTSwitchStatement.CONTROLLER );
switch_statement.setBody( switch_body );
switch_body.setParent( switch_statement );
switch_body.setPropertyInParent( IASTSwitchStatement.BODY );
return switch_statement;
return parseIfStatement();
case IToken.t_switch:
return parseSwitchStatement();
//iteration statements
case IToken.t_while:
startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN);
IASTExpression while_condition = condition();
consume(IToken.tRPAREN);
IASTStatement while_body = statement();
cleanupLastToken();
IASTWhileStatement while_statement = createWhileStatement();
((ASTNode)while_statement).setOffset( startOffset );
while_statement.setCondition( while_condition );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.CONDITION );
while_statement.setBody( while_body );
while_condition.setParent( while_statement );
while_condition.setPropertyInParent( IASTWhileStatement.BODY );
while_body.setParent( while_statement );
return while_statement;
return parseWhileStatement();
case IToken.t_do:
startOffset = consume(IToken.t_do).getOffset();
IASTStatement do_body = statement();
consume(IToken.t_while);
consume(IToken.tLPAREN);
IASTExpression do_condition = condition();
consume(IToken.tRPAREN);
cleanupLastToken();
IASTDoStatement do_statement = createDoStatement();
((ASTNode)do_statement).setOffset( startOffset );
do_statement.setBody( do_body );
do_body.setParent( do_statement );
do_body.setPropertyInParent( IASTDoStatement.BODY );
do_statement.setCondition( do_condition );
do_condition.setParent( do_statement );
do_condition.setPropertyInParent( IASTDoStatement.CONDITION );
return do_statement;
return parseDoStatement();
case IToken.t_for:
startOffset = consume( IToken.t_for ).getOffset();
consume(IToken.tLPAREN);
IASTNode init = forInitStatement();
IASTExpression for_condition = null;
if (LT(1) != IToken.tSEMI)
for_condition = condition();
consume(IToken.tSEMI);
IASTExpression iterationExpression = null;
if (LT(1) != IToken.tRPAREN) {
iterationExpression = expression();
cleanupLastToken();
}
consume(IToken.tRPAREN);
IASTStatement for_body = statement();
cleanupLastToken();
IASTForStatement for_statement = createForStatement();
((ASTNode)for_statement).setOffset( startOffset );
if( init instanceof IASTDeclaration )
{
for_statement.setInit((IASTDeclaration) init);
((IASTDeclaration) init).setParent( for_statement );
((IASTDeclaration) init).setPropertyInParent( IASTForStatement.INITDECLARATION );
}
else if( init instanceof IASTExpression )
{
for_statement.setInit((IASTExpression) init);
((IASTExpression) init).setParent( for_statement );
((IASTExpression) init).setPropertyInParent( IASTForStatement.INITEXPRESSION );
}
if( for_condition != null )
{
for_statement.setCondition( for_condition );
for_condition.setParent( for_statement );
for_condition.setPropertyInParent( IASTForStatement.CONDITION );
}
if( iterationExpression != null )
{
for_statement.setIterationExpression( iterationExpression );
iterationExpression.setParent( for_statement );
iterationExpression.setPropertyInParent( IASTForStatement.ITERATION );
}
for_statement.setBody( for_body );
for_body.setParent( for_statement );
for_body.setPropertyInParent( IASTForStatement.BODY );
return for_statement;
return parseForStatement();
//jump statement
case IToken.t_break:
startOffset = consume(IToken.t_break).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTBreakStatement break_statement = createBreakStatement();
((ASTNode)break_statement).setOffset( startOffset );
return break_statement;
return parseBreakStatement();
case IToken.t_continue:
startOffset = consume(IToken.t_continue).getOffset();
consume(IToken.tSEMI);
cleanupLastToken();
IASTContinueStatement continue_statement = createContinueStatement();
((ASTNode)continue_statement).setOffset( startOffset );
return continue_statement;
return parseContinueStatement();
case IToken.t_return:
startOffset = consume(IToken.t_return).getOffset();
IASTExpression result = null;
if (LT(1) != IToken.tSEMI) {
result = expression();
cleanupLastToken();
}
consume(IToken.tSEMI);
cleanupLastToken();
IASTReturnStatement return_statement = createReturnStatement();
((ASTNode)return_statement).setOffset( startOffset );
if( result != null )
{
return_statement.setReturnValue( result );
result.setParent( return_statement );
result.setPropertyInParent( IASTReturnStatement.RETURNVALUE );
}
return return_statement;
return parseReturnStatement();
case IToken.t_goto:
startOffset = consume(IToken.t_goto).getOffset();
IToken identifier = consume(IToken.tIDENTIFIER);
consume(IToken.tSEMI);
cleanupLastToken();
IASTName goto_label_name = createName( identifier );
IASTGotoStatement goto_statement = createGoToStatement();
((ASTNode)goto_statement).setOffset( startOffset );
goto_statement.setName( goto_label_name );
goto_label_name.setParent( goto_statement );
goto_label_name.setPropertyInParent( IASTGotoStatement.NAME );
return goto_statement;
return parseGotoStatement();
case IToken.tSEMI:
startOffset = consume(IToken.tSEMI ).getOffset();
cleanupLastToken();
IASTNullStatement null_statement = createNullStatement();
((ASTNode)null_statement).setOffset( startOffset );
cleanupLastToken();
return null_statement;
return parseNullStatement();
case IToken.t_try :
int startO = consume().getOffset();
IASTStatement tryBlock = compoundStatement();
List catchHandlers = new ArrayList( DEFAULT_CATCH_HANDLER_LIST_SIZE );
catchHandlerSequence(catchHandlers);
cleanupLastToken();
ICPPASTTryBlockStatement tryStatement = createTryBlockStatement();
((ASTNode)tryStatement).setOffset( startO );
tryStatement.setTryBody( tryBlock );
tryBlock.setParent( tryStatement );
tryBlock.setPropertyInParent( ICPPASTTryBlockStatement.BODY );
for( int i = 0; i < catchHandlers.size(); ++i )
{
ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers.get(i);
tryStatement.addCatchHandler( handler );
handler.setParent( tryStatement );
handler.setPropertyInParent( ICPPASTTryBlockStatement.CATCH_HANDLER );
}
return tryStatement;
return parseTryStatement();
default:
// can be many things:
// label
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
IToken labelName = consume(IToken.tIDENTIFIER);
consume(IToken.tCOLON);
IASTLabelStatement label_statement = createLabelStatement();
((ASTNode)label_statement).setOffset( labelName.getOffset() );
IASTName name = createName( labelName );
label_statement.setName( name );
name.setParent( label_statement );
name.setPropertyInParent( IASTLabelStatement.NAME );
return label_statement;
return parseLabelStatement();
}
// expressionStatement
// Note: the function style cast ambiguity is handled in
// expression
// Since it only happens when we are in a statement
IToken mark = mark();
try {
IASTExpression expression = expression();
consume(IToken.tSEMI);
IASTExpressionStatement expressionStatement = createExpressionStatement();
expressionStatement.setExpression( expression );
expression.setParent( expressionStatement );
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
cleanupLastToken();
return expressionStatement;
} catch (BacktrackException b) {
backup(mark);
}
// declarationStatement
IASTDeclaration d = declaration();
IASTDeclarationStatement ds = createDeclarationStatement();
ds.setDeclaration(d);
d.setParent( ds );
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
cleanupLastToken();
return ds;
return parseDeclarationOrExpressionStatement();
}
}
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseTryStatement() throws EndOfFileException, BacktrackException {
int startO = consume().getOffset();
IASTStatement tryBlock = compoundStatement();
List catchHandlers = new ArrayList( DEFAULT_CATCH_HANDLER_LIST_SIZE );
catchHandlerSequence(catchHandlers);
cleanupLastToken();
ICPPASTTryBlockStatement tryStatement = createTryBlockStatement();
((ASTNode)tryStatement).setOffset( startO );
tryStatement.setTryBody( tryBlock );
tryBlock.setParent( tryStatement );
tryBlock.setPropertyInParent( ICPPASTTryBlockStatement.BODY );
for( int i = 0; i < catchHandlers.size(); ++i )
{
ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers.get(i);
tryStatement.addCatchHandler( handler );
handler.setParent( tryStatement );
handler.setPropertyInParent( ICPPASTTryBlockStatement.CATCH_HANDLER );
}
return tryStatement;
}
/**