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:
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);
|
||||
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.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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue