mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 16:56:04 +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:
parent
7877aedb36
commit
21a1814cc5
4 changed files with 545 additions and 543 deletions
|
@ -848,5 +848,27 @@ public class AST2Tests extends AST2BaseTest {
|
||||||
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d.getPointerOperators().get(0);
|
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d.getPointerOperators().get(0);
|
||||||
assertEquals( po.getName().toString(), "X::"); //$NON-NLS-1$
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
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.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
@ -1323,4 +1325,464 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
*/
|
*/
|
||||||
protected abstract IASTCastExpression createCastExpression();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -82,7 +82,6 @@ import org.eclipse.cdt.core.parser.BacktrackException;
|
||||||
import org.eclipse.cdt.core.parser.EndOfFileException;
|
import org.eclipse.cdt.core.parser.EndOfFileException;
|
||||||
import org.eclipse.cdt.core.parser.IGCCToken;
|
import org.eclipse.cdt.core.parser.IGCCToken;
|
||||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
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.IScanner;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
import org.eclipse.cdt.core.parser.ParseError;
|
import org.eclipse.cdt.core.parser.ParseError;
|
||||||
|
@ -2058,290 +2057,46 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IASTStatement statement() throws EndOfFileException, BacktrackException {
|
protected IASTStatement statement() throws EndOfFileException, BacktrackException {
|
||||||
|
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
// labeled statements
|
// labeled statements
|
||||||
case IToken.t_case:
|
case IToken.t_case:
|
||||||
int startOffset = consume(IToken.t_case).getOffset();
|
return parseCaseStatement();
|
||||||
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;
|
|
||||||
case IToken.t_default:
|
case IToken.t_default:
|
||||||
startOffset = consume(IToken.t_default).getOffset();
|
return parseDefaultStatement();
|
||||||
consume(IToken.tCOLON);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTDefaultStatement df = createDefaultStatement();
|
|
||||||
((ASTNode)df).setOffset( startOffset );
|
|
||||||
return df;
|
|
||||||
// compound statement
|
// compound statement
|
||||||
case IToken.tLBRACE:
|
case IToken.tLBRACE:
|
||||||
IASTCompoundStatement compound = compoundStatement();
|
return parseCompoundStatement();
|
||||||
cleanupLastToken();
|
|
||||||
return compound;
|
|
||||||
// selection statement
|
// selection statement
|
||||||
case IToken.t_if:
|
case IToken.t_if:
|
||||||
IASTIfStatement if_statement = null;
|
return parseIfStatement();
|
||||||
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:
|
case IToken.t_switch:
|
||||||
startOffset = consume( IToken.t_switch ).getOffset();
|
return parseSwitchStatement();
|
||||||
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;
|
|
||||||
//iteration statements
|
//iteration statements
|
||||||
case IToken.t_while:
|
case IToken.t_while:
|
||||||
startOffset = consume(IToken.t_while).getOffset();
|
return parseWhileStatement();
|
||||||
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;
|
|
||||||
case IToken.t_do:
|
case IToken.t_do:
|
||||||
startOffset = consume(IToken.t_do).getOffset();
|
return parseDoStatement();
|
||||||
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;
|
|
||||||
case IToken.t_for:
|
case IToken.t_for:
|
||||||
startOffset = consume( IToken.t_for ).getOffset();
|
return parseForStatement();
|
||||||
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;
|
|
||||||
//jump statement
|
//jump statement
|
||||||
case IToken.t_break:
|
case IToken.t_break:
|
||||||
startOffset = consume(IToken.t_break).getOffset();
|
return parseBreakStatement();
|
||||||
consume(IToken.tSEMI);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTBreakStatement break_statement = createBreakStatement();
|
|
||||||
((ASTNode)break_statement).setOffset( startOffset );
|
|
||||||
return break_statement;
|
|
||||||
case IToken.t_continue:
|
case IToken.t_continue:
|
||||||
startOffset = consume(IToken.t_continue).getOffset();
|
return parseContinueStatement();
|
||||||
consume(IToken.tSEMI);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTContinueStatement continue_statement = createContinueStatement();
|
|
||||||
((ASTNode)continue_statement).setOffset( startOffset );
|
|
||||||
return continue_statement;
|
|
||||||
case IToken.t_return:
|
case IToken.t_return:
|
||||||
startOffset = consume(IToken.t_return).getOffset();
|
return parseReturnStatement();
|
||||||
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;
|
|
||||||
case IToken.t_goto:
|
case IToken.t_goto:
|
||||||
startOffset = consume(IToken.t_goto).getOffset();
|
return parseGotoStatement();
|
||||||
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;
|
|
||||||
case IToken.tSEMI:
|
case IToken.tSEMI:
|
||||||
startOffset = consume(IToken.tSEMI ).getOffset();
|
return parseNullStatement();
|
||||||
cleanupLastToken();
|
|
||||||
IASTNullStatement null_statement = createNullStatement();
|
|
||||||
((ASTNode)null_statement).setOffset( startOffset );
|
|
||||||
return null_statement;
|
|
||||||
default:
|
default:
|
||||||
// can be many things:
|
// can be many things:
|
||||||
// label
|
// label
|
||||||
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
|
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
|
||||||
IToken labelName = consume(IToken.tIDENTIFIER);
|
return parseLabelStatement();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
// expressionStatement
|
|
||||||
// Note: the function style cast ambiguity is handled in
|
return parseDeclarationOrExpressionStatement();
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4412,310 +4412,73 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
// labeled statements
|
// labeled statements
|
||||||
case IToken.t_case:
|
case IToken.t_case:
|
||||||
int startOffset = consume(IToken.t_case).getOffset();
|
return parseCaseStatement();
|
||||||
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;
|
|
||||||
case IToken.t_default:
|
case IToken.t_default:
|
||||||
startOffset = consume(IToken.t_default).getOffset();
|
return parseDefaultStatement();
|
||||||
consume(IToken.tCOLON);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTDefaultStatement df = createDefaultStatement();
|
|
||||||
((ASTNode)df).setOffset( startOffset );
|
|
||||||
return df;
|
|
||||||
// compound statement
|
// compound statement
|
||||||
case IToken.tLBRACE:
|
case IToken.tLBRACE:
|
||||||
IASTCompoundStatement compound = compoundStatement();
|
return parseCompoundStatement();
|
||||||
cleanupLastToken();
|
|
||||||
return compound;
|
|
||||||
// selection statement
|
// selection statement
|
||||||
case IToken.t_if:
|
case IToken.t_if:
|
||||||
IASTIfStatement if_statement = null;
|
return parseIfStatement();
|
||||||
if_loop: while( true ){
|
case IToken.t_switch:
|
||||||
int so = consume(IToken.t_if).getOffset();
|
return parseSwitchStatement();
|
||||||
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;
|
|
||||||
//iteration statements
|
//iteration statements
|
||||||
case IToken.t_while:
|
case IToken.t_while:
|
||||||
startOffset = consume(IToken.t_while).getOffset();
|
return parseWhileStatement();
|
||||||
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;
|
|
||||||
case IToken.t_do:
|
case IToken.t_do:
|
||||||
startOffset = consume(IToken.t_do).getOffset();
|
return parseDoStatement();
|
||||||
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;
|
|
||||||
case IToken.t_for:
|
case IToken.t_for:
|
||||||
startOffset = consume( IToken.t_for ).getOffset();
|
return parseForStatement();
|
||||||
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;
|
|
||||||
//jump statement
|
//jump statement
|
||||||
case IToken.t_break:
|
case IToken.t_break:
|
||||||
startOffset = consume(IToken.t_break).getOffset();
|
return parseBreakStatement();
|
||||||
consume(IToken.tSEMI);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTBreakStatement break_statement = createBreakStatement();
|
|
||||||
((ASTNode)break_statement).setOffset( startOffset );
|
|
||||||
return break_statement;
|
|
||||||
case IToken.t_continue:
|
case IToken.t_continue:
|
||||||
startOffset = consume(IToken.t_continue).getOffset();
|
return parseContinueStatement();
|
||||||
consume(IToken.tSEMI);
|
|
||||||
cleanupLastToken();
|
|
||||||
IASTContinueStatement continue_statement = createContinueStatement();
|
|
||||||
((ASTNode)continue_statement).setOffset( startOffset );
|
|
||||||
return continue_statement;
|
|
||||||
case IToken.t_return:
|
case IToken.t_return:
|
||||||
startOffset = consume(IToken.t_return).getOffset();
|
return parseReturnStatement();
|
||||||
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;
|
|
||||||
case IToken.t_goto:
|
case IToken.t_goto:
|
||||||
startOffset = consume(IToken.t_goto).getOffset();
|
return parseGotoStatement();
|
||||||
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;
|
|
||||||
case IToken.tSEMI:
|
case IToken.tSEMI:
|
||||||
startOffset = consume(IToken.tSEMI ).getOffset();
|
return parseNullStatement();
|
||||||
cleanupLastToken();
|
|
||||||
IASTNullStatement null_statement = createNullStatement();
|
|
||||||
((ASTNode)null_statement).setOffset( startOffset );
|
|
||||||
cleanupLastToken();
|
|
||||||
return null_statement;
|
|
||||||
case IToken.t_try :
|
case IToken.t_try :
|
||||||
int startO = consume().getOffset();
|
return parseTryStatement();
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// can be many things:
|
// can be many things:
|
||||||
// label
|
// label
|
||||||
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
|
if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
|
||||||
IToken labelName = consume(IToken.tIDENTIFIER);
|
return parseLabelStatement();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
// expressionStatement
|
|
||||||
// Note: the function style cast ambiguity is handled in
|
return parseDeclarationOrExpressionStatement();
|
||||||
// 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
|
||||||
|
* @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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue