diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java index 3c027940154..e61b4a3852f 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java @@ -114,13 +114,17 @@ public class DOMBuilder implements IParserCallback /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionOperator(org.eclipse.cdt.internal.core.newparser.Token) */ - public void expressionOperator(Token operator) throws Exception { + public void expressionOperator(Object expression, Token operator) throws Exception { + Expression e = (Expression)expression; + e.add( operator ); } /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionTerminal(org.eclipse.cdt.internal.core.newparser.Token) */ - public void expressionTerminal(Token terminal) throws Exception { + public void expressionTerminal(Object expression, Token terminal) throws Exception { + Expression e = (Expression)expression; + e.add( terminal ); } /** @@ -268,7 +272,10 @@ public class DOMBuilder implements IParserCallback * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionBegin(java.lang.Object) */ public Object expressionBegin(Object container) { - return null; + IExpressionOwner owner = (IExpressionOwner)container; + Expression expression = new Expression(); + owner.setExpression(expression); + return expression; } /** * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionEnd(java.lang.Object) @@ -329,4 +336,10 @@ public class DOMBuilder implements IParserCallback public void simpleDeclSpecifierName(Object declaration) { } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionAbort(java.lang.Object) + */ + public void expressionAbort(Object expression) { + } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Declarator.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Declarator.java index 8cc5c61a6df..f2db2ad9f08 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Declarator.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Declarator.java @@ -4,7 +4,7 @@ import org.eclipse.cdt.internal.core.parser.util.DeclSpecifier; import org.eclipse.cdt.internal.core.parser.util.Name; -public class Declarator { +public class Declarator implements IExpressionOwner { public Declarator(DeclSpecifier.Container declaration) { this.declaration = declaration; @@ -61,4 +61,20 @@ public class Declarator { return parms; } + private Expression expression = null; + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IExpressionOwner#getExpression() + */ + public Expression getExpression() { + return expression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IExpressionOwner#setExpression(org.eclipse.cdt.internal.core.dom.Expression) + */ + public void setExpression(Expression exp) { + expression = exp; + } + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Expression.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Expression.java new file mode 100644 index 00000000000..cc201b383df --- /dev/null +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/Expression.java @@ -0,0 +1,39 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: John Camelon + * Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.internal.core.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.internal.core.parser.Token; + +/** + * @author jcamelon + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Expression { + + private List tokens = new ArrayList(); + + public void add( Token t ) + { + tokens.add( t ); + } + + public List tokens() + { + return tokens; + } + +} diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IExpressionOwner.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IExpressionOwner.java new file mode 100644 index 00000000000..39f1f6e58db --- /dev/null +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IExpressionOwner.java @@ -0,0 +1,18 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * Rational Software - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.core.dom; + +public interface IExpressionOwner { + + public Expression getExpression(); + public void setExpression( Expression exp ); +} diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index 9c8a18dac7c..ee6e1c4350b 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -1,3 +1,8 @@ +2003-03-19 John Camelon + Updated Parser method visibility to solidify external interface. + Solved and removed TODO's from Scanner implementation. + Updated Parser and callbacks to handle basic expressions. + 2003-03-18 John Camelon Updated IParserCallback (and implementations) to add a typeName to DeclSpecifier. Updated IParserCallback and NewModelBuilder to distinguish between Function declarations and definitions. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/NewModelBuilder.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/NewModelBuilder.java index 15ced840d11..7d0635daefd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/NewModelBuilder.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/NewModelBuilder.java @@ -242,13 +242,13 @@ org.eclipse.cdt.internal.core.newparser.IParserCallback#beginSimpleDeclaration(T /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionOperator(org.eclipse.cdt.internal.core.newparser.Token) */ - public void expressionOperator(Token operator) throws Exception { + public void expressionOperator(Object expression, Token operator) throws Exception { } /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionTerminal(org.eclipse.cdt.internal.core.newparser.Token) */ - public void expressionTerminal(Token terminal) throws Exception { + public void expressionTerminal(Object expression, Token terminal) throws Exception { } /** @@ -358,4 +358,12 @@ org.eclipse.cdt.internal.core.newparser.IParserCallback#beginSimpleDeclaration(T declSpecifier.setName( currName ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionAbort(java.lang.Object) + */ + public void expressionAbort(Object expression) { + // TODO Auto-generated method stub + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java index 8e3a35e648d..c00c56731d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java @@ -30,7 +30,7 @@ public class ExpressionEvaluator implements IParserCallback { /** * @see org.eclipse.cdt.core.newparser.IParserCallback#expressionOperator(Token) */ - public void expressionOperator(Token operator) throws Exception { + public void expressionOperator(Object expression, Token operator) throws Exception { int second = popInt(); int first; @@ -95,7 +95,7 @@ public class ExpressionEvaluator implements IParserCallback { /** * @see org.eclipse.cdt.core.newparser.IParserCallback#expressionTerminal(Token) */ - public void expressionTerminal(Token terminal) throws Exception { + public void expressionTerminal(Object expression, Token terminal) throws Exception { switch (terminal.getType()) { case Token.tINTEGER: stack.push(new Integer(terminal.getImage())); @@ -306,4 +306,12 @@ public class ExpressionEvaluator implements IParserCallback { public void simpleDeclSpecifierName(Object declaration) { } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionAbort(java.lang.Object) + */ + public void expressionAbort(Object expression) { + // TODO Auto-generated method stub + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java index 4096f745ccb..d9607a6c459 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java @@ -54,8 +54,9 @@ public interface IParserCallback { public void baseSpecifierEnd( Object baseSpecifier ); public Object expressionBegin( Object container ); - public void expressionOperator(Token operator) throws Exception; - public void expressionTerminal(Token terminal) throws Exception; + public void expressionOperator(Object expression, Token operator) throws Exception; + public void expressionTerminal(Object expression, Token terminal) throws Exception; + public void expressionAbort( Object expression ); public void expressionEnd(Object expression ); public Object elaboratedTypeSpecifierBegin( Object container, Token classKey ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java index feef546ca8e..3a38213db91 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java @@ -105,13 +105,13 @@ public class NullParserCallback implements IParserCallback { /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionOperator(Token) */ - public void expressionOperator(Token operator) throws Exception { + public void expressionOperator(Object expression, Token operator) throws Exception { } /** * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#expressionTerminal(Token) */ - public void expressionTerminal(Token terminal) throws Exception { + public void expressionTerminal(Object expression, Token terminal) throws Exception { } /** @@ -222,4 +222,12 @@ public class NullParserCallback implements IParserCallback { public void simpleDeclSpecifierName(Object declaration) { } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#expressionAbort(java.lang.Object) + */ + public void expressionAbort(Object expression) { + // TODO Auto-generated method stub + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index f269dcea536..b471ab134e6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -74,7 +74,7 @@ c, quick); * : (declaration)* * */ - public void translationUnit() throws Exception { + protected void translationUnit() throws Exception { Object translationUnit = callback.translationUnitBegin(); Token lastBacktrack = null; Token lastToken; @@ -130,7 +130,7 @@ c, quick); * - explicitInstantiation and explicitSpecialization into * templateDeclaration */ - public void declaration( Object container ) throws Exception { + protected void declaration( Object container ) throws Exception { switch (LT(1)) { case Token.t_asm: // asmDefinition( ); @@ -176,7 +176,7 @@ c, quick); * To do: * - work in ctorInitializer and functionTryBlock */ - public void simpleDeclaration( Object container ) throws Exception { + protected void simpleDeclaration( Object container ) throws Exception { Object simpleDecl = callback.simpleDeclarationBegin( container); declSpecifierSeq(simpleDecl, false); @@ -239,7 +239,7 @@ c, quick); } - public void parameterDeclaration( Object containerObject ) throws Exception + protected void parameterDeclaration( Object containerObject ) throws Exception { Object parameterDecl = callback.parameterDeclarationBegin( containerObject ); declSpecifierSeq( parameterDecl, true ); @@ -273,7 +273,7 @@ c, quick); * - folded elaboratedTypeSpecifier into classSpecifier and enumSpecifier * - find template names in name */ - public void declSpecifierSeq( Object decl, boolean parm ) throws Exception { + protected void declSpecifierSeq( Object decl, boolean parm ) throws Exception { boolean encounteredTypename = false; boolean encounteredRawType = false; declSpecifiers: @@ -366,7 +366,7 @@ c, quick); * - Handle template ids * - Handle unqualifiedId */ - public boolean name() throws Exception { + protected boolean name() throws Exception { Token first = LA(1); Token last = null; @@ -408,7 +408,7 @@ c, quick); * cvQualifier * : "const" | "volatile" */ - public Object cvQualifier() throws Exception { + protected Object cvQualifier() throws Exception { switch (LT(1)) { case Token.t_const: case Token.t_volatile: @@ -426,7 +426,7 @@ c, quick); * To Do: * - handle initializers */ - public void initDeclarator( Object owner ) throws Exception { + protected void initDeclarator( Object owner ) throws Exception { Object declarator = declarator( owner ); // handle = initializerClause @@ -434,13 +434,17 @@ c, quick); consume(); // assignmentExpression || { initializerList , } || { } + Object expression = null; try { - assignmentExpression(); + expression = callback.expressionBegin( declarator ); + assignmentExpression( expression ); + callback.expressionEnd( expression ); } catch( Backtrack b ) { - // doNothing + if( expression != null ) + callback.expressionAbort( expression ); } if (LT(1) == Token.tLBRACE) { @@ -463,7 +467,18 @@ c, quick); { consume(); // EAT IT! - constantExpression(); + Object expression = null; + try + { + expression = callback.expressionBegin( declarator ); + constantExpression( expression ); + callback.expressionEnd( expression ); + } + catch( Backtrack b ) + { + if( expression != null ) + callback.expressionAbort( expression ); + } if( LT(1) == Token.tRPAREN ) consume(); @@ -487,7 +502,7 @@ c, quick); * declaratorId * : name */ - public Object declarator( Object container ) throws Exception { + protected Object declarator( Object container ) throws Exception { do { @@ -569,7 +584,7 @@ c, quick); * | "&" * | name "*" (cvQualifier)* */ - public Object ptrOperator() throws Exception { + protected Object ptrOperator() throws Exception { int t = LT(1); if (t == Token.tAMPER) { @@ -604,7 +619,7 @@ c, quick); * enumSpecifier * "enum" (name)? "{" (enumerator-list) "}" */ - public void enumSpecifier( Object owner ) throws Exception + protected void enumSpecifier( Object owner ) throws Exception { if( LT(1) != Token.t_enum ) throw backtrack; @@ -640,7 +655,7 @@ c, quick); * classSpecifier * : classKey name (baseClause)? "{" (memberSpecification)* "}" */ - public void classSpecifier( Object owner ) throws Exception { + protected void classSpecifier( Object owner ) throws Exception { Token classKey = null; Token mark = mark(); @@ -717,7 +732,7 @@ c, quick); callback.classSpecifierEnd(classSpec); } - public void baseSpecifier( Object classSpecOwner ) throws Exception { + protected void baseSpecifier( Object classSpecOwner ) throws Exception { Object baseSpecifier = callback.baseSpecifierBegin( classSpecOwner ); @@ -751,16 +766,19 @@ c, quick); callback.baseSpecifierEnd( baseSpecifier ); } - public void functionBody() throws Exception { + protected void functionBody() throws Exception { compoundStatement(); } // Statements - public void statement() throws Exception { + protected void statement() throws Exception { + Object expression = null; switch (LT(1)) { case Token.t_case: consume(); - constantExpression(); + expression = callback.expressionBegin( null ); //TODO regarding this null + constantExpression(expression); + callback.expressionEnd( expression ); consume(Token.tCOLON); statement(); return; @@ -813,7 +831,11 @@ c, quick); condition(); consume(Token.tSEMI); if (LT(1) != Token.tRPAREN) - expression(); + { + expression = callback.expressionBegin( null ); //TODO get rid of NULL + expression(expression); + callback.expressionEnd( expression ); + } consume(Token.tRPAREN); statement(); return; @@ -828,7 +850,11 @@ c, quick); case Token.t_return: consume(); if (LT(1) != Token.tSEMI) - expression(); + { + expression = callback.expressionBegin( null ); //TODO get rid of NULL + expression(expression); + callback.expressionEnd( expression ); + } consume(Token.tSEMI); return; case Token.t_goto: @@ -864,7 +890,9 @@ c, quick); // Note: the function style cast ambiguity is handled in expression // Since it only happens when we are in a statement try { - expression(); + expression = callback.expressionBegin( null ); //TODO get rid of NULL + expression(expression); + callback.expressionEnd( expression ); consume(Token.tSEMI); return; } catch (Backtrack b) { @@ -875,15 +903,15 @@ c, quick); } } - public void condition() throws Exception { + protected void condition() throws Exception { // TO DO } - public void forInitStatement() throws Exception { + protected void forInitStatement() throws Exception { // TO DO } - public void compoundStatement() throws Exception { + protected void compoundStatement() throws Exception { consume(Token.tLBRACE); while (LT(1) != Token.tRBRACE) statement(); @@ -891,28 +919,28 @@ c, quick); } // Expressions - public void constantExpression() throws Exception { - conditionalExpression(); + protected void constantExpression( Object expression ) throws Exception { + conditionalExpression( expression ); } - public void expression() throws Exception { - assignmentExpression(); + public void expression( Object expression ) throws Exception { + assignmentExpression( expression ); while (LT(1) == Token.tCOMMA) { Token t = consume(); - assignmentExpression(); - callback.expressionOperator(t); + assignmentExpression( expression ); + callback.expressionOperator(expression, t); } } - public void assignmentExpression() throws Exception { + protected void assignmentExpression( Object expression ) throws Exception { if (LT(1) == Token.t_throw) { - throwExpression(); + throwExpression(expression); return; } // if the condition not taken, try assignment operators - if (!conditionalExpression()) { + if (!conditionalExpression(expression)) { switch (LT(1)) { case Token.tASSIGN: case Token.tSTARASSIGN: @@ -926,95 +954,95 @@ c, quick); case Token.tXORASSIGN: case Token.tBITORASSIGN: Token t = consume(); - conditionalExpression(); - callback.expressionOperator(t); + conditionalExpression(expression); + callback.expressionOperator(expression, t); break; } } } - public void throwExpression() throws Exception { + protected void throwExpression( Object expression ) throws Exception { consume(Token.t_throw); try { - expression(); + expression(expression); } catch (Backtrack b) { } } - public boolean conditionalExpression() throws Exception { - logicalOrExpression(); + protected boolean conditionalExpression( Object expression ) throws Exception { + logicalOrExpression( expression ); if (LT(1) == Token.tQUESTION) { consume(); - expression(); + expression(expression); consume(Token.tCOLON); - assignmentExpression(); + assignmentExpression(expression); return true; } else return false; } - public void logicalOrExpression() throws Exception { - logicalAndExpression(); + protected void logicalOrExpression( Object expression ) throws Exception { + logicalAndExpression( expression ); while (LT(1) == Token.tOR) { Token t = consume(); - logicalAndExpression(); - callback.expressionOperator(t); + logicalAndExpression( expression ); + callback.expressionOperator(expression, t); } } - public void logicalAndExpression() throws Exception { - inclusiveOrExpression(); + protected void logicalAndExpression( Object expression ) throws Exception { + inclusiveOrExpression( expression ); while (LT(1) == Token.tAND) { Token t = consume(); - inclusiveOrExpression(); - callback.expressionOperator(t); + inclusiveOrExpression(expression ); + callback.expressionOperator(expression, t); } } - public void inclusiveOrExpression() throws Exception { - exclusiveOrExpression(); + protected void inclusiveOrExpression( Object expression ) throws Exception { + exclusiveOrExpression(expression); while (LT(1) == Token.tBITOR) { Token t = consume(); - exclusiveOrExpression(); - callback.expressionOperator(t); + exclusiveOrExpression(expression); + callback.expressionOperator(expression, t); } } - public void exclusiveOrExpression() throws Exception { - andExpression(); + protected void exclusiveOrExpression( Object expression ) throws Exception { + andExpression( expression ); while (LT(1) == Token.tXOR) { Token t = consume(); - andExpression(); - callback.expressionOperator(t); + andExpression(expression); + callback.expressionOperator(expression, t); } } - public void andExpression() throws Exception { - equalityExpression(); + protected void andExpression( Object expression ) throws Exception { + equalityExpression(expression); while (LT(1) == Token.tAMPER) { Token t = consume(); - equalityExpression(); - callback.expressionOperator(t); + equalityExpression(expression); + callback.expressionOperator(expression, t); } } - public void equalityExpression() throws Exception { - relationalExpression(); + protected void equalityExpression(Object expression) throws Exception { + relationalExpression(expression); for (;;) { switch (LT(1)) { case Token.tEQUAL: case Token.tNOTEQUAL: Token t = consume(); - relationalExpression(); - callback.expressionOperator(t); + relationalExpression(expression); + callback.expressionOperator(expression, t); break; default: return; @@ -1022,8 +1050,8 @@ c, quick); } } - public void relationalExpression() throws Exception { - shiftExpression(); + protected void relationalExpression(Object expression) throws Exception { + shiftExpression(expression); for (;;) { switch (LT(1)) { @@ -1035,8 +1063,8 @@ c, quick); case Token.tLTEQUAL: case Token.tGTEQUAL: Token t = consume(); - shiftExpression(); - callback.expressionOperator(t); + shiftExpression(expression); + callback.expressionOperator(expression, t); break; default: return; @@ -1044,16 +1072,16 @@ c, quick); } } - public void shiftExpression() throws Exception { - additiveExpression(); + protected void shiftExpression( Object expression ) throws Exception { + additiveExpression(expression); for (;;) { switch (LT(1)) { case Token.tSHIFTL: case Token.tSHIFTR: Token t = consume(); - additiveExpression(); - callback.expressionOperator(t); + additiveExpression(expression); + callback.expressionOperator(expression, t); break; default: return; @@ -1061,16 +1089,16 @@ c, quick); } } - public void additiveExpression() throws Exception { - multiplicativeExpression(); + protected void additiveExpression( Object expression ) throws Exception { + multiplicativeExpression(expression); for (;;) { switch (LT(1)) { case Token.tPLUS: case Token.tMINUS: Token t = consume(); - multiplicativeExpression(); - callback.expressionOperator(t); + multiplicativeExpression(expression); + callback.expressionOperator(expression, t); break; default: return; @@ -1078,8 +1106,8 @@ c, quick); } } - public void multiplicativeExpression() throws Exception { - pmExpression(); + protected void multiplicativeExpression( Object expression ) throws Exception { + pmExpression( expression ); for (;;) { switch (LT(1)) { @@ -1087,8 +1115,8 @@ c, quick); case Token.tDIV: case Token.tMOD: Token t = consume(); - pmExpression(); - callback.expressionOperator(t); + pmExpression(expression ); + callback.expressionOperator(expression , t); break; default: return; @@ -1096,16 +1124,16 @@ c, quick); } } - public void pmExpression() throws Exception { - castExpression(); + protected void pmExpression( Object expression ) throws Exception { + castExpression( expression ); for (;;) { switch (LT(1)) { case Token.tDOTSTAR: case Token.tARROWSTAR: Token t = consume(); - castExpression(); - callback.expressionOperator(t); + castExpression( expression ); + callback.expressionOperator(expression, t); break; default: return; @@ -1118,7 +1146,7 @@ c, quick); * : unaryExpression * | "(" typeId ")" castExpression */ - public void castExpression() throws Exception { + protected void castExpression( Object expression ) throws Exception { // TO DO: we need proper symbol checkint to ensure type name if (false && LT(1) == Token.tLPAREN) { Token mark = mark(); @@ -1128,17 +1156,17 @@ c, quick); try { typeId(); consume(Token.tRPAREN); - castExpression(); + castExpression( expression ); return; } catch (Backtrack b) { backup(mark); } } - unaryExpression(); + unaryExpression(expression); } - public void typeId() throws Exception { + protected void typeId() throws Exception { try { name(); return; @@ -1146,7 +1174,7 @@ c, quick); } } - public void deleteExpression() throws Exception { + protected void deleteExpression( Object expression ) throws Exception { if (LT(1) == Token.tCOLONCOLON) { // global scope consume(); @@ -1160,10 +1188,10 @@ c, quick); consume(Token.tRBRACKET); } - castExpression(); + castExpression( expression ); } - public void newExpression() throws Exception { + protected void newExpression( Object expression ) throws Exception { if (LT(1) == Token.tCOLONCOLON) { // global scope consume(); @@ -1171,10 +1199,10 @@ c, quick); consume (Token.t_new); - // TO DO: finish this horrible mess... + //TODO: finish this horrible mess... } - public void unaryExpression() throws Exception { + protected void unaryExpression( Object expression ) throws Exception { switch (LT(1)) { case Token.tSTAR: case Token.tAMPER: @@ -1185,8 +1213,8 @@ c, quick); case Token.tINCR: case Token.tDECR: Token t = consume(); - castExpression(); - callback.expressionOperator(t); + castExpression(expression); + callback.expressionOperator(expression, t); return; case Token.t_sizeof: if (LT(1) == Token.tLPAREN) { @@ -1194,34 +1222,34 @@ c, quick); typeId(); consume(Token.tRPAREN); } else { - unaryExpression(); + unaryExpression( expression ); } return; case Token.t_new: - newExpression(); + newExpression( expression ); return; case Token.t_delete: - deleteExpression(); + deleteExpression( expression ); return; case Token.tCOLONCOLON: switch (LT(2)) { case Token.t_new: - newExpression(); + newExpression(expression); return; case Token.t_delete: - deleteExpression(); + deleteExpression(expression); return; default: - postfixExpression(); + postfixExpression(expression); return; } default: - postfixExpression(); + postfixExpression(expression); return; } } - public void postfixExpression() throws Exception { + protected void postfixExpression( Object expression) throws Exception { switch (LT(1)) { case Token.t_typename: consume(); @@ -1236,7 +1264,7 @@ c, quick); typeId(); consume(Token.tGT); consume(Token.tLPAREN); - expression(); + expression(expression); consume(Token.tRPAREN); break; case Token.t_typeid: @@ -1245,13 +1273,13 @@ c, quick); try { typeId(); } catch (Backtrack b) { - expression(); + expression(expression); } consume(Token.tRPAREN); break; default: // TO DO: try simpleTypeSpecifier "(" expressionList ")" - primaryExpression(); + primaryExpression(expression); } for (;;) { @@ -1259,14 +1287,14 @@ c, quick); case Token.tLBRACKET: // array access consume(); - expression(); + expression(expression); consume(Token.tRBRACKET); break; case Token.tLPAREN: // function call consume(); // Note: since expressionList and expression are the same... - expression(); + expression(expression); consume(Token.tRPAREN); break; case Token.tINCR: @@ -1287,25 +1315,25 @@ c, quick); } } - public void primaryExpression() throws Exception { + protected void primaryExpression( Object expression ) throws Exception { int type = LT(1); switch (type) { // TO DO: we need more literals... case Token.tINTEGER: - callback.expressionTerminal(consume()); + callback.expressionTerminal(expression, consume()); return; case Token.tSTRING: - callback.expressionTerminal(consume()); + callback.expressionTerminal(expression, consume()); return; case Token.tIDENTIFIER: - callback.expressionTerminal(consume()); + callback.expressionTerminal(expression, consume()); return; case Token.t_this: consume(); return; case Token.tLPAREN: consume(); - expression(); + expression(expression); consume(Token.tRPAREN); return; default: @@ -1315,7 +1343,7 @@ c, quick); } } - public void varName() throws Exception { + protected void varName() throws Exception { if (LT(1) == Token.tCOLONCOLON) consume(); @@ -1430,7 +1458,7 @@ c, quick); } // Utility routines that require a knowledge of the grammar - public static String generateName(Token startToken) throws Exception { + protected static String generateName(Token startToken) throws Exception { Token currToken = startToken.getNext(); if (currToken == null || currToken.getType() != Token.tCOLONCOLON) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java index c6bf539e1c5..6b9703c7eb8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java @@ -347,12 +347,14 @@ public class Scanner implements IScanner { // we can just leave it internal private boolean throwExceptionPPError = true; private boolean throwExceptionOnRedefinition = false; - private boolean throwExceptionOnBadPPDirective = true; + private boolean throwExceptionOnBadUndefinition = false; + private boolean throwExceptionOnBadPreprocessorSyntax = true; private boolean throwExceptionOnInclusionNotFound = true; private boolean throwExceptionOnBadMacroExpansion = true; private boolean throwExceptionOnUnboundedString = true; private boolean throwExceptionOnEOFWithinMultilineComment = true; private boolean throwExceptionOnEOFWithoutBalancedEndifs = true; + private boolean throwExceptionOnBadCharacterRead = true; private boolean quickScan = false; public void setQuickScan(boolean qs) { @@ -630,7 +632,7 @@ public class Scanner implements IScanner { Object directive = ppDirectives.get(token); if (directive == null) { - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException( BAD_PP + currentContext.getOffset()); @@ -669,9 +671,10 @@ public class Scanner implements IScanner { skipOverWhitespace(); // definition String toBeUndefined = getNextIdentifier(); - // TODO -- Should we throw an exception if we - // do not have this in our table? - definitions.remove(toBeUndefined); + + if( ( definitions.remove(toBeUndefined) == null ) && throwExceptionOnBadUndefinition ) + throw new ScannerException( "Attempt to #undef symbol " + toBeUndefined + " when it was never defined"); + skipOverTextUntilNewline(); c = getChar(); continue; @@ -702,8 +705,9 @@ public class Scanner implements IScanner { } continue; case PreprocessorDirectives.ENDIF : - // TODO - make sure there is nothing after endif - + String restOfLine = getRestOfPreprocessorLine().trim(); + if( ! restOfLine.equals( "" ) && throwExceptionOnBadPreprocessorSyntax ) + throw new ScannerException( BAD_PP + currentContext.getOffset() ); passOnToClient = branches.poundendif(); c = getChar(); continue; @@ -736,7 +740,7 @@ public class Scanner implements IScanner { String elsifExpression = getRestOfPreprocessorLine(); if (elsifExpression.equals("")) - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException("Malformed #elsif clause"); boolean elsifResult = @@ -774,7 +778,7 @@ public class Scanner implements IScanner { String remainderOfLine = getRestOfPreprocessorLine().trim(); if (!remainderOfLine.equals("")) { - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException( BAD_PP + currentContext.getOffset()); } @@ -782,7 +786,7 @@ public class Scanner implements IScanner { c = getChar(); continue; default : - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException( BAD_PP + currentContext.getOffset()); @@ -1102,11 +1106,12 @@ public class Scanner implements IScanner { currentContext); } default : + // Bad character + if( throwExceptionOnBadCharacterRead ) + throw new ScannerException( "Invalid character read @ offset " + currentContext.getOffset() + " of file " + currentContext.getFilename() ); break; } - // Bad character - // TODO - does this need it's own exception throw Parser.endOfFile; } } @@ -1259,7 +1264,7 @@ public class Scanner implements IScanner { EXPRESSION, definitions); Parser parser = new Parser(trial, evaluator); - parser.expression(); + parser.expression(null); //TODO should this be null? expressionEvalResult = evaluator.getResult(); @@ -1470,13 +1475,13 @@ public class Scanner implements IScanner { } else { // this is not a comment // it is a bad statement - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException( BAD_PP + currentContext.getOffset()); } } else { System.out.println("Unexpected character " + ((char) c)); - if (throwExceptionOnBadPPDirective) + if (throwExceptionOnBadPreprocessorSyntax) throw new ScannerException(BAD_PP + currentContext.getOffset()); } diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java index 4f914078c8f..b236a2e56f0 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java @@ -11,12 +11,14 @@ import org.eclipse.cdt.internal.core.dom.BaseSpecifier; import org.eclipse.cdt.internal.core.dom.ClassSpecifier; import org.eclipse.cdt.internal.core.dom.DOMBuilder; import org.eclipse.cdt.internal.core.dom.Declarator; +import org.eclipse.cdt.internal.core.dom.Expression; import org.eclipse.cdt.internal.core.dom.ParameterDeclaration; import org.eclipse.cdt.internal.core.dom.ParameterDeclarationClause; import org.eclipse.cdt.internal.core.dom.SimpleDeclaration; import org.eclipse.cdt.internal.core.dom.TranslationUnit; import org.eclipse.cdt.internal.core.parser.Parser; import org.eclipse.cdt.internal.core.parser.ParserException; +import org.eclipse.cdt.internal.core.parser.Token; import org.eclipse.cdt.internal.core.parser.util.DeclSpecifier; import org.eclipse.cdt.internal.core.parser.util.Name; @@ -39,12 +41,12 @@ public class DOMTests extends TestCase { } /** - * Test code: int x; + * Test code: int x = 5; * Purpose: to test the simple decaration in it's simplest form. */ public void testIntGlobal() throws Exception { // Parse and get the translation Unit - TranslationUnit translationUnit = parse("int x;"); + TranslationUnit translationUnit = parse("int x = 5;"); // Get the simple declaration List declarations = translationUnit.getDeclarations(); @@ -60,6 +62,13 @@ public class DOMTests extends TestCase { Declarator declarator = (Declarator)declarators.get(0); Name name = declarator.getName(); assertEquals("x", name.toString()); + + Expression exp = declarator.getExpression(); + assertNotNull( exp ); + assertEquals( 1, exp.tokens().size() ); + Token t = (Token)exp.tokens().get(0); + assertEquals( t.getImage(), "5" ); + assertEquals( t.getType(), Token.tINTEGER); } /** @@ -243,14 +252,14 @@ public class DOMTests extends TestCase { } /** - * Test code: bool myFunction( int parm1, double parm2 ); + * Test code: bool myFunction( int parm1 = 3 * 4, double parm2 ); * @throws Exception */ public void testFunctionDeclarationWithParameters() throws Exception { // Parse and get the translaton unit Writer code = new StringWriter(); - code.write("bool myFunction( int parm1, double parm2 );"); + code.write("bool myFunction( int parm1 = 3 * 4, double parm2 );"); TranslationUnit translationUnit = parse(code.toString()); // Get the declaration @@ -271,7 +280,17 @@ public class DOMTests extends TestCase { List parm1Decls = parm1.getDeclarators(); assertEquals( 1, parm1Decls.size() ); Declarator parm1Declarator = (Declarator) parm1Decls.get(0); - assertEquals( "parm1", parm1Declarator.getName().toString() ); + assertEquals( "parm1", parm1Declarator.getName().toString() ); + Expression initialValueParm1 = parm1Declarator.getExpression(); + assertEquals( initialValueParm1.tokens().size(), 3 ); + Token t1 = (Token)initialValueParm1.tokens().get( 0 ); + Token t2 = (Token)initialValueParm1.tokens().get( 1 ); + Token t3 = (Token)initialValueParm1.tokens().get( 2 ); + assertEquals( t1.getType(), Token.tINTEGER ); + assertEquals( t1.getImage(), "3" ); + assertEquals( t3.getType(), Token.tSTAR ); + assertEquals( t2.getType(), Token.tINTEGER ); + assertEquals( t2.getImage(), "4" ); ParameterDeclaration parm2 = (ParameterDeclaration)parameterDecls.get( 1 ); assertEquals( DeclSpecifier.t_double, parm2.getDeclSpecifier().getType() ); diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java index d395014858a..af8c46e973e 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java @@ -20,7 +20,7 @@ public class ExprEvalTest extends TestCase { public void runTest(String code, int expectedValue) throws Exception { ExpressionEvaluator evaluator = new ExpressionEvaluator(); Parser parser = new Parser(code, evaluator); - parser.expression(); + parser.expression(null); assertEquals(expectedValue, ((Integer)evaluator.getResult()).intValue()); }