diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java
deleted file mode 100644
index 39fe4b34223..00000000000
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.eclipse.cdt.core.parser.tests;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.NullLogService;
-import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
-import org.eclipse.cdt.core.parser.ParserFactory;
-import org.eclipse.cdt.core.parser.ParserLanguage;
-import org.eclipse.cdt.core.parser.ScannerInfo;
-import org.eclipse.cdt.core.parser.ast.IASTExpression;
-import org.eclipse.cdt.internal.core.parser.IExpressionParser;
-import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
-
-public class ExprEvalTest extends TestCase {
-
- public static Test suite() {
- return new TestSuite(ExprEvalTest.class);
- }
-
- public ExprEvalTest(String name) {
- super(name);
- }
-
- public void runTest(String code, int expectedValue) throws Exception {
-
- final NullSourceElementRequestor nullCallback = new NullSourceElementRequestor();
- IExpressionParser parser = InternalParserUtil.createExpressionParser(ParserFactory.createScanner( new CodeReader( code.toCharArray() ), new ScannerInfo(), null, ParserLanguage.CPP, nullCallback, new NullLogService(), null ), ParserLanguage.CPP, null );
- IASTExpression expression = parser.expression(null,null, null);
- assertEquals(expectedValue, expression.evaluateExpression());
- }
-
- public void testInteger() throws Exception {
- runTest("5;", 5); //$NON-NLS-1$
- runTest( "33;", 33 ); //$NON-NLS-1$
- }
-
- public void testNot() throws Exception
- {
- runTest( "!1;", 0 ); //$NON-NLS-1$
- runTest( "!0;", 1 ); //$NON-NLS-1$
- runTest( "!4;", 0 ); //$NON-NLS-1$
- runTest( "!!4;", 1 ); //$NON-NLS-1$
- }
-
- public void testMultiplicational() throws Exception
- {
- runTest( "3 * 4;", 12 ); //$NON-NLS-1$
- runTest( "55 * 2;", 110 ); //$NON-NLS-1$
- runTest( "4 / 3;", 1 ); //$NON-NLS-1$
- runTest( "100/4;", 25 ); //$NON-NLS-1$
- runTest( "8 % 2;", 0 ); //$NON-NLS-1$
- runTest( "8 % 3;", 2 ); //$NON-NLS-1$
- }
-
- public void testAdditive() throws Exception
- {
- runTest( "4 + 4;", 8 ); //$NON-NLS-1$
- runTest( "4 - 4;", 0 ); //$NON-NLS-1$
- }
-
- public void testLogicalAnd() throws Exception
- {
- runTest( "4 && 5;", 1 ); //$NON-NLS-1$
- runTest( "0 && 5;", 0 ); //$NON-NLS-1$
- runTest( "5 && 0;", 0 ); //$NON-NLS-1$
- runTest( "0 && 0;", 0 ); //$NON-NLS-1$
- }
-
- public void testLogicalOr() throws Exception
- {
- runTest( "4 || 5;", 1 ); //$NON-NLS-1$
- runTest( "0 || 5;", 1 ); //$NON-NLS-1$
- runTest( "5 || 0;", 1 ); //$NON-NLS-1$
- runTest( "0 || 0;", 0 ); //$NON-NLS-1$
- }
-
- public void testRelational() throws Exception {
- runTest("1 < 2;", 1); //$NON-NLS-1$
- runTest("2 < 1;", 0); //$NON-NLS-1$
- runTest("2 == 1 + 1;", 1); //$NON-NLS-1$
- runTest("2 != 1 + 1;", 0); //$NON-NLS-1$
- }
-
- public void testBracketed() throws Exception {
- runTest("2 * (3 + 4);", 14); //$NON-NLS-1$
- }
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java
deleted file mode 100644
index 5a4e6ebb8d9..00000000000
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java
+++ /dev/null
@@ -1,2912 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.core.parser;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.cdt.core.parser.BacktrackException;
-import org.eclipse.cdt.core.parser.EndOfFileException;
-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.ITokenDuple;
-import org.eclipse.cdt.core.parser.KeywordSetKey;
-import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
-import org.eclipse.cdt.core.parser.ParseError;
-import org.eclipse.cdt.core.parser.ParserFactory;
-import org.eclipse.cdt.core.parser.ParserLanguage;
-import org.eclipse.cdt.core.parser.ParserMode;
-import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
-import org.eclipse.cdt.core.parser.ast.ASTSemanticException;
-import org.eclipse.cdt.core.parser.ast.IASTArrayModifier;
-import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
-import org.eclipse.cdt.core.parser.ast.IASTExpression;
-import org.eclipse.cdt.core.parser.ast.IASTFactory;
-import org.eclipse.cdt.core.parser.ast.IASTNode;
-import org.eclipse.cdt.core.parser.ast.IASTScope;
-import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
-import org.eclipse.cdt.core.parser.ast.IASTTypeId;
-import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
-import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
-import org.eclipse.cdt.core.parser.extension.IParserExtension;
-import org.eclipse.cdt.core.parser.util.CharArrayUtils;
-import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
-
-/**
- * @author jcamelon
- */
-public class ExpressionParser implements IExpressionParser, IParserData {
-
- protected static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$
- private static int FIRST_ERROR_UNSET = -1;
- protected boolean parsePassed = true;
- protected int firstErrorOffset = FIRST_ERROR_UNSET;
- protected int firstErrorLine = FIRST_ERROR_UNSET;
- private BacktrackException backtrack = new BacktrackException();
- private int backtrackCount = 0;
-
- protected final void throwBacktrack( IProblem problem ) throws BacktrackException {
- ++backtrackCount;
- backtrack.initialize( problem );
- throw backtrack;
- }
-
- protected final void throwBacktrack( int startingOffset, int endingOffset, int lineNumber, char[] f ) throws BacktrackException {
- ++backtrackCount;
- backtrack.initialize( startingOffset, ( endingOffset == 0 ) ? startingOffset + 1 : endingOffset, lineNumber, f );
- throw backtrack;
- }
-
- protected final IParserExtension extension;
-
- //TODO this stuff needs to be encapsulated by IParserData
- protected final IParserLogService log;
- protected ParserLanguage language = ParserLanguage.CPP;
- protected IASTFactory astFactory = null;
- protected IScanner scanner;
- protected IToken currToken;
- protected IToken lastToken;
- private boolean limitReached = false;
- private ScopeStack templateIdScopes = new ScopeStack();
- private TypeId typeIdInstance = new TypeId();
-
- private static class ScopeStack {
- private int [] stack;
- private int index = -1;
-
- public ScopeStack(){
- stack = new int [8];
- }
-
- private void grow(){
- int [] newStack = new int[ stack.length << 1 ];
- System.arraycopy( stack, 0, newStack, 0, stack.length );
- stack = newStack;
- }
-
- final public void push( int i ){
- if( ++index == stack.length )
- grow();
- stack[index] = i;
- }
- final public int pop(){
- if( index >= 0 )
- return stack[index--];
- return -1;
- }
- final public int peek(){
- if( index >= 0 )
- return stack[index];
- return -1;
- }
- final public int size(){
- return index + 1;
- }
- }
- /**
- * @return Returns the astFactory.
- */
- public IASTFactory getAstFactory() {
- return astFactory;
- }
- /**
- * @return Returns the log.
- */
- public IParserLogService getLog() {
- return log;
- }
-
- /**
- * Look Ahead in the token list to see what is coming.
- *
- * @param i How far ahead do you wish to peek?
- * @return the token you wish to observe
- * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile
- */
- public IToken LA(int i) throws EndOfFileException {
-
- if (isCancelled) {
- throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
- }
-
- if (i < 1) // can't go backwards
- return null;
- if (currToken == null)
- currToken = fetchToken();
- IToken retToken = currToken;
- for (; i > 1; --i) {
- retToken = retToken.getNext();
- if (retToken == null)
- retToken = fetchToken();
- }
- return retToken;
- }
-
- /**
- * Look ahead in the token list and return the token type.
- *
- * @param i How far ahead do you wish to peek?
- * @return The type of that token
- * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile
- */
- public int LT(int i) throws EndOfFileException {
- return LA(i).getType();
- }
-
- /**
- * Consume the next token available, regardless of the type.
- *
- * @return The token that was consumed and removed from our buffer.
- * @throws EndOfFileException If there is no token to consume.
- */
- public IToken consume() throws EndOfFileException {
-
- if (currToken == null)
- currToken = fetchToken();
- if (currToken != null)
- lastToken = currToken;
- currToken = currToken.getNext();
- handleNewToken(lastToken);
- return lastToken;
- }
-
- /**
- * Consume the next token available only if the type is as specified.
- *
- * @param type The type of token that you are expecting.
- * @return the token that was consumed and removed from our buffer.
- * @throws BacktrackException If LT(1) != type
- */
- public IToken consume(int type) throws EndOfFileException,
- BacktrackException {
- if (LT(1) == type)
- return consume();
- IToken la = LA(1);
- throwBacktrack(la.getOffset(), la.getEndOffset(), la.getLineNumber(), la.getFilename());
- return null;
- }
-
- /**
- * Mark our place in the buffer so that we could return to it should we have to.
- *
- * @return The current token.
- * @throws EndOfFileException If there are no more tokens.
- */
- public IToken mark() throws EndOfFileException {
- if (currToken == null)
- currToken = fetchToken();
- return currToken;
- }
-
- /**
- * Rollback to a previous point, reseting the queue of tokens.
- *
- * @param mark The point that we wish to restore to.
- *
- */
- public void backup(IToken mark) {
- currToken = mark;
- lastToken = null; // this is not entirely right ...
- }
-
- /**
- * @param extension TODO
- * @param scanner2
- * @param callback
- * @param language2
- * @param log2
- */
- public ExpressionParser(IScanner scanner, ParserLanguage language,
- IParserLogService log, IParserExtension extension) {
- this.scanner = scanner;
- this.language = language;
- this.log = log;
- this.extension = extension;
- setupASTFactory(scanner, language);
- }
-
- /**
- * @param scanner
- * @param language
- */
- protected void setupASTFactory(IScanner scanner, ParserLanguage language) {
- astFactory = ParserFactory.createASTFactory(
- ParserMode.EXPRESSION_PARSE, language);
- scanner.setASTFactory(astFactory);
- astFactory.setLogger(log);
- }
-
- /**
- * This is the single entry point for setting parsePassed to
- * false, and also making note what token offset we failed upon.
- *
- * @throws EndOfFileException
- */
- protected void failParse() {
- try {
- if (firstErrorOffset == FIRST_ERROR_UNSET){
- firstErrorOffset = LA(1).getOffset();
- firstErrorLine = LA(1).getLineNumber();
- }
- } catch (EndOfFileException eof) {
- // do nothing
- } finally {
- parsePassed = false;
- }
- }
-
- /**
- * Consumes template parameters.
- *
- * @param previousLast Previous "last" token (returned if nothing was consumed)
- * @return Last consumed token, or previousLast
if nothing was consumed
- * @throws BacktrackException request a backtrack
- */
- protected IToken consumeTemplateParameters(IToken previousLast)
- throws EndOfFileException, BacktrackException {
- if (language != ParserLanguage.CPP)
- return previousLast;
- int startingOffset = previousLast == null ? lastToken.getOffset() : previousLast.getOffset();
- IToken last = previousLast;
- if (LT(1) == IToken.tLT) {
- last = consume(IToken.tLT);
- // until we get all the names sorted out
- ScopeStack scopes = new ScopeStack();
- scopes.push(IToken.tLT);
-
- while (scopes.size() > 0) {
- int top;
- last = consume();
-
- switch (last.getType()) {
- case IToken.tGT :
- if (scopes.peek() == IToken.tLT) {
- scopes.pop();
- }
- break;
- case IToken.tRBRACKET :
- do {
- top = scopes.pop();
- } while (scopes.size() > 0
- && (top == IToken.tGT || top == IToken.tLT));
- if (top != IToken.tLBRACKET)
- throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
-
- break;
- case IToken.tRPAREN :
- do {
- top = scopes.pop();
- } while (scopes.size() > 0
- && (top == IToken.tGT || top == IToken.tLT));
- if (top != IToken.tLPAREN)
- throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
-
- break;
- case IToken.tLT :
- case IToken.tLBRACKET :
- case IToken.tLPAREN :
- scopes.push(last.getType());
- break;
- }
- }
- }
- return last;
- }
-
- protected List templateArgumentList(IASTScope scope,
- IASTCompletionNode.CompletionKind kind) throws EndOfFileException,
- BacktrackException {
- IToken start = LA(1);
- int startingOffset = start.getOffset();
- int startingLineNumber = start.getOffset();
- char [] fn = start.getFilename();
- start = null;
- IASTExpression expression = null;
- List list = new ArrayList();
-
- boolean completedArg = false;
- boolean failed = false;
-
- templateIdScopes.push( IToken.tLT );
-
- while (LT(1) != IToken.tGT) {
- completedArg = false;
-
- IToken mark = mark();
-
- try {
- IASTTypeId typeId = typeId(scope, false, kind);
-
- expression = astFactory.createExpression(scope,
- IASTExpression.Kind.POSTFIX_TYPEID_TYPEID, null, null,
- null, typeId, null, EMPTY_STRING, null);
- list.add(expression);
- completedArg = true;
- } catch (BacktrackException e) {
- backup(mark);
- } catch (ASTSemanticException e) {
- backup(mark);
- }
-
- if (!completedArg) {
- try {
- IToken la = LA(1);
- int so = la.getOffset();
- int ln= la.getLineNumber();
- expression = assignmentExpression(scope,
- CompletionKind.VARIABLE_TYPE,
- KeywordSetKey.EXPRESSION);
-
- if (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY) {
- throwBacktrack(so, ( lastToken != null ) ? lastToken.getEndOffset() : 0, ln, fn );
- }
- list.add(expression);
- completedArg = true;
- } catch (BacktrackException e) {
- backup(mark);
- }
- }
- if (!completedArg) {
- try {
- ITokenDuple nameDuple = name(scope, null,
- KeywordSetKey.EMPTY);
- expression = astFactory.createExpression(scope,
- IASTExpression.Kind.ID_EXPRESSION, null, null,
- null, null, nameDuple, EMPTY_STRING, null);
- list.add(expression);
- continue;
- } catch (ASTSemanticException e) {
- failed = true;
- break;
- } catch (BacktrackException e) {
- failed = true;
- break;
- } catch (Exception e) {
- logException("templateArgumentList::createExpression()", e); //$NON-NLS-1$
- failed = true;
- break;
- }
- }
-
- if (LT(1) == IToken.tCOMMA) {
- consume();
- } else if (LT(1) != IToken.tGT) {
- failed = true;
- break;
- }
- }
-
- templateIdScopes.pop();
-
- if (failed) {
- if (expression != null)
- expression.freeReferences(astFactory.getReferenceManager());
- throwBacktrack(startingOffset, 0, startingLineNumber, fn );
- }
-
- return list;
- }
-
- /**
- * Parse a template-id, according to the ANSI C++ spec.
- *
- * template-id: template-name < template-argument-list opt >
- * template-name : identifier
- *
- * @return the last token that we consumed in a successful parse
- *
- * @throws BacktrackException request a backtrack
- */
- protected IToken templateId(IASTScope scope, CompletionKind kind)
- throws EndOfFileException, BacktrackException {
- ITokenDuple duple = name(scope, kind, KeywordSetKey.EMPTY);
- //IToken last = consumeTemplateParameters(duple.getLastToken());
- return duple.getLastToken();//last;
- }
-
- /**
- * Parse a name.
- *
- * name
- * : ("::")? name2 ("::" name2)*
- *
- * name2
- * : IDENTIFER
- * : template-id
- *
- * @param key TODO
- * @throws BacktrackException request a backtrack
- */
- protected ITokenDuple name(IASTScope scope,
- IASTCompletionNode.CompletionKind kind, KeywordSetKey key)
- throws BacktrackException, EndOfFileException {
-
- TemplateParameterManager argumentList = TemplateParameterManager
- .getInstance();
-
- try {
- IToken first = LA(1);
- IToken last = null;
- IToken mark = mark();
-
- boolean hasTemplateId = false;
- boolean startsWithColonColon = false;
-
- if (LT(1) == IToken.tCOLONCOLON) {
- argumentList.addSegment(null);
- last = consume(IToken.tCOLONCOLON);
- setCompletionValues(scope, kind, KeywordSetKey.EMPTY,
- getCompliationUnit());
- startsWithColonColon = true;
- }
-
- if (LT(1) == IToken.tCOMPL)
- consume();
-
- switch (LT(1)) {
- case IToken.tIDENTIFIER :
- IToken prev = last;
- last = consume(IToken.tIDENTIFIER);
- if (startsWithColonColon)
- setCompletionValues(scope, kind, getCompliationUnit());
- else if (prev != null)
- setCompletionValues(scope, kind, first, prev,
- KeywordSetKey.EMPTY);
- else
- setCompletionValuesNoContext(scope, kind, key);
-
- last = consumeTemplateArguments(scope, last, argumentList,
- kind);
- if (last.getType() == IToken.tGT)
- hasTemplateId = true;
- break;
-
- default :
- IToken l = LA(1);
- backup(mark);
- throwBacktrack(first.getOffset(), l.getEndOffset(), first.getLineNumber(), l.getFilename());
- }
-
- while (LT(1) == IToken.tCOLONCOLON) {
- IToken prev = last;
- last = consume(IToken.tCOLONCOLON);
- setCompletionValues(scope, kind, first, prev,
- KeywordSetKey.EMPTY);
-
- if (queryLookaheadCapability() && LT(1) == IToken.t_template)
- consume();
-
- if (queryLookaheadCapability() && LT(1) == IToken.tCOMPL)
- consume();
-
- switch (LT(1)) {
- case IToken.t_operator :
- IToken l = LA(1);
- backup(mark);
- throwBacktrack(first.getOffset(), l.getEndOffset(), first.getLineNumber(), l.getFilename());
- case IToken.tIDENTIFIER :
- prev = last;
- last = consume();
- setCompletionValues(scope, kind, first, prev,
- KeywordSetKey.EMPTY);
- last = consumeTemplateArguments(scope, last,
- argumentList, kind);
- if (last.getType() == IToken.tGT)
- hasTemplateId = true;
- }
- }
-
- ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last,
- (hasTemplateId
- ? argumentList.getTemplateArgumentsList()
- : null));
- setGreaterNameContext(tokenDuple);
- return tokenDuple;
- } finally {
- TemplateParameterManager.returnInstance(argumentList);
- }
-
- }
-
- /**
- * @param scope
- * @param kind
- * @param key
- */
- protected void setCompletionValuesNoContext(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException {
- }
- /**
- * @param tokenDuple
- */
- protected void setGreaterNameContext(ITokenDuple tokenDuple) {
- //do nothing in this implementation
- }
-
- /**
- * @param scope
- * @param kind
- */
- protected void setCompletionValues(IASTScope scope, CompletionKind kind,
- IASTNode context) throws EndOfFileException {
- }
-
- /**
- * @param scope
- * @param kind
- */
- protected void setCompletionValues(IASTScope scope, CompletionKind kind)
- throws EndOfFileException {
- }
-
- /**
- * @return
- */
- protected IASTNode getCompliationUnit() {
- return null;
- }
-
- /**
- * @param scope
- * @param kind
- * @param key
- * @param node
- */
- protected void setCompletionValues(IASTScope scope, CompletionKind kind,
- KeywordSetKey key, IASTNode node) throws EndOfFileException {
- }
-
- /**
- * @param scope
- * @param last
- * @param argumentList
- * @return
- * @throws EndOfFileException
- * @throws BacktrackException
- */
- protected IToken consumeTemplateArguments(IASTScope scope, IToken last,
- TemplateParameterManager argumentList,
- IASTCompletionNode.CompletionKind completionKind)
- throws EndOfFileException, BacktrackException {
- if (language != ParserLanguage.CPP)
- return last;
- if (LT(1) == IToken.tLT) {
- IToken secondMark = mark();
- consume(IToken.tLT);
- try {
- List list = templateArgumentList(scope, completionKind);
- argumentList.addSegment(list);
- last = consume(IToken.tGT);
- } catch (BacktrackException bt) {
- argumentList.addSegment(null);
- backup(secondMark);
- }
- } else {
- argumentList.addSegment(null);
- }
- return last;
- }
-
- /**
- * Parse a const-volatile qualifier.
- *
- * cvQualifier
- * : "const" | "volatile"
- *
- * TODO: fix this
- * @param ptrOp Pointer Operator that const-volatile applies to.
- * @return Returns the same object sent in.
- * @throws BacktrackException
- */
- protected IToken cvQualifier(IDeclarator declarator)
- throws EndOfFileException, BacktrackException {
- IToken result = null;
- int startingOffset = LA(1).getOffset();
- switch (LT(1)) {
- case IToken.t_const :
- result = consume(IToken.t_const);
- declarator.addPointerOperator(ASTPointerOperator.CONST_POINTER);
- break;
- case IToken.t_volatile :
- result = consume(IToken.t_volatile);
- declarator
- .addPointerOperator(ASTPointerOperator.VOLATILE_POINTER);
- break;
- case IToken.t_restrict :
- if (language == ParserLanguage.C) {
- result = consume(IToken.t_restrict);
- declarator
- .addPointerOperator(ASTPointerOperator.RESTRICT_POINTER);
- break;
- }
- if (extension.isValidCVModifier(language, IToken.t_restrict)) {
- result = consume(IToken.t_restrict);
- declarator.addPointerOperator(extension.getPointerOperator(
- language, IToken.t_restrict));
- break;
- }
- IToken la = LA(1);
- throwBacktrack(startingOffset, la.getEndOffset(), la.getLineNumber(), la.getFilename());
-
- default :
- if (extension.isValidCVModifier(language, LT(1))) {
- result = consume();
- declarator.addPointerOperator(extension.getPointerOperator(
- language, result.getType()));
- }
- }
- return result;
- }
-
- protected IToken consumeArrayModifiers(IDeclarator d, IASTScope scope)
- throws EndOfFileException, BacktrackException {
- int startingOffset = LA(1).getOffset();
- IToken last = null;
- while (LT(1) == IToken.tLBRACKET) {
- consume(IToken.tLBRACKET); // eat the '['
-
- IASTExpression exp = null;
- if (LT(1) != IToken.tRBRACKET) {
- exp = constantExpression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE,
- KeywordSetKey.EXPRESSION);
- }
- last = consume(IToken.tRBRACKET);
- IASTArrayModifier arrayMod = null;
- try {
- arrayMod = astFactory.createArrayModifier(exp);
- } catch (Exception e) {
- logException("consumeArrayModifiers::createArrayModifier()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
- }
- d.addArrayModifier(arrayMod);
- }
- return last;
- }
-
- protected void operatorId(Declarator d, IToken originalToken,
- TemplateParameterManager templateArgs,
- IASTCompletionNode.CompletionKind completionKind)
- throws BacktrackException, EndOfFileException {
- // we know this is an operator
- IToken operatorToken = consume(IToken.t_operator);
- IToken toSend = null;
- if (LA(1).isOperator() || LT(1) == IToken.tLPAREN
- || LT(1) == IToken.tLBRACKET) {
- if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
- && LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) {
- consume();
- consume(IToken.tLBRACKET);
- toSend = consume(IToken.tRBRACKET);
- // vector new and delete operators
- } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) {
- // operator ()
- consume(IToken.tLPAREN);
- toSend = consume(IToken.tRPAREN);
- } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) {
- consume(IToken.tLBRACKET);
- toSend = consume(IToken.tRBRACKET);
- } else if (LA(1).isOperator())
- toSend = consume();
- else
- throwBacktrack(operatorToken.getOffset(), toSend != null ? toSend.getEndOffset() : 0, operatorToken.getLineNumber(), operatorToken.getFilename() );
- } else {
- // must be a conversion function
- typeId(d.getDeclarationWrapper().getScope(), true,
- CompletionKind.TYPE_REFERENCE);
- toSend = lastToken;
- }
-
- boolean hasTemplateId = (templateArgs != null);
- boolean grabbedNewInstance = false;
- if (templateArgs == null) {
- templateArgs = TemplateParameterManager.getInstance();
- grabbedNewInstance = true;
- }
-
- try {
- toSend = consumeTemplateArguments(d.getDeclarationWrapper()
- .getScope(), toSend, templateArgs, completionKind);
- if (toSend.getType() == IToken.tGT) {
- hasTemplateId = true;
- }
-
- ITokenDuple duple = TokenFactory.createTokenDuple(
- originalToken == null ? operatorToken : originalToken,
- toSend, (hasTemplateId ? templateArgs
- .getTemplateArgumentsList() : null));
-
- d.setName(duple);
- } finally {
- if (grabbedNewInstance)
- TemplateParameterManager.returnInstance(templateArgs);
- }
- }
-
- /**
- * Parse a Pointer Operator.
- *
- * ptrOperator
- * : "*" (cvQualifier)*
- * | "&"
- * | ::? nestedNameSpecifier "*" (cvQualifier)*
- *
- * @param owner Declarator that this pointer operator corresponds to.
- * @throws BacktrackException request a backtrack
- */
- protected IToken consumePointerOperators(IDeclarator d)
- throws EndOfFileException, BacktrackException {
- IToken result = null;
- for (;;) {
- if (LT(1) == IToken.tAMPER) {
- result = consume(IToken.tAMPER);
- d.addPointerOperator(ASTPointerOperator.REFERENCE);
- return result;
-
- }
- IToken mark = mark();
-
- ITokenDuple nameDuple = null;
- if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) {
- try {
- try {
- nameDuple = name(d.getScope(),
- CompletionKind.SINGLE_NAME_REFERENCE,
- KeywordSetKey.EMPTY);
- } catch (OffsetLimitReachedException olre) {
- backup(mark);
- return null;
- }
- } catch (BacktrackException bt) {
- backup(mark);
- return null;
- }
- }
- if (LT(1) == IToken.tSTAR) {
- result = consume(IToken.tSTAR);
-
- d.setPointerOperatorName(nameDuple);
-
- IToken successful = null;
- for (;;) {
- IToken newSuccess = cvQualifier(d);
- if (newSuccess != null)
- successful = newSuccess;
- else
- break;
-
- }
-
- if (successful == null) {
- d.addPointerOperator(ASTPointerOperator.POINTER);
- }
- continue;
- }
- if (nameDuple != null)
- nameDuple.freeReferences(astFactory.getReferenceManager());
- backup(mark);
- return result;
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression constantExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- return conditionalExpression(scope, kind, key);
- }
-
- public IASTExpression expression(IASTScope scope, CompletionKind kind,
- KeywordSetKey key) throws BacktrackException, EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int ln = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression assignmentExpression = assignmentExpression(scope, kind,
- key);
- while (LT(1) == IToken.tCOMMA) {
- consume(IToken.tCOMMA);
- setParameterListExpression(assignmentExpression);
- IASTExpression secondExpression = assignmentExpression(scope, kind,
- key);
- setParameterListExpression(null);
- int endOffset = lastToken != null ? lastToken.getEndOffset() : 0 ;
- try {
- assignmentExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.EXPRESSIONLIST,
- assignmentExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("expression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, ln, fn);
- }
- }
- return assignmentExpression;
- }
-
- /**
- * @param assignmentExpression
- */
- protected void setParameterListExpression(
- IASTExpression assignmentExpression) {
- }
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression assignmentExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- setCompletionValues(scope, kind, key);
- if (LT(1) == IToken.t_throw) {
- return throwExpression(scope, key);
- }
- IASTExpression conditionalExpression = conditionalExpression(scope,
- kind, key);
- // if the condition not taken, try assignment operators
- if (conditionalExpression != null
- && conditionalExpression.getExpressionKind() == IASTExpression.Kind.CONDITIONALEXPRESSION)
- return conditionalExpression;
- switch (LT(1)) {
- case IToken.tASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL,
- conditionalExpression, kind, key);
- case IToken.tSTARASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT,
- conditionalExpression, kind, key);
- case IToken.tDIVASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV,
- conditionalExpression, kind, key);
- case IToken.tMODASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD,
- conditionalExpression, kind, key);
- case IToken.tPLUSASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS,
- conditionalExpression, kind, key);
- case IToken.tMINUSASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS,
- conditionalExpression, kind, key);
- case IToken.tSHIFTRASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT,
- conditionalExpression, kind, key);
- case IToken.tSHIFTLASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT,
- conditionalExpression, kind, key);
- case IToken.tAMPERASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND,
- conditionalExpression, kind, key);
- case IToken.tXORASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR,
- conditionalExpression, kind, key);
- case IToken.tBITORASSIGN :
- return assignmentOperatorExpression(scope,
- IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR,
- conditionalExpression, kind, key);
- }
- return conditionalExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression throwExpression(IASTScope scope, KeywordSetKey key)
- throws EndOfFileException, BacktrackException {
- IToken throwToken = consume(IToken.t_throw);
- setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE,
- KeywordSetKey.EXPRESSION);
- IASTExpression throwExpression = null;
- try {
- throwExpression = expression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE, key);
- } catch (BacktrackException b) {
- }
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.THROWEXPRESSION, throwExpression, null,
- null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("throwExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(throwToken.getOffset(), endOffset, throwToken.getLineNumber(), throwToken.getFilename() );
-
- }
- return null;
- }
-
- /**
- * @param expression
- * @return
- * @throws BacktrackException
- */
- protected IASTExpression conditionalExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int ln = la.getLineNumber();
- char [] fn = la.getFilename();
- la = null;
- IASTExpression firstExpression = logicalOrExpression(scope, kind, key);
- if (LT(1) == IToken.tQUESTION) {
- consume(IToken.tQUESTION);
- IASTExpression secondExpression = expression(scope, kind, key);
- consume(IToken.tCOLON);
- IASTExpression thirdExpression = assignmentExpression(scope, kind,
- key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.CONDITIONALEXPRESSION,
- firstExpression, secondExpression, thirdExpression,
- null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("conditionalExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, ln, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression logicalOrExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = logicalAndExpression(scope, kind, key);
- while (LT(1) == IToken.tOR) {
- consume(IToken.tOR);
- IASTExpression secondExpression = logicalAndExpression(scope, kind,
- key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.LOGICALOREXPRESSION,
- firstExpression, secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("logicalOrExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression logicalAndExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = inclusiveOrExpression(scope, kind, key);
- while (LT(1) == IToken.tAND) {
- consume(IToken.tAND);
- IASTExpression secondExpression = inclusiveOrExpression(scope,
- kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.LOGICALANDEXPRESSION,
- firstExpression, secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("logicalAndExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression inclusiveOrExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = exclusiveOrExpression(scope, kind, key);
- while (LT(1) == IToken.tBITOR) {
- consume();
- IASTExpression secondExpression = exclusiveOrExpression(scope,
- kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.INCLUSIVEOREXPRESSION,
- firstExpression, secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("inclusiveOrExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression exclusiveOrExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = andExpression(scope, kind, key);
- while (LT(1) == IToken.tXOR) {
- consume();
-
- IASTExpression secondExpression = andExpression(scope, kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.EXCLUSIVEOREXPRESSION,
- firstExpression, secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("exclusiveORExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression andExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = equalityExpression(scope, kind, key);
- while (LT(1) == IToken.tAMPER) {
- consume();
- IASTExpression secondExpression = equalityExpression(scope, kind,
- key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.ANDEXPRESSION, firstExpression,
- secondExpression, null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("andExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- return firstExpression;
- }
-
- /**
- * @param methodName
- * @param e
- */
- public void logException(String methodName, Exception e) {
- if (!(e instanceof EndOfFileException) && e != null && log.isTracing()) {
- StringBuffer buffer = new StringBuffer();
- buffer.append("Parser: Unexpected exception in "); //$NON-NLS-1$
- buffer.append(methodName);
- buffer.append(":"); //$NON-NLS-1$
- buffer.append(e.getClass().getName());
- buffer.append("::"); //$NON-NLS-1$
- buffer.append(e.getMessage());
- buffer.append(". w/"); //$NON-NLS-1$
- buffer.append(scanner.toString());
- log.traceLog(buffer.toString());
-// log.errorLog(buffer.toString());
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression equalityExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = relationalExpression(scope, kind, key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tEQUAL :
- case IToken.tNOTEQUAL :
- IToken t = consume();
- IASTExpression secondExpression = relationalExpression(
- scope, kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope, (t
- .getType() == IToken.tEQUAL)
- ? IASTExpression.Kind.EQUALITY_EQUALS
- : IASTExpression.Kind.EQUALITY_NOTEQUALS,
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "equalityExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression relationalExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = shiftExpression(scope, kind, key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tGT :
- if (templateIdScopes.size() > 0 && templateIdScopes.peek() == IToken.tLT) {
- return firstExpression;
- }
- case IToken.tLT :
- case IToken.tLTEQUAL :
- case IToken.tGTEQUAL :
- IToken mark = mark();
- int t = consume().getType();
- IASTExpression secondExpression = shiftExpression(scope,
- kind, key);
- if (LA(1) == mark.getNext()) {
- // we did not consume anything
- // this is most likely an error
- backup(mark);
- return firstExpression;
- }
- IASTExpression.Kind expressionKind = null;
- switch (t) {
- case IToken.tGT :
- expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHAN;
- break;
- case IToken.tLT :
- expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHAN;
- break;
- case IToken.tLTEQUAL :
- expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO;
- break;
- case IToken.tGTEQUAL :
- expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO;
- break;
- }
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- expressionKind, firstExpression,
- secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "relationalExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- if (extension.isValidRelationalExpressionStart(language,
- LT(1))) {
- IASTExpression extensionExpression = extension
- .parseRelationalExpression(scope, this, kind,
- key, firstExpression);
- if (extensionExpression != null)
- return extensionExpression;
- }
- return firstExpression;
- }
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- public IASTExpression shiftExpression(IASTScope scope, CompletionKind kind,
- KeywordSetKey key) throws BacktrackException, EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = additiveExpression(scope, kind, key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tSHIFTL :
- case IToken.tSHIFTR :
- IToken t = consume();
- IASTExpression secondExpression = additiveExpression(scope,
- kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- ((t.getType() == IToken.tSHIFTL)
- ? IASTExpression.Kind.SHIFT_LEFT
- : IASTExpression.Kind.SHIFT_RIGHT),
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("shiftExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression additiveExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = multiplicativeExpression(scope, kind,
- key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tPLUS :
- case IToken.tMINUS :
- IToken t = consume();
- IASTExpression secondExpression = multiplicativeExpression(
- scope, kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- ((t.getType() == IToken.tPLUS)
- ? IASTExpression.Kind.ADDITIVE_PLUS
- : IASTExpression.Kind.ADDITIVE_MINUS),
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "additiveExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression multiplicativeExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws BacktrackException,
- EndOfFileException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = pmExpression(scope, kind, key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tSTAR :
- case IToken.tDIV :
- case IToken.tMOD :
- IToken t = consume();
- IASTExpression secondExpression = pmExpression(scope, kind,
- key);
- IASTExpression.Kind expressionKind = null;
- switch (t.getType()) {
- case IToken.tSTAR :
- expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY;
- break;
- case IToken.tDIV :
- expressionKind = IASTExpression.Kind.MULTIPLICATIVE_DIVIDE;
- break;
- case IToken.tMOD :
- expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MODULUS;
- break;
- }
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- expressionKind, firstExpression,
- secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- firstExpression.freeReferences(astFactory
- .getReferenceManager());
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "multiplicativeExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression pmExpression(IASTScope scope, CompletionKind kind,
- KeywordSetKey key) throws EndOfFileException, BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
-
- IASTExpression firstExpression = castExpression(scope, kind, key);
- for (;;) {
- switch (LT(1)) {
- case IToken.tDOTSTAR :
- case IToken.tARROWSTAR :
- IToken t = consume();
- IASTExpression secondExpression = castExpression(scope,
- kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- firstExpression = astFactory.createExpression(scope,
- ((t.getType() == IToken.tDOTSTAR)
- ? IASTExpression.Kind.PM_DOTSTAR
- : IASTExpression.Kind.PM_ARROWSTAR),
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("pmExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * castExpression
- * : unaryExpression
- * | "(" typeId ")" castExpression
- */
- protected IASTExpression castExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- // TO DO: we need proper symbol checkint to ensure type name
- if (LT(1) == IToken.tLPAREN) {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IToken mark = mark();
- consume();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push( IToken.tLPAREN );
- }
- boolean popped = false;
- IASTTypeId typeId = null;
- // If this isn't a type name, then we shouldn't be here
- try {
- try {
- typeId = typeId(scope, false, getCastExpressionKind(kind));
- consume(IToken.tRPAREN);
- } catch (BacktrackException bte) {
- backup(mark);
- if (typeId != null)
- typeId.freeReferences(astFactory.getReferenceManager());
- throw bte;
- }
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- popped = true;
- }
- IASTExpression castExpression = castExpression(scope, kind, key);
- if( castExpression != null && castExpression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY )
- {
- backup( mark );
- if (typeId != null)
- typeId.freeReferences(astFactory.getReferenceManager());
- return unaryExpression(scope, kind, key);
- }
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- mark = null; // clean up mark so that we can garbage collect
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.CASTEXPRESSION, castExpression,
- null, null, typeId, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("castExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- } catch (BacktrackException b) {
- if (templateIdScopes.size() > 0 && !popped) {
- templateIdScopes.pop();
- }
- }
- }
- return unaryExpression(scope, kind, key);
-
- }
-
- /**
- * @param kind
- * @return
- */
- private CompletionKind getCastExpressionKind(CompletionKind kind) {
- return ((kind == CompletionKind.SINGLE_NAME_REFERENCE || kind == CompletionKind.FUNCTION_REFERENCE)
- ? kind
- : CompletionKind.TYPE_REFERENCE);
- }
-
- /**
- * @param completionKind TODO
- * @throws BacktrackException
- */
- public IASTTypeId typeId(IASTScope scope, boolean skipArrayModifiers,
- CompletionKind completionKind) throws EndOfFileException,
- BacktrackException {
- IToken mark = mark();
- ITokenDuple name = null;
- boolean isConst = false, isVolatile = false;
- boolean isSigned = false, isUnsigned = false;
- boolean isShort = false, isLong = false;
- boolean isTypename = false;
-
- IASTSimpleTypeSpecifier.Type kind = null;
- do {
- try {
- name = name(scope, completionKind,
- KeywordSetKey.DECL_SPECIFIER_SEQUENCE);
- kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
- break;
- } catch (BacktrackException b) {
- // do nothing
- }
-
- boolean encounteredType = false;
- simpleMods : for (;;) {
- switch (LT(1)) {
- case IToken.t_signed :
- consume();
- isSigned = true;
- break;
-
- case IToken.t_unsigned :
- consume();
- isUnsigned = true;
- break;
-
- case IToken.t_short :
- consume();
- isShort = true;
- break;
-
- case IToken.t_long :
- consume();
- isLong = true;
- break;
-
- case IToken.t_const :
- consume();
- isConst = true;
- break;
-
- case IToken.t_volatile :
- consume();
- isVolatile = true;
- break;
-
- case IToken.tIDENTIFIER :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- name = name(scope, completionKind, KeywordSetKey.EMPTY);
- kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
- break;
-
- case IToken.t_int :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.INT;
- consume();
- break;
-
- case IToken.t_char :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.CHAR;
- consume();
- break;
-
- case IToken.t_bool :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.BOOL;
- consume();
- break;
-
- case IToken.t_double :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.DOUBLE;
- consume();
- break;
-
- case IToken.t_float :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.FLOAT;
- consume();
- break;
-
- case IToken.t_wchar_t :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.WCHAR_T;
- consume();
- break;
-
- case IToken.t_void :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type.VOID;
- consume();
- break;
-
- case IToken.t__Bool :
- if (encounteredType)
- break simpleMods;
- encounteredType = true;
- kind = IASTSimpleTypeSpecifier.Type._BOOL;
- consume();
- break;
-
- default :
- break simpleMods;
- }
- }
-
- if (kind != null)
- break;
-
- if (isShort || isLong || isUnsigned || isSigned) {
- kind = IASTSimpleTypeSpecifier.Type.INT;
- break;
- }
-
- if (LT(1) == IToken.t_typename || LT(1) == IToken.t_struct
- || LT(1) == IToken.t_class || LT(1) == IToken.t_enum
- || LT(1) == IToken.t_union) {
- consume();
- try {
- name = name(scope, completionKind, KeywordSetKey.EMPTY);
- kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
- } catch (BacktrackException b) {
- backup(mark);
- throwBacktrack(b);
- }
- }
-
- } while (false);
-
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- if (kind == null)
- throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
-
- TypeId id = getTypeIdInstance(scope);
- IToken last = lastToken;
- IToken temp = last;
-
- //template parameters are consumed as part of name
- //lastToken = consumeTemplateParameters( last );
- //if( lastToken == null ) lastToken = last;
-
- temp = consumePointerOperators(id);
- if (temp != null)
- last = temp;
-
- if (!skipArrayModifiers) {
- temp = consumeArrayModifiers(id, scope);
- if (temp != null)
- last = temp;
- }
-
- endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- char[] signature = EMPTY_STRING;
- if (last != null)
- {
- if( lastToken == null )
- lastToken = last;
- signature = TokenFactory.createCharArrayRepresentation(mark, last);
- }
- return astFactory.createTypeId(scope, kind, isConst, isVolatile,
- isShort, isLong, isSigned, isUnsigned, isTypename, name, id
- .getPointerOperators(), id.getArrayModifiers(),
- signature);
- } catch (ASTSemanticException e) {
- backup(mark);
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("typeId::createTypeId()", e); //$NON-NLS-1$
- throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
- }
- return null;
- }
-
- /**
- * @param scope
- * @return
- */
- private TypeId getTypeIdInstance(IASTScope scope) {
- typeIdInstance.reset(scope);
- return typeIdInstance;
- }
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression deleteExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- if (LT(1) == IToken.tCOLONCOLON) {
- // global scope
- consume(IToken.tCOLONCOLON);
- }
-
- consume(IToken.t_delete);
-
- boolean vectored = false;
- if (LT(1) == IToken.tLBRACKET) {
- // array delete
- consume();
- consume(IToken.tRBRACKET);
- vectored = true;
- }
- IASTExpression castExpression = castExpression(scope, kind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope, (vectored
- ? IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION
- : IASTExpression.Kind.DELETE_CASTEXPRESSION),
- castExpression, null, null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("deleteExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- return null;
- }
-
- /**
- * Pazse a new-expression.
- *
- * @param expression
- * @throws BacktrackException
- *
- *
- * newexpression: ::? new newplacement? newtypeid newinitializer?
- * ::? new newplacement? ( typeid ) newinitializer?
- * newplacement: ( expressionlist )
- * newtypeid: typespecifierseq newdeclarator?
- * newdeclarator: ptroperator newdeclarator? | directnewdeclarator
- * directnewdeclarator: [ expression ]
- * directnewdeclarator [ constantexpression ]
- * newinitializer: ( expressionlist? )
- */
- protected IASTExpression newExpression(IASTScope scope, KeywordSetKey key)
- throws BacktrackException, EndOfFileException {
- setCompletionValues(scope, CompletionKind.NEW_TYPE_REFERENCE,
- KeywordSetKey.EMPTY);
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- if (LT(1) == IToken.tCOLONCOLON) {
- // global scope
- consume(IToken.tCOLONCOLON);
- }
- consume(IToken.t_new);
- boolean typeIdInParen = false;
- boolean placementParseFailure = true;
- IToken beforeSecondParen = null;
- IToken backtrackMarker = null;
- IASTTypeId typeId = null;
- ArrayList newPlacementExpressions = new ArrayList();
- ArrayList newTypeIdExpressions = new ArrayList();
- ArrayList newInitializerExpressions = new ArrayList();
-
- if (LT(1) == IToken.tLPAREN) {
- consume(IToken.tLPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- try {
- // Try to consume placement list
- // Note: since expressionList and expression are the same...
- backtrackMarker = mark();
- newPlacementExpressions.add(expression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE, key));
- consume(IToken.tRPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } //pop 1st Parent
- placementParseFailure = false;
- if (LT(1) == IToken.tLPAREN) {
- beforeSecondParen = mark();
- consume(IToken.tLPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- } //push 2nd Paren
- typeIdInParen = true;
- }
- } catch (BacktrackException e) {
- backup(backtrackMarker);
- }
- if (placementParseFailure) {
- // CASE: new (typeid-not-looking-as-placement) ...
- // the first expression in () is not a placement
- // - then it has to be typeId
- typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE);
- consume(IToken.tRPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } //pop 1st Paren
- } else {
- if (!typeIdInParen) {
- if (LT(1) == IToken.tLBRACKET) {
- // CASE: new (typeid-looking-as-placement) [expr]...
- // the first expression in () has been parsed as a placement;
- // however, we assume that it was in fact typeId, and this
- // new statement creates an array.
- // Do nothing, fallback to array/initializer processing
- } else {
- // CASE: new (placement) typeid ...
- // the first expression in () is parsed as a placement,
- // and the next expression doesn't start with '(' or '['
- // - then it has to be typeId
- try {
- backtrackMarker = mark();
- typeId = typeId(scope, true,
- CompletionKind.NEW_TYPE_REFERENCE);
- } catch (BacktrackException e) {
- // Hmmm, so it wasn't typeId after all... Then it is
- // CASE: new (typeid-looking-as-placement)
- backup(backtrackMarker);
- // TODO fix this
- return null;
- }
- }
- } else {
- // Tricky cases: first expression in () is parsed as a placement,
- // and the next expression starts with '('.
- // The problem is, the first expression might as well be a typeid
- try {
- typeId = typeId(scope, true,
- CompletionKind.NEW_TYPE_REFERENCE);
- consume(IToken.tRPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } //popping the 2nd Paren
-
- if (LT(1) == IToken.tLPAREN
- || LT(1) == IToken.tLBRACKET) {
- // CASE: new (placement)(typeid)(initializer)
- // CASE: new (placement)(typeid)[] ...
- // Great, so far all our assumptions have been correct
- // Do nothing, fallback to array/initializer processing
- } else {
- // CASE: new (placement)(typeid)
- // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid)
- // Worst-case scenario - this cannot be resolved w/o more semantic information.
- // Luckily, we don't need to know what was that - we only know that
- // new-expression ends here.
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- setCompletionValues(scope,
- CompletionKind.NO_SUCH_KIND,
- KeywordSetKey.EMPTY);
- return astFactory.createExpression(scope,
- IASTExpression.Kind.NEW_TYPEID, null,
- null, null, typeId, null, EMPTY_STRING,
- astFactory.createNewDescriptor(
- newPlacementExpressions,
- newTypeIdExpressions,
- newInitializerExpressions));
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "newExpression_1::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- }
- } catch (BacktrackException e) {
- // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
- // Fallback to initializer processing
- backup(beforeSecondParen);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }//pop that 2nd paren
- }
- }
- }
- } else {
- // CASE: new typeid ...
- // new parameters do not start with '('
- // i.e it has to be a plain typeId
- typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE);
- }
- while (LT(1) == IToken.tLBRACKET) {
- // array new
- consume();
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLBRACKET);
- }
-
- newTypeIdExpressions.add(assignmentExpression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE, key));
- consume(IToken.tRBRACKET);
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- }
- // newinitializer
- if (LT(1) == IToken.tLPAREN) {
- consume(IToken.tLPAREN);
- setCurrentFunctionName(((typeId != null) ? typeId
- .getFullSignatureCharArray() : EMPTY_STRING));
- setCompletionValues(scope, CompletionKind.CONSTRUCTOR_REFERENCE);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
-
- //we want to know the difference between no newInitializer and an empty new Initializer
- //if the next token is the RPAREN, then we have an Empty expression in our list.
- newInitializerExpressions.add(expression(scope,
- CompletionKind.CONSTRUCTOR_REFERENCE, key));
-
- setCurrentFunctionName(EMPTY_STRING);
- consume(IToken.tRPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- }
- setCompletionValues(scope, CompletionKind.NO_SUCH_KIND,
- KeywordSetKey.EMPTY);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.NEW_TYPEID, null, null, null, typeId,
- null, EMPTY_STRING, astFactory.createNewDescriptor(
- newPlacementExpressions, newTypeIdExpressions,
- newInitializerExpressions));
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- return null;
- } catch (Exception e) {
- logException("newExpression_2::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- return null;
- }
-
- /**
- * @param functionName
- */
- protected void setCurrentFunctionName(char[] functionName) {
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- public IASTExpression unaryExpression(IASTScope scope, CompletionKind kind,
- KeywordSetKey key) throws EndOfFileException, BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- switch (LT(1)) {
- case IToken.tSTAR :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION, kind,
- key);
- case IToken.tAMPER :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION, kind,
- key);
- case IToken.tPLUS :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION, kind,
- key);
- case IToken.tMINUS :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION, kind,
- key);
- case IToken.tNOT :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION, kind, key);
- case IToken.tCOMPL :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION, kind,
- key);
- case IToken.tINCR :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_INCREMENT, kind, key);
- case IToken.tDECR :
- consume();
- return unaryOperatorCastExpression(scope,
- IASTExpression.Kind.UNARY_DECREMENT, kind, key);
- case IToken.t_sizeof :
- consume(IToken.t_sizeof);
- IToken mark = LA(1);
- IASTTypeId d = null;
- IASTExpression unaryExpression = null;
- if (LT(1) == IToken.tLPAREN) {
- try {
- consume(IToken.tLPAREN);
- d = typeId(scope, false,
- CompletionKind.SINGLE_NAME_REFERENCE);
- consume(IToken.tRPAREN);
- } catch (BacktrackException bt) {
- backup(mark);
- unaryExpression = unaryExpression(scope, kind, key);
- }
- } else {
- unaryExpression = unaryExpression(scope, kind, key);
- }
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- if (unaryExpression == null)
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.UNARY_SIZEOF_TYPEID, null,
- null, null, d, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION,
- unaryExpression, null, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e1) {
- throwBacktrack(e1.getProblem());
- } catch (Exception e) {
- logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- case IToken.t_new :
- return newExpression(scope, key);
- case IToken.t_delete :
- return deleteExpression(scope, kind, key);
- case IToken.tCOLONCOLON :
- if (queryLookaheadCapability(2)) {
- switch (LT(2)) {
- case IToken.t_new :
- return newExpression(scope, key);
- case IToken.t_delete :
- return deleteExpression(scope, kind, key);
- default :
- return postfixExpression(scope, kind, key);
- }
- }
- default :
- if (extension.isValidUnaryExpressionStart(LT(1))) {
- IASTExpression extensionExpression = extension
- .parseUnaryExpression(scope, this, kind, key);
- if (extensionExpression != null)
- return extensionExpression;
- }
- return postfixExpression(scope, kind, key);
- }
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression postfixExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- IASTExpression firstExpression = null;
- boolean isTemplate = false;
-
- setCompletionValues(scope, kind, key);
- switch (LT(1)) {
- case IToken.t_typename :
- consume(IToken.t_typename);
-
- boolean templateTokenConsumed = false;
- if (LT(1) == IToken.t_template) {
- consume(IToken.t_template);
- templateTokenConsumed = true;
- }
- ITokenDuple nestedName = name(scope,
- CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY);
-
- consume(IToken.tLPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- IASTExpression expressionList = expression(scope,
- CompletionKind.TYPE_REFERENCE, key);
- int endOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
-
- try {
- firstExpression = astFactory
- .createExpression(
- scope,
- (templateTokenConsumed
- ? IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID
- : IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER),
- expressionList, null, null, null,
- nestedName, EMPTY_STRING, null);
- } catch (ASTSemanticException ase) {
- throwBacktrack(ase.getProblem());
- } catch (Exception e) {
- logException("postfixExpression_1::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- // simple-type-specifier ( assignment-expression , .. )
- case IToken.t_char :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR, key);
- break;
- case IToken.t_wchar_t :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART, key);
- break;
- case IToken.t_bool :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL, key);
- break;
- case IToken.t_short :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT, key);
- break;
- case IToken.t_int :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT, key);
- break;
- case IToken.t_long :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG, key);
- break;
- case IToken.t_signed :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED, key);
- break;
- case IToken.t_unsigned :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED, key);
- break;
- case IToken.t_float :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT, key);
- break;
- case IToken.t_double :
- firstExpression = simpleTypeConstructorExpression(scope,
- IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE, key);
- break;
- case IToken.t_dynamic_cast :
- firstExpression = specialCastExpression(scope,
- IASTExpression.Kind.POSTFIX_DYNAMIC_CAST, key);
- break;
- case IToken.t_static_cast :
- firstExpression = specialCastExpression(scope,
- IASTExpression.Kind.POSTFIX_STATIC_CAST, key);
- break;
- case IToken.t_reinterpret_cast :
- firstExpression = specialCastExpression(scope,
- IASTExpression.Kind.POSTFIX_REINTERPRET_CAST, key);
- break;
- case IToken.t_const_cast :
- firstExpression = specialCastExpression(scope,
- IASTExpression.Kind.POSTFIX_CONST_CAST, key);
- break;
- case IToken.t_typeid :
- consume();
- consume(IToken.tLPAREN);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- boolean isTypeId = true;
- IASTExpression lhs = null;
- IASTTypeId typeId = null;
- try {
- typeId = typeId(scope, false, CompletionKind.TYPE_REFERENCE);
- } catch (BacktrackException b) {
- isTypeId = false;
- lhs = expression(scope, CompletionKind.TYPE_REFERENCE, key);
- }
- endOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- try {
- firstExpression = astFactory
- .createExpression(
- scope,
- (isTypeId
- ? IASTExpression.Kind.POSTFIX_TYPEID_TYPEID
- : IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION),
- lhs, null, null, typeId, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e6) {
- throwBacktrack(e6.getProblem());
- } catch (Exception e) {
- logException("postfixExpression_2::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- firstExpression = primaryExpression(scope, kind, key);
- }
- IASTExpression secondExpression = null;
- for (;;) {
- switch (LT(1)) {
- case IToken.tLBRACKET :
- // array access
- consume(IToken.tLBRACKET);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLBRACKET);
- }
- secondExpression = expression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE, key);
- int endOffset = consume(IToken.tRBRACKET).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.POSTFIX_SUBSCRIPT,
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e2) {
- throwBacktrack(e2.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_3::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- case IToken.tLPAREN :
- // function call
- consume(IToken.tLPAREN);
- IASTNode context = null;
- if (firstExpression != null) {
- if (firstExpression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION)
- setCurrentFunctionName(firstExpression
- .getIdExpressionCharArray());
- else if (firstExpression.getRHSExpression() != null
- && firstExpression.getRHSExpression()
- .getIdExpressionCharArray() != null) {
- setCurrentFunctionName(firstExpression
- .getRHSExpression().getIdExpressionCharArray());
- context = astFactory
- .expressionToMostPreciseASTNode(scope,
- firstExpression.getLHSExpression());
- }
- }
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- setCompletionValues(scope,
- CompletionKind.FUNCTION_REFERENCE, context);
- secondExpression = expression(scope,
- CompletionKind.FUNCTION_REFERENCE, key);
- setCurrentFunctionName(EMPTY_STRING);
- endOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.POSTFIX_FUNCTIONCALL,
- firstExpression, secondExpression, null, null,
- null, EMPTY_STRING, null);
- } catch (ASTSemanticException e3) {
- throwBacktrack(e3.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_4::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- case IToken.tINCR :
- endOffset = consume(IToken.tINCR).getEndOffset();
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.POSTFIX_INCREMENT,
- firstExpression, null, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e1) {
- throwBacktrack(e1.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_5::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- case IToken.tDECR :
- endOffset = consume().getEndOffset();
- try {
- firstExpression = astFactory.createExpression(scope,
- IASTExpression.Kind.POSTFIX_DECREMENT,
- firstExpression, null, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e4) {
- throwBacktrack(e4.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_6::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- case IToken.tDOT :
- // member access
- consume(IToken.tDOT);
-
- if (queryLookaheadCapability())
- if (LT(1) == IToken.t_template) {
- consume(IToken.t_template);
- isTemplate = true;
- }
-
- Kind memberCompletionKind = (isTemplate
- ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS
- : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION);
-
- setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE,
- KeywordSetKey.EMPTY, firstExpression,
- memberCompletionKind);
- secondExpression = primaryExpression(scope,
- CompletionKind.MEMBER_REFERENCE, key);
- endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- if (secondExpression != null
- && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION
- && CharArrayUtils.indexOf( '~', secondExpression.getIdExpressionCharArray() ) != -1)
- memberCompletionKind = Kind.POSTFIX_DOT_DESTRUCTOR;
-
- try {
- firstExpression = astFactory.createExpression(scope,
- memberCompletionKind, firstExpression,
- secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e5) {
- throwBacktrack(e5.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_7::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- case IToken.tARROW :
- // member access
- consume(IToken.tARROW);
-
- if (queryLookaheadCapability())
- if (LT(1) == IToken.t_template) {
- consume(IToken.t_template);
- isTemplate = true;
- }
-
- Kind arrowCompletionKind = (isTemplate
- ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP
- : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION);
-
- setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE,
- KeywordSetKey.EMPTY, firstExpression,
- arrowCompletionKind);
- secondExpression = primaryExpression(scope,
- CompletionKind.MEMBER_REFERENCE, key);
- endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- if (secondExpression != null
- && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION
- && CharArrayUtils.indexOf( '~', secondExpression.getIdExpressionCharArray() ) != -1)
- arrowCompletionKind = Kind.POSTFIX_ARROW_DESTRUCTOR;
- try {
- firstExpression = astFactory.createExpression(scope,
- arrowCompletionKind, firstExpression,
- secondExpression, null, null, null,
- EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "postfixExpression_8::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- break;
- default :
- return firstExpression;
- }
- }
- }
-
- /**
- * @return
- * @throws EndOfFileException
- */
- protected boolean queryLookaheadCapability(int count)
- throws EndOfFileException {
- //make sure we can look ahead one before doing this
- boolean result = true;
- try {
- LA(count);
- } catch (EndOfFileException olre) {
- result = false;
- }
- return result;
- }
-
- protected boolean queryLookaheadCapability() throws EndOfFileException {
- return queryLookaheadCapability(1);
- }
-
- protected void checkEndOfFile() throws EndOfFileException {
- LA(1);
- }
-
- protected IASTExpression simpleTypeConstructorExpression(IASTScope scope,
- Kind type, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- la = null;
- char[] typeName = consume().getCharImage();
- consume(IToken.tLPAREN);
- setCurrentFunctionName(typeName);
- IASTExpression inside = expression(scope,
- CompletionKind.CONSTRUCTOR_REFERENCE, key);
- setCurrentFunctionName(EMPTY_STRING);
- int endOffset = consume(IToken.tRPAREN).getEndOffset();
- try {
- return astFactory.createExpression(scope, type, inside, null, null,
- null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException(
- "simpleTypeConstructorExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- return null;
- }
-
- /**
- * @param expression
- * @throws BacktrackException
- */
- protected IASTExpression primaryExpression(IASTScope scope,
- CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
- BacktrackException {
- IToken t = null;
- switch (LT(1)) {
- // TO DO: we need more literals...
- case IToken.tINTEGER :
- t = consume();
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_INTEGER_LITERAL, null,
- null, null, null, null, t.getCharImage(), null);
- } catch (ASTSemanticException e1) {
- throwBacktrack(e1.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_1::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
- }
- case IToken.tFLOATINGPT :
- t = consume();
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_FLOAT_LITERAL, null,
- null, null, null, null, t.getCharImage(), null);
- } catch (ASTSemanticException e2) {
- throwBacktrack(e2.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_2::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
- }
- case IToken.tSTRING :
- case IToken.tLSTRING :
- t = consume();
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_STRING_LITERAL, null,
- null, null, null, null, t.getCharImage(), null);
- } catch (ASTSemanticException e5) {
- throwBacktrack(e5.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_3::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
- }
-
- case IToken.t_false :
- case IToken.t_true :
- t = consume();
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL, null,
- null, null, null, null, t.getCharImage(), null);
- } catch (ASTSemanticException e3) {
- throwBacktrack(e3.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_4::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename() );
- }
-
- case IToken.tCHAR :
- case IToken.tLCHAR :
-
- t = consume();
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_CHAR_LITERAL, null,
- null, null, null, null, t.getCharImage(), null);
- } catch (ASTSemanticException e4) {
- throwBacktrack(e4.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_5::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
- }
-
- case IToken.t_this :
- t = consume(IToken.t_this);
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_THIS, null, null, null,
- null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e7) {
- throwBacktrack(e7.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_6::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
- }
- case IToken.tLPAREN :
- t = consume();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- IASTExpression lhs = expression(scope, kind, key);
- int endOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION,
- lhs, null, null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e6) {
- throwBacktrack(e6.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_7::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), endOffset, t.getLineNumber(), t.getFilename() );
- }
- case IToken.tIDENTIFIER :
- case IToken.tCOLONCOLON :
- case IToken.t_operator :
- case IToken.tCOMPL :
- ITokenDuple duple = null;
- int startingOffset = LA(1).getOffset();
- int line = LA(1).getLineNumber();
- try {
- duple = name(scope, kind, key);
- } catch (BacktrackException bt) {
- IToken mark = mark();
- Declarator d = new Declarator(new DeclarationWrapper(scope,
- mark.getOffset(), mark.getLineNumber(), null, mark.getFilename()));
-
- if (LT(1) == IToken.tCOLONCOLON
- || LT(1) == IToken.tIDENTIFIER) {
- IToken start = consume();
- IToken end = null;
- if (start.getType() == IToken.tIDENTIFIER)
- end = consumeTemplateParameters(end);
- while (LT(1) == IToken.tCOLONCOLON
- || LT(1) == IToken.tIDENTIFIER) {
- end = consume();
- if (end.getType() == IToken.tIDENTIFIER)
- end = consumeTemplateParameters(end);
- }
- if (LT(1) == IToken.t_operator)
- operatorId(d, start, null, kind);
- else {
- backup(mark);
- throwBacktrack(startingOffset, end.getEndOffset(), end.getLineNumber(), t.getFilename());
- }
- } else if (LT(1) == IToken.t_operator)
- operatorId(d, null, null, kind);
-
- duple = d.getNameDuple();
- }
-
- endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope,
- IASTExpression.Kind.ID_EXPRESSION, null, null,
- null, null, duple, EMPTY_STRING, null);
- } catch (ASTSemanticException e8) {
- throwBacktrack(e8.getProblem());
- } catch (Exception e) {
- logException("primaryExpression_8::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, duple.getFilename());
- }
- default :
- IToken la= LA(1);
- startingOffset = la.getOffset();
- line = la.getLineNumber();
- char [] fn = la.getFilename();
- if (!queryLookaheadCapability(2)) {
- if (LA(1).canBeAPrefix()) {
- consume();
- checkEndOfFile();
- }
- }
- IASTExpression empty = null;
- try {
- empty = astFactory.createExpression(scope,
- IASTExpression.Kind.PRIMARY_EMPTY, null, null,
- null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e9) {
- throwBacktrack( e9.getProblem() );
- return null;
- } catch (Exception e) {
- logException("primaryExpression_9::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, 0, line, fn);
- }
- return empty;
- }
-
- }
-
- /**
- * Fetches a token from the scanner.
- *
- * @return the next token from the scanner
- * @throws EndOfFileException thrown when the scanner.nextToken() yields no tokens
- */
- protected IToken fetchToken() throws EndOfFileException {
- if (limitReached)
- throw new EndOfFileException();
-
- try {
- IToken value = scanner.nextToken();
- return value;
- } catch (OffsetLimitReachedException olre) {
- limitReached = true;
- handleOffsetLimitException(olre);
- return null;
- }
- }
-
- /**
- * @param value
- */
- protected void handleNewToken(IToken value) {
- }
-
- protected void handleOffsetLimitException(
- OffsetLimitReachedException exception) throws EndOfFileException {
- // unexpected, throw EOF instead (equivalent)
- throw new EndOfFileException();
- }
-
- protected IASTExpression assignmentOperatorExpression(IASTScope scope,
- IASTExpression.Kind kind, IASTExpression lhs,
- CompletionKind completionKind, KeywordSetKey key)
- throws EndOfFileException, BacktrackException {
- IToken t = consume();
- IASTExpression assignmentExpression = assignmentExpression(scope,
- completionKind, key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope, kind, lhs,
- assignmentExpression, null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("assignmentOperatorExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(t.getOffset(), endOffset, t.getLineNumber(), t.getFilename());
- }
- return null;
- }
-
- protected void setCompletionValues(IASTScope scope,
- IASTCompletionNode.CompletionKind kind, KeywordSetKey key)
- throws EndOfFileException {
- }
-
- protected void setCompletionValues(IASTScope scope,
- IASTCompletionNode.CompletionKind kind, KeywordSetKey key,
- IASTNode node, String prefix) throws EndOfFileException {
- }
-
- protected void setCompletionValues(IASTScope scope, CompletionKind kind,
- KeywordSetKey key, IASTExpression firstExpression,
- Kind expressionKind) throws EndOfFileException {
- }
-
- protected void setCompletionValues(IASTScope scope, CompletionKind kind,
- IToken first, IToken last, KeywordSetKey key)
- throws EndOfFileException {
- }
-
- protected IASTExpression unaryOperatorCastExpression(IASTScope scope,
- IASTExpression.Kind kind, CompletionKind completionKind,
- KeywordSetKey key) throws EndOfFileException, BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- la = null;
- IASTExpression castExpression = castExpression(scope, completionKind,
- key);
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
- try {
- return astFactory.createExpression(scope, kind, castExpression,
- null, null, null, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("unaryOperatorCastExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn);
- }
- return null;
- }
-
- protected IASTExpression specialCastExpression(IASTScope scope,
- IASTExpression.Kind kind, KeywordSetKey key)
- throws EndOfFileException, BacktrackException {
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int line = la.getLineNumber();
- char [] fn = la.getFilename();
- la = null;
-
- consume();
- consume(IToken.tLT);
- IASTTypeId duple = typeId(scope, false, CompletionKind.TYPE_REFERENCE);
- consume(IToken.tGT);
- consume(IToken.tLPAREN);
- IASTExpression lhs = expression(scope,
- CompletionKind.SINGLE_NAME_REFERENCE, key);
- int endOffset = consume(IToken.tRPAREN).getEndOffset();
- try {
- return astFactory.createExpression(scope, kind, lhs, null, null,
- duple, null, EMPTY_STRING, null);
- } catch (ASTSemanticException e) {
- throwBacktrack(e.getProblem());
- } catch (Exception e) {
- logException("specialCastExpression::createExpression()", e); //$NON-NLS-1$
- throwBacktrack(startingOffset, endOffset, line, fn );
- }
- return null;
- }
-
-
- protected boolean isCancelled = false;
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.IParserData#getLastToken()
- */
- public IToken getLastToken() {
- return lastToken;
- }
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.IParserData#getParserLanguage()
- */
- public final ParserLanguage getParserLanguage() {
- return language;
- }
- /**
- * Parse an identifier.
- *
- * @throws BacktrackException request a backtrack
- */
- public IToken identifier() throws EndOfFileException, BacktrackException {
- IToken first = consume(IToken.tIDENTIFIER); // throws backtrack if its not that
- if( first instanceof ITokenDuple ) setGreaterNameContext((ITokenDuple) first);
- return first;
- }
-
-
- public boolean validateCaches() {
- return true;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- return scanner.toString(); //$NON-NLS-1$
- }
-
- /**
- * @return Returns the backtrackCount.
- */
- public final int getBacktrackCount() {
- return backtrackCount;
- }
-
- /**
- * @param bt
- */
- protected void throwBacktrack(BacktrackException bt) throws BacktrackException {
- throw bt;
- }
-
- /**
- * @throws EndOfFileException
- */
- protected void errorHandling() throws EndOfFileException {
- int depth = ( LT(1) == IToken.tLBRACE ) ? 1 : 0;
- int type = consume().getType();
- if( type == IToken.tSEMI ) return;
- while (!((LT(1) == IToken.tSEMI && depth == 0)
- || (LT(1) == IToken.tRBRACE && depth == 1)))
- {
- switch (LT(1))
- {
- case IToken.tLBRACE :
- ++depth;
- break;
- case IToken.tRBRACE :
- --depth;
- break;
- }
- if( depth < 0 )
- return;
-
- consume();
- }
- // eat the SEMI/RBRACE as well
- consume();
- }
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IExpressionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IExpressionParser.java
deleted file mode 100644
index f59cf40bffd..00000000000
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IExpressionParser.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.core.parser;
-
-import org.eclipse.cdt.core.parser.BacktrackException;
-import org.eclipse.cdt.core.parser.EndOfFileException;
-import org.eclipse.cdt.core.parser.KeywordSetKey;
-import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
-import org.eclipse.cdt.core.parser.ast.IASTExpression;
-import org.eclipse.cdt.core.parser.ast.IASTScope;
-
-/**
- * @author jcamelon
- */
-public interface IExpressionParser {
-
- /**
- * Request a parse from a pre-configured parser to parse an expression.
- *
- * @param key TODO
- * @param expression Optional parameter representing an expression object that
- * your particular IParserCallback instance would appreciate
- * @throws BacktrackException thrown if the Scanner/Stream provided does not yield a valid
- * expression
- */
- public IASTExpression expression(IASTScope scope, IASTCompletionNode.CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException;
-
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserData.java
index de2bb4ce295..fa32c674b1f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserData.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserData.java
@@ -23,7 +23,11 @@ import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
* @author jcamelon
*
*/
-public interface IParserData extends IExpressionParser {
+public interface IParserData {
+
+ public IASTExpression expression(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key) throws BacktrackException, EndOfFileException;
+
/**
* @return Returns the astFactory.
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
index b7c8c28ae8b..dd975eb75e6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
@@ -14,28 +14,14 @@ import java.io.File;
import java.io.IOException;
import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.IParserLogService;
-import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ParserFactory;
-import org.eclipse.cdt.core.parser.ParserFactoryError;
-import org.eclipse.cdt.core.parser.ParserLanguage;
-import org.eclipse.cdt.core.parser.extension.ExtensionDialect;
-import org.eclipse.cdt.core.parser.extension.IParserExtensionFactory;
/**
* @author jcamelon
*/
public class InternalParserUtil extends ParserFactory {
- private static IParserExtensionFactory extensionFactory = new ParserExtensionFactory( ExtensionDialect.GCC );
- public static IExpressionParser createExpressionParser( IScanner scanner, ParserLanguage language, IParserLogService log ) throws ParserFactoryError
- {
- if( scanner == null ) throw new ParserFactoryError( ParserFactoryError.Kind.NULL_SCANNER );
- if( language == null ) throw new ParserFactoryError( ParserFactoryError.Kind.NULL_LANGUAGE );
- IParserLogService logService = ( log == null ) ? createDefaultLogService() : log;
- return new ExpressionParser( scanner, language, logService, extensionFactory.createParserExtension() );
- }
/**
* @param finalPath
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 3560ba780d8..9348c2cadd6 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
@@ -23,12 +23,15 @@ import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.KeywordSetKey;
+import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
+import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
import org.eclipse.cdt.core.parser.ast.ASTSemanticException;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTArrayModifier;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
@@ -39,6 +42,7 @@ import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.ast.IASTExpression;
+import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceAlias;
@@ -58,6 +62,7 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
+import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
import org.eclipse.cdt.core.parser.extension.IParserExtension;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory;
@@ -71,8 +76,2838 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
*
* @author jcamelon
*/
-public abstract class Parser extends ExpressionParser implements IParser
+public abstract class Parser implements IParserData, IParser
{
+
+ protected static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$
+ private static int FIRST_ERROR_UNSET = -1;
+ protected boolean parsePassed = true;
+ protected int firstErrorOffset = FIRST_ERROR_UNSET;
+ protected int firstErrorLine = FIRST_ERROR_UNSET;
+ private BacktrackException backtrack = new BacktrackException();
+ private int backtrackCount = 0;
+
+ protected final void throwBacktrack( IProblem problem ) throws BacktrackException {
+ ++backtrackCount;
+ backtrack.initialize( problem );
+ throw backtrack;
+ }
+
+ protected final void throwBacktrack( int startingOffset, int endingOffset, int lineNumber, char[] f ) throws BacktrackException {
+ ++backtrackCount;
+ backtrack.initialize( startingOffset, ( endingOffset == 0 ) ? startingOffset + 1 : endingOffset, lineNumber, f );
+ throw backtrack;
+ }
+
+ protected final IParserExtension extension;
+
+ //TODO this stuff needs to be encapsulated by IParserData
+ protected final IParserLogService log;
+ protected ParserLanguage language = ParserLanguage.CPP;
+ protected IASTFactory astFactory = null;
+ protected IScanner scanner;
+ protected IToken currToken;
+ protected IToken lastToken;
+ private boolean limitReached = false;
+ private ScopeStack templateIdScopes = new ScopeStack();
+ private TypeId typeIdInstance = new TypeId();
+
+ private static class ScopeStack {
+ private int [] stack;
+ private int index = -1;
+
+ public ScopeStack(){
+ stack = new int [8];
+ }
+
+ private void grow(){
+ int [] newStack = new int[ stack.length << 1 ];
+ System.arraycopy( stack, 0, newStack, 0, stack.length );
+ stack = newStack;
+ }
+
+ final public void push( int i ){
+ if( ++index == stack.length )
+ grow();
+ stack[index] = i;
+ }
+ final public int pop(){
+ if( index >= 0 )
+ return stack[index--];
+ return -1;
+ }
+ final public int peek(){
+ if( index >= 0 )
+ return stack[index];
+ return -1;
+ }
+ final public int size(){
+ return index + 1;
+ }
+ }
+ /**
+ * @return Returns the astFactory.
+ */
+ public IASTFactory getAstFactory() {
+ return astFactory;
+ }
+ /**
+ * @return Returns the log.
+ */
+ public IParserLogService getLog() {
+ return log;
+ }
+
+ /**
+ * Look Ahead in the token list to see what is coming.
+ *
+ * @param i How far ahead do you wish to peek?
+ * @return the token you wish to observe
+ * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile
+ */
+ public IToken LA(int i) throws EndOfFileException {
+
+ if (isCancelled) {
+ throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
+ }
+
+ if (i < 1) // can't go backwards
+ return null;
+ if (currToken == null)
+ currToken = fetchToken();
+ IToken retToken = currToken;
+ for (; i > 1; --i) {
+ retToken = retToken.getNext();
+ if (retToken == null)
+ retToken = fetchToken();
+ }
+ return retToken;
+ }
+
+ /**
+ * Look ahead in the token list and return the token type.
+ *
+ * @param i How far ahead do you wish to peek?
+ * @return The type of that token
+ * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile
+ */
+ public int LT(int i) throws EndOfFileException {
+ return LA(i).getType();
+ }
+
+ /**
+ * Consume the next token available, regardless of the type.
+ *
+ * @return The token that was consumed and removed from our buffer.
+ * @throws EndOfFileException If there is no token to consume.
+ */
+ public IToken consume() throws EndOfFileException {
+
+ if (currToken == null)
+ currToken = fetchToken();
+ if (currToken != null)
+ lastToken = currToken;
+ currToken = currToken.getNext();
+ handleNewToken(lastToken);
+ return lastToken;
+ }
+
+ /**
+ * Consume the next token available only if the type is as specified.
+ *
+ * @param type The type of token that you are expecting.
+ * @return the token that was consumed and removed from our buffer.
+ * @throws BacktrackException If LT(1) != type
+ */
+ public IToken consume(int type) throws EndOfFileException,
+ BacktrackException {
+ if (LT(1) == type)
+ return consume();
+ IToken la = LA(1);
+ throwBacktrack(la.getOffset(), la.getEndOffset(), la.getLineNumber(), la.getFilename());
+ return null;
+ }
+
+ /**
+ * Mark our place in the buffer so that we could return to it should we have to.
+ *
+ * @return The current token.
+ * @throws EndOfFileException If there are no more tokens.
+ */
+ public IToken mark() throws EndOfFileException {
+ if (currToken == null)
+ currToken = fetchToken();
+ return currToken;
+ }
+
+ /**
+ * Rollback to a previous point, reseting the queue of tokens.
+ *
+ * @param mark The point that we wish to restore to.
+ *
+ */
+ public void backup(IToken mark) {
+ currToken = mark;
+ lastToken = null; // this is not entirely right ...
+ }
+
+ /**
+ * This is the single entry point for setting parsePassed to
+ * false, and also making note what token offset we failed upon.
+ *
+ * @throws EndOfFileException
+ */
+ protected void failParse() {
+ try {
+ if (firstErrorOffset == FIRST_ERROR_UNSET){
+ firstErrorOffset = LA(1).getOffset();
+ firstErrorLine = LA(1).getLineNumber();
+ }
+ } catch (EndOfFileException eof) {
+ // do nothing
+ } finally {
+ parsePassed = false;
+ }
+ }
+
+ /**
+ * Consumes template parameters.
+ *
+ * @param previousLast Previous "last" token (returned if nothing was consumed)
+ * @return Last consumed token, or previousLast
if nothing was consumed
+ * @throws BacktrackException request a backtrack
+ */
+ protected IToken consumeTemplateParameters(IToken previousLast)
+ throws EndOfFileException, BacktrackException {
+ if (language != ParserLanguage.CPP)
+ return previousLast;
+ int startingOffset = previousLast == null ? lastToken.getOffset() : previousLast.getOffset();
+ IToken last = previousLast;
+ if (LT(1) == IToken.tLT) {
+ last = consume(IToken.tLT);
+ // until we get all the names sorted out
+ ScopeStack scopes = new ScopeStack();
+ scopes.push(IToken.tLT);
+
+ while (scopes.size() > 0) {
+ int top;
+ last = consume();
+
+ switch (last.getType()) {
+ case IToken.tGT :
+ if (scopes.peek() == IToken.tLT) {
+ scopes.pop();
+ }
+ break;
+ case IToken.tRBRACKET :
+ do {
+ top = scopes.pop();
+ } while (scopes.size() > 0
+ && (top == IToken.tGT || top == IToken.tLT));
+ if (top != IToken.tLBRACKET)
+ throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
+
+ break;
+ case IToken.tRPAREN :
+ do {
+ top = scopes.pop();
+ } while (scopes.size() > 0
+ && (top == IToken.tGT || top == IToken.tLT));
+ if (top != IToken.tLPAREN)
+ throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
+
+ break;
+ case IToken.tLT :
+ case IToken.tLBRACKET :
+ case IToken.tLPAREN :
+ scopes.push(last.getType());
+ break;
+ }
+ }
+ }
+ return last;
+ }
+
+ protected List templateArgumentList(IASTScope scope,
+ IASTCompletionNode.CompletionKind kind) throws EndOfFileException,
+ BacktrackException {
+ IToken start = LA(1);
+ int startingOffset = start.getOffset();
+ int startingLineNumber = start.getOffset();
+ char [] fn = start.getFilename();
+ start = null;
+ IASTExpression expression = null;
+ List list = new ArrayList();
+
+ boolean completedArg = false;
+ boolean failed = false;
+
+ templateIdScopes.push( IToken.tLT );
+
+ while (LT(1) != IToken.tGT) {
+ completedArg = false;
+
+ IToken mark = mark();
+
+ try {
+ IASTTypeId typeId = typeId(scope, false, kind);
+
+ expression = astFactory.createExpression(scope,
+ IASTExpression.Kind.POSTFIX_TYPEID_TYPEID, null, null,
+ null, typeId, null, EMPTY_STRING, null);
+ list.add(expression);
+ completedArg = true;
+ } catch (BacktrackException e) {
+ backup(mark);
+ } catch (ASTSemanticException e) {
+ backup(mark);
+ }
+
+ if (!completedArg) {
+ try {
+ IToken la = LA(1);
+ int so = la.getOffset();
+ int ln= la.getLineNumber();
+ expression = assignmentExpression(scope,
+ CompletionKind.VARIABLE_TYPE,
+ KeywordSetKey.EXPRESSION);
+
+ if (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY) {
+ throwBacktrack(so, ( lastToken != null ) ? lastToken.getEndOffset() : 0, ln, fn );
+ }
+ list.add(expression);
+ completedArg = true;
+ } catch (BacktrackException e) {
+ backup(mark);
+ }
+ }
+ if (!completedArg) {
+ try {
+ ITokenDuple nameDuple = name(scope, null,
+ KeywordSetKey.EMPTY);
+ expression = astFactory.createExpression(scope,
+ IASTExpression.Kind.ID_EXPRESSION, null, null,
+ null, null, nameDuple, EMPTY_STRING, null);
+ list.add(expression);
+ continue;
+ } catch (ASTSemanticException e) {
+ failed = true;
+ break;
+ } catch (BacktrackException e) {
+ failed = true;
+ break;
+ } catch (Exception e) {
+ logException("templateArgumentList::createExpression()", e); //$NON-NLS-1$
+ failed = true;
+ break;
+ }
+ }
+
+ if (LT(1) == IToken.tCOMMA) {
+ consume();
+ } else if (LT(1) != IToken.tGT) {
+ failed = true;
+ break;
+ }
+ }
+
+ templateIdScopes.pop();
+
+ if (failed) {
+ if (expression != null)
+ expression.freeReferences(astFactory.getReferenceManager());
+ throwBacktrack(startingOffset, 0, startingLineNumber, fn );
+ }
+
+ return list;
+ }
+
+ /**
+ * Parse a template-id, according to the ANSI C++ spec.
+ *
+ * template-id: template-name < template-argument-list opt >
+ * template-name : identifier
+ *
+ * @return the last token that we consumed in a successful parse
+ *
+ * @throws BacktrackException request a backtrack
+ */
+ protected IToken templateId(IASTScope scope, CompletionKind kind)
+ throws EndOfFileException, BacktrackException {
+ ITokenDuple duple = name(scope, kind, KeywordSetKey.EMPTY);
+ //IToken last = consumeTemplateParameters(duple.getLastToken());
+ return duple.getLastToken();//last;
+ }
+
+ /**
+ * Parse a name.
+ *
+ * name
+ * : ("::")? name2 ("::" name2)*
+ *
+ * name2
+ * : IDENTIFER
+ * : template-id
+ *
+ * @param key TODO
+ * @throws BacktrackException request a backtrack
+ */
+ protected ITokenDuple name(IASTScope scope,
+ IASTCompletionNode.CompletionKind kind, KeywordSetKey key)
+ throws BacktrackException, EndOfFileException {
+
+ TemplateParameterManager argumentList = TemplateParameterManager
+ .getInstance();
+
+ try {
+ IToken first = LA(1);
+ IToken last = null;
+ IToken mark = mark();
+
+ boolean hasTemplateId = false;
+ boolean startsWithColonColon = false;
+
+ if (LT(1) == IToken.tCOLONCOLON) {
+ argumentList.addSegment(null);
+ last = consume(IToken.tCOLONCOLON);
+ setCompletionValues(scope, kind, KeywordSetKey.EMPTY,
+ getCompliationUnit());
+ startsWithColonColon = true;
+ }
+
+ if (LT(1) == IToken.tCOMPL)
+ consume();
+
+ switch (LT(1)) {
+ case IToken.tIDENTIFIER :
+ IToken prev = last;
+ last = consume(IToken.tIDENTIFIER);
+ if (startsWithColonColon)
+ setCompletionValues(scope, kind, getCompliationUnit());
+ else if (prev != null)
+ setCompletionValues(scope, kind, first, prev,
+ KeywordSetKey.EMPTY);
+ else
+ setCompletionValuesNoContext(scope, kind, key);
+
+ last = consumeTemplateArguments(scope, last, argumentList,
+ kind);
+ if (last.getType() == IToken.tGT)
+ hasTemplateId = true;
+ break;
+
+ default :
+ IToken l = LA(1);
+ backup(mark);
+ throwBacktrack(first.getOffset(), l.getEndOffset(), first.getLineNumber(), l.getFilename());
+ }
+
+ while (LT(1) == IToken.tCOLONCOLON) {
+ IToken prev = last;
+ last = consume(IToken.tCOLONCOLON);
+ setCompletionValues(scope, kind, first, prev,
+ KeywordSetKey.EMPTY);
+
+ if (queryLookaheadCapability() && LT(1) == IToken.t_template)
+ consume();
+
+ if (queryLookaheadCapability() && LT(1) == IToken.tCOMPL)
+ consume();
+
+ switch (LT(1)) {
+ case IToken.t_operator :
+ IToken l = LA(1);
+ backup(mark);
+ throwBacktrack(first.getOffset(), l.getEndOffset(), first.getLineNumber(), l.getFilename());
+ case IToken.tIDENTIFIER :
+ prev = last;
+ last = consume();
+ setCompletionValues(scope, kind, first, prev,
+ KeywordSetKey.EMPTY);
+ last = consumeTemplateArguments(scope, last,
+ argumentList, kind);
+ if (last.getType() == IToken.tGT)
+ hasTemplateId = true;
+ }
+ }
+
+ ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last,
+ (hasTemplateId
+ ? argumentList.getTemplateArgumentsList()
+ : null));
+ setGreaterNameContext(tokenDuple);
+ return tokenDuple;
+ } finally {
+ TemplateParameterManager.returnInstance(argumentList);
+ }
+
+ }
+
+ /**
+ * @param scope
+ * @param kind
+ * @param key
+ */
+ protected void setCompletionValuesNoContext(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException {
+ }
+ /**
+ * @param tokenDuple
+ */
+ protected void setGreaterNameContext(ITokenDuple tokenDuple) {
+ //do nothing in this implementation
+ }
+
+ /**
+ * @param scope
+ * @param kind
+ */
+ protected void setCompletionValues(IASTScope scope, CompletionKind kind,
+ IASTNode context) throws EndOfFileException {
+ }
+
+ /**
+ * @param scope
+ * @param kind
+ */
+ protected void setCompletionValues(IASTScope scope, CompletionKind kind)
+ throws EndOfFileException {
+ }
+
+ /**
+ * @param scope
+ * @param kind
+ * @param key
+ * @param node
+ */
+ protected void setCompletionValues(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key, IASTNode node) throws EndOfFileException {
+ }
+
+ /**
+ * @param scope
+ * @param last
+ * @param argumentList
+ * @return
+ * @throws EndOfFileException
+ * @throws BacktrackException
+ */
+ protected IToken consumeTemplateArguments(IASTScope scope, IToken last,
+ TemplateParameterManager argumentList,
+ IASTCompletionNode.CompletionKind completionKind)
+ throws EndOfFileException, BacktrackException {
+ if (language != ParserLanguage.CPP)
+ return last;
+ if (LT(1) == IToken.tLT) {
+ IToken secondMark = mark();
+ consume(IToken.tLT);
+ try {
+ List list = templateArgumentList(scope, completionKind);
+ argumentList.addSegment(list);
+ last = consume(IToken.tGT);
+ } catch (BacktrackException bt) {
+ argumentList.addSegment(null);
+ backup(secondMark);
+ }
+ } else {
+ argumentList.addSegment(null);
+ }
+ return last;
+ }
+
+ /**
+ * Parse a const-volatile qualifier.
+ *
+ * cvQualifier
+ * : "const" | "volatile"
+ *
+ * TODO: fix this
+ * @param ptrOp Pointer Operator that const-volatile applies to.
+ * @return Returns the same object sent in.
+ * @throws BacktrackException
+ */
+ protected IToken cvQualifier(IDeclarator declarator)
+ throws EndOfFileException, BacktrackException {
+ IToken result = null;
+ int startingOffset = LA(1).getOffset();
+ switch (LT(1)) {
+ case IToken.t_const :
+ result = consume(IToken.t_const);
+ declarator.addPointerOperator(ASTPointerOperator.CONST_POINTER);
+ break;
+ case IToken.t_volatile :
+ result = consume(IToken.t_volatile);
+ declarator
+ .addPointerOperator(ASTPointerOperator.VOLATILE_POINTER);
+ break;
+ case IToken.t_restrict :
+ if (language == ParserLanguage.C) {
+ result = consume(IToken.t_restrict);
+ declarator
+ .addPointerOperator(ASTPointerOperator.RESTRICT_POINTER);
+ break;
+ }
+ if (extension.isValidCVModifier(language, IToken.t_restrict)) {
+ result = consume(IToken.t_restrict);
+ declarator.addPointerOperator(extension.getPointerOperator(
+ language, IToken.t_restrict));
+ break;
+ }
+ IToken la = LA(1);
+ throwBacktrack(startingOffset, la.getEndOffset(), la.getLineNumber(), la.getFilename());
+
+ default :
+ if (extension.isValidCVModifier(language, LT(1))) {
+ result = consume();
+ declarator.addPointerOperator(extension.getPointerOperator(
+ language, result.getType()));
+ }
+ }
+ return result;
+ }
+
+ protected IToken consumeArrayModifiers(IDeclarator d, IASTScope scope)
+ throws EndOfFileException, BacktrackException {
+ int startingOffset = LA(1).getOffset();
+ IToken last = null;
+ while (LT(1) == IToken.tLBRACKET) {
+ consume(IToken.tLBRACKET); // eat the '['
+
+ IASTExpression exp = null;
+ if (LT(1) != IToken.tRBRACKET) {
+ exp = constantExpression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE,
+ KeywordSetKey.EXPRESSION);
+ }
+ last = consume(IToken.tRBRACKET);
+ IASTArrayModifier arrayMod = null;
+ try {
+ arrayMod = astFactory.createArrayModifier(exp);
+ } catch (Exception e) {
+ logException("consumeArrayModifiers::createArrayModifier()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, last.getEndOffset(), last.getLineNumber(), last.getFilename());
+ }
+ d.addArrayModifier(arrayMod);
+ }
+ return last;
+ }
+
+ protected void operatorId(Declarator d, IToken originalToken,
+ TemplateParameterManager templateArgs,
+ IASTCompletionNode.CompletionKind completionKind)
+ throws BacktrackException, EndOfFileException {
+ // we know this is an operator
+ IToken operatorToken = consume(IToken.t_operator);
+ IToken toSend = null;
+ if (LA(1).isOperator() || LT(1) == IToken.tLPAREN
+ || LT(1) == IToken.tLBRACKET) {
+ if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
+ && LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) {
+ consume();
+ consume(IToken.tLBRACKET);
+ toSend = consume(IToken.tRBRACKET);
+ // vector new and delete operators
+ } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) {
+ // operator ()
+ consume(IToken.tLPAREN);
+ toSend = consume(IToken.tRPAREN);
+ } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) {
+ consume(IToken.tLBRACKET);
+ toSend = consume(IToken.tRBRACKET);
+ } else if (LA(1).isOperator())
+ toSend = consume();
+ else
+ throwBacktrack(operatorToken.getOffset(), toSend != null ? toSend.getEndOffset() : 0, operatorToken.getLineNumber(), operatorToken.getFilename() );
+ } else {
+ // must be a conversion function
+ typeId(d.getDeclarationWrapper().getScope(), true,
+ CompletionKind.TYPE_REFERENCE);
+ toSend = lastToken;
+ }
+
+ boolean hasTemplateId = (templateArgs != null);
+ boolean grabbedNewInstance = false;
+ if (templateArgs == null) {
+ templateArgs = TemplateParameterManager.getInstance();
+ grabbedNewInstance = true;
+ }
+
+ try {
+ toSend = consumeTemplateArguments(d.getDeclarationWrapper()
+ .getScope(), toSend, templateArgs, completionKind);
+ if (toSend.getType() == IToken.tGT) {
+ hasTemplateId = true;
+ }
+
+ ITokenDuple duple = TokenFactory.createTokenDuple(
+ originalToken == null ? operatorToken : originalToken,
+ toSend, (hasTemplateId ? templateArgs
+ .getTemplateArgumentsList() : null));
+
+ d.setName(duple);
+ } finally {
+ if (grabbedNewInstance)
+ TemplateParameterManager.returnInstance(templateArgs);
+ }
+ }
+
+ /**
+ * Parse a Pointer Operator.
+ *
+ * ptrOperator
+ * : "*" (cvQualifier)*
+ * | "&"
+ * | ::? nestedNameSpecifier "*" (cvQualifier)*
+ *
+ * @param owner Declarator that this pointer operator corresponds to.
+ * @throws BacktrackException request a backtrack
+ */
+ protected IToken consumePointerOperators(IDeclarator d)
+ throws EndOfFileException, BacktrackException {
+ IToken result = null;
+ for (;;) {
+ if (LT(1) == IToken.tAMPER) {
+ result = consume(IToken.tAMPER);
+ d.addPointerOperator(ASTPointerOperator.REFERENCE);
+ return result;
+
+ }
+ IToken mark = mark();
+
+ ITokenDuple nameDuple = null;
+ if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) {
+ try {
+ try {
+ nameDuple = name(d.getScope(),
+ CompletionKind.SINGLE_NAME_REFERENCE,
+ KeywordSetKey.EMPTY);
+ } catch (OffsetLimitReachedException olre) {
+ backup(mark);
+ return null;
+ }
+ } catch (BacktrackException bt) {
+ backup(mark);
+ return null;
+ }
+ }
+ if (LT(1) == IToken.tSTAR) {
+ result = consume(IToken.tSTAR);
+
+ d.setPointerOperatorName(nameDuple);
+
+ IToken successful = null;
+ for (;;) {
+ IToken newSuccess = cvQualifier(d);
+ if (newSuccess != null)
+ successful = newSuccess;
+ else
+ break;
+
+ }
+
+ if (successful == null) {
+ d.addPointerOperator(ASTPointerOperator.POINTER);
+ }
+ continue;
+ }
+ if (nameDuple != null)
+ nameDuple.freeReferences(astFactory.getReferenceManager());
+ backup(mark);
+ return result;
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression constantExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ return conditionalExpression(scope, kind, key);
+ }
+
+ public IASTExpression expression(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key) throws BacktrackException, EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int ln = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression assignmentExpression = assignmentExpression(scope, kind,
+ key);
+ while (LT(1) == IToken.tCOMMA) {
+ consume(IToken.tCOMMA);
+ setParameterListExpression(assignmentExpression);
+ IASTExpression secondExpression = assignmentExpression(scope, kind,
+ key);
+ setParameterListExpression(null);
+ int endOffset = lastToken != null ? lastToken.getEndOffset() : 0 ;
+ try {
+ assignmentExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.EXPRESSIONLIST,
+ assignmentExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("expression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, ln, fn);
+ }
+ }
+ return assignmentExpression;
+ }
+
+ /**
+ * @param assignmentExpression
+ */
+ protected void setParameterListExpression(
+ IASTExpression assignmentExpression) {
+ }
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression assignmentExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ setCompletionValues(scope, kind, key);
+ if (LT(1) == IToken.t_throw) {
+ return throwExpression(scope, key);
+ }
+ IASTExpression conditionalExpression = conditionalExpression(scope,
+ kind, key);
+ // if the condition not taken, try assignment operators
+ if (conditionalExpression != null
+ && conditionalExpression.getExpressionKind() == IASTExpression.Kind.CONDITIONALEXPRESSION)
+ return conditionalExpression;
+ switch (LT(1)) {
+ case IToken.tASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL,
+ conditionalExpression, kind, key);
+ case IToken.tSTARASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT,
+ conditionalExpression, kind, key);
+ case IToken.tDIVASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV,
+ conditionalExpression, kind, key);
+ case IToken.tMODASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD,
+ conditionalExpression, kind, key);
+ case IToken.tPLUSASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS,
+ conditionalExpression, kind, key);
+ case IToken.tMINUSASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS,
+ conditionalExpression, kind, key);
+ case IToken.tSHIFTRASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT,
+ conditionalExpression, kind, key);
+ case IToken.tSHIFTLASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT,
+ conditionalExpression, kind, key);
+ case IToken.tAMPERASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND,
+ conditionalExpression, kind, key);
+ case IToken.tXORASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR,
+ conditionalExpression, kind, key);
+ case IToken.tBITORASSIGN :
+ return assignmentOperatorExpression(scope,
+ IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR,
+ conditionalExpression, kind, key);
+ }
+ return conditionalExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression throwExpression(IASTScope scope, KeywordSetKey key)
+ throws EndOfFileException, BacktrackException {
+ IToken throwToken = consume(IToken.t_throw);
+ setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE,
+ KeywordSetKey.EXPRESSION);
+ IASTExpression throwExpression = null;
+ try {
+ throwExpression = expression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE, key);
+ } catch (BacktrackException b) {
+ }
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.THROWEXPRESSION, throwExpression, null,
+ null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("throwExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(throwToken.getOffset(), endOffset, throwToken.getLineNumber(), throwToken.getFilename() );
+
+ }
+ return null;
+ }
+
+ /**
+ * @param expression
+ * @return
+ * @throws BacktrackException
+ */
+ protected IASTExpression conditionalExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int ln = la.getLineNumber();
+ char [] fn = la.getFilename();
+ la = null;
+ IASTExpression firstExpression = logicalOrExpression(scope, kind, key);
+ if (LT(1) == IToken.tQUESTION) {
+ consume(IToken.tQUESTION);
+ IASTExpression secondExpression = expression(scope, kind, key);
+ consume(IToken.tCOLON);
+ IASTExpression thirdExpression = assignmentExpression(scope, kind,
+ key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.CONDITIONALEXPRESSION,
+ firstExpression, secondExpression, thirdExpression,
+ null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("conditionalExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, ln, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression logicalOrExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = logicalAndExpression(scope, kind, key);
+ while (LT(1) == IToken.tOR) {
+ consume(IToken.tOR);
+ IASTExpression secondExpression = logicalAndExpression(scope, kind,
+ key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.LOGICALOREXPRESSION,
+ firstExpression, secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("logicalOrExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression logicalAndExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = inclusiveOrExpression(scope, kind, key);
+ while (LT(1) == IToken.tAND) {
+ consume(IToken.tAND);
+ IASTExpression secondExpression = inclusiveOrExpression(scope,
+ kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.LOGICALANDEXPRESSION,
+ firstExpression, secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("logicalAndExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression inclusiveOrExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = exclusiveOrExpression(scope, kind, key);
+ while (LT(1) == IToken.tBITOR) {
+ consume();
+ IASTExpression secondExpression = exclusiveOrExpression(scope,
+ kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.INCLUSIVEOREXPRESSION,
+ firstExpression, secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("inclusiveOrExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression exclusiveOrExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = andExpression(scope, kind, key);
+ while (LT(1) == IToken.tXOR) {
+ consume();
+
+ IASTExpression secondExpression = andExpression(scope, kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.EXCLUSIVEOREXPRESSION,
+ firstExpression, secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("exclusiveORExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression andExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = equalityExpression(scope, kind, key);
+ while (LT(1) == IToken.tAMPER) {
+ consume();
+ IASTExpression secondExpression = equalityExpression(scope, kind,
+ key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.ANDEXPRESSION, firstExpression,
+ secondExpression, null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("andExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ return firstExpression;
+ }
+
+ /**
+ * @param methodName
+ * @param e
+ */
+ public void logException(String methodName, Exception e) {
+ if (!(e instanceof EndOfFileException) && e != null && log.isTracing()) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Parser: Unexpected exception in "); //$NON-NLS-1$
+ buffer.append(methodName);
+ buffer.append(":"); //$NON-NLS-1$
+ buffer.append(e.getClass().getName());
+ buffer.append("::"); //$NON-NLS-1$
+ buffer.append(e.getMessage());
+ buffer.append(". w/"); //$NON-NLS-1$
+ buffer.append(scanner.toString());
+ log.traceLog(buffer.toString());
+// log.errorLog(buffer.toString());
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression equalityExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = relationalExpression(scope, kind, key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tEQUAL :
+ case IToken.tNOTEQUAL :
+ IToken t = consume();
+ IASTExpression secondExpression = relationalExpression(
+ scope, kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope, (t
+ .getType() == IToken.tEQUAL)
+ ? IASTExpression.Kind.EQUALITY_EQUALS
+ : IASTExpression.Kind.EQUALITY_NOTEQUALS,
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "equalityExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression relationalExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = shiftExpression(scope, kind, key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tGT :
+ if (templateIdScopes.size() > 0 && templateIdScopes.peek() == IToken.tLT) {
+ return firstExpression;
+ }
+ case IToken.tLT :
+ case IToken.tLTEQUAL :
+ case IToken.tGTEQUAL :
+ IToken mark = mark();
+ int t = consume().getType();
+ IASTExpression secondExpression = shiftExpression(scope,
+ kind, key);
+ if (LA(1) == mark.getNext()) {
+ // we did not consume anything
+ // this is most likely an error
+ backup(mark);
+ return firstExpression;
+ }
+ IASTExpression.Kind expressionKind = null;
+ switch (t) {
+ case IToken.tGT :
+ expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHAN;
+ break;
+ case IToken.tLT :
+ expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHAN;
+ break;
+ case IToken.tLTEQUAL :
+ expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO;
+ break;
+ case IToken.tGTEQUAL :
+ expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO;
+ break;
+ }
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ expressionKind, firstExpression,
+ secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "relationalExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ if (extension.isValidRelationalExpressionStart(language,
+ LT(1))) {
+ IASTExpression extensionExpression = extension
+ .parseRelationalExpression(scope, this, kind,
+ key, firstExpression);
+ if (extensionExpression != null)
+ return extensionExpression;
+ }
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ public IASTExpression shiftExpression(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key) throws BacktrackException, EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = additiveExpression(scope, kind, key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tSHIFTL :
+ case IToken.tSHIFTR :
+ IToken t = consume();
+ IASTExpression secondExpression = additiveExpression(scope,
+ kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ ((t.getType() == IToken.tSHIFTL)
+ ? IASTExpression.Kind.SHIFT_LEFT
+ : IASTExpression.Kind.SHIFT_RIGHT),
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("shiftExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression additiveExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = multiplicativeExpression(scope, kind,
+ key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tPLUS :
+ case IToken.tMINUS :
+ IToken t = consume();
+ IASTExpression secondExpression = multiplicativeExpression(
+ scope, kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ ((t.getType() == IToken.tPLUS)
+ ? IASTExpression.Kind.ADDITIVE_PLUS
+ : IASTExpression.Kind.ADDITIVE_MINUS),
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "additiveExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression multiplicativeExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws BacktrackException,
+ EndOfFileException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = pmExpression(scope, kind, key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tSTAR :
+ case IToken.tDIV :
+ case IToken.tMOD :
+ IToken t = consume();
+ IASTExpression secondExpression = pmExpression(scope, kind,
+ key);
+ IASTExpression.Kind expressionKind = null;
+ switch (t.getType()) {
+ case IToken.tSTAR :
+ expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY;
+ break;
+ case IToken.tDIV :
+ expressionKind = IASTExpression.Kind.MULTIPLICATIVE_DIVIDE;
+ break;
+ case IToken.tMOD :
+ expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MODULUS;
+ break;
+ }
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ expressionKind, firstExpression,
+ secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ firstExpression.freeReferences(astFactory
+ .getReferenceManager());
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "multiplicativeExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression pmExpression(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key) throws EndOfFileException, BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+
+ IASTExpression firstExpression = castExpression(scope, kind, key);
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tDOTSTAR :
+ case IToken.tARROWSTAR :
+ IToken t = consume();
+ IASTExpression secondExpression = castExpression(scope,
+ kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ ((t.getType() == IToken.tDOTSTAR)
+ ? IASTExpression.Kind.PM_DOTSTAR
+ : IASTExpression.Kind.PM_ARROWSTAR),
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("pmExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * castExpression
+ * : unaryExpression
+ * | "(" typeId ")" castExpression
+ */
+ protected IASTExpression castExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ // TO DO: we need proper symbol checkint to ensure type name
+ if (LT(1) == IToken.tLPAREN) {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IToken mark = mark();
+ consume();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push( IToken.tLPAREN );
+ }
+ boolean popped = false;
+ IASTTypeId typeId = null;
+ // If this isn't a type name, then we shouldn't be here
+ try {
+ try {
+ typeId = typeId(scope, false, getCastExpressionKind(kind));
+ consume(IToken.tRPAREN);
+ } catch (BacktrackException bte) {
+ backup(mark);
+ if (typeId != null)
+ typeId.freeReferences(astFactory.getReferenceManager());
+ throw bte;
+ }
+
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ popped = true;
+ }
+ IASTExpression castExpression = castExpression(scope, kind, key);
+ if( castExpression != null && castExpression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY )
+ {
+ backup( mark );
+ if (typeId != null)
+ typeId.freeReferences(astFactory.getReferenceManager());
+ return unaryExpression(scope, kind, key);
+ }
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ mark = null; // clean up mark so that we can garbage collect
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.CASTEXPRESSION, castExpression,
+ null, null, typeId, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("castExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ } catch (BacktrackException b) {
+ if (templateIdScopes.size() > 0 && !popped) {
+ templateIdScopes.pop();
+ }
+ }
+ }
+ return unaryExpression(scope, kind, key);
+
+ }
+
+ /**
+ * @param kind
+ * @return
+ */
+ private CompletionKind getCastExpressionKind(CompletionKind kind) {
+ return ((kind == CompletionKind.SINGLE_NAME_REFERENCE || kind == CompletionKind.FUNCTION_REFERENCE)
+ ? kind
+ : CompletionKind.TYPE_REFERENCE);
+ }
+
+ /**
+ * @param completionKind TODO
+ * @throws BacktrackException
+ */
+ public IASTTypeId typeId(IASTScope scope, boolean skipArrayModifiers,
+ CompletionKind completionKind) throws EndOfFileException,
+ BacktrackException {
+ IToken mark = mark();
+ ITokenDuple name = null;
+ boolean isConst = false, isVolatile = false;
+ boolean isSigned = false, isUnsigned = false;
+ boolean isShort = false, isLong = false;
+ boolean isTypename = false;
+
+ IASTSimpleTypeSpecifier.Type kind = null;
+ do {
+ try {
+ name = name(scope, completionKind,
+ KeywordSetKey.DECL_SPECIFIER_SEQUENCE);
+ kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
+ break;
+ } catch (BacktrackException b) {
+ // do nothing
+ }
+
+ boolean encounteredType = false;
+ simpleMods : for (;;) {
+ switch (LT(1)) {
+ case IToken.t_signed :
+ consume();
+ isSigned = true;
+ break;
+
+ case IToken.t_unsigned :
+ consume();
+ isUnsigned = true;
+ break;
+
+ case IToken.t_short :
+ consume();
+ isShort = true;
+ break;
+
+ case IToken.t_long :
+ consume();
+ isLong = true;
+ break;
+
+ case IToken.t_const :
+ consume();
+ isConst = true;
+ break;
+
+ case IToken.t_volatile :
+ consume();
+ isVolatile = true;
+ break;
+
+ case IToken.tIDENTIFIER :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ name = name(scope, completionKind, KeywordSetKey.EMPTY);
+ kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
+ break;
+
+ case IToken.t_int :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.INT;
+ consume();
+ break;
+
+ case IToken.t_char :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.CHAR;
+ consume();
+ break;
+
+ case IToken.t_bool :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.BOOL;
+ consume();
+ break;
+
+ case IToken.t_double :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.DOUBLE;
+ consume();
+ break;
+
+ case IToken.t_float :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.FLOAT;
+ consume();
+ break;
+
+ case IToken.t_wchar_t :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.WCHAR_T;
+ consume();
+ break;
+
+ case IToken.t_void :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type.VOID;
+ consume();
+ break;
+
+ case IToken.t__Bool :
+ if (encounteredType)
+ break simpleMods;
+ encounteredType = true;
+ kind = IASTSimpleTypeSpecifier.Type._BOOL;
+ consume();
+ break;
+
+ default :
+ break simpleMods;
+ }
+ }
+
+ if (kind != null)
+ break;
+
+ if (isShort || isLong || isUnsigned || isSigned) {
+ kind = IASTSimpleTypeSpecifier.Type.INT;
+ break;
+ }
+
+ if (LT(1) == IToken.t_typename || LT(1) == IToken.t_struct
+ || LT(1) == IToken.t_class || LT(1) == IToken.t_enum
+ || LT(1) == IToken.t_union) {
+ consume();
+ try {
+ name = name(scope, completionKind, KeywordSetKey.EMPTY);
+ kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
+ } catch (BacktrackException b) {
+ backup(mark);
+ throwBacktrack(b);
+ }
+ }
+
+ } while (false);
+
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ if (kind == null)
+ throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
+
+ TypeId id = getTypeIdInstance(scope);
+ IToken last = lastToken;
+ IToken temp = last;
+
+ //template parameters are consumed as part of name
+ //lastToken = consumeTemplateParameters( last );
+ //if( lastToken == null ) lastToken = last;
+
+ temp = consumePointerOperators(id);
+ if (temp != null)
+ last = temp;
+
+ if (!skipArrayModifiers) {
+ temp = consumeArrayModifiers(id, scope);
+ if (temp != null)
+ last = temp;
+ }
+
+ endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ char[] signature = EMPTY_STRING;
+ if (last != null)
+ {
+ if( lastToken == null )
+ lastToken = last;
+ signature = TokenFactory.createCharArrayRepresentation(mark, last);
+ }
+ return astFactory.createTypeId(scope, kind, isConst, isVolatile,
+ isShort, isLong, isSigned, isUnsigned, isTypename, name, id
+ .getPointerOperators(), id.getArrayModifiers(),
+ signature);
+ } catch (ASTSemanticException e) {
+ backup(mark);
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("typeId::createTypeId()", e); //$NON-NLS-1$
+ throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
+ }
+ return null;
+ }
+
+ /**
+ * @param scope
+ * @return
+ */
+ private TypeId getTypeIdInstance(IASTScope scope) {
+ typeIdInstance.reset(scope);
+ return typeIdInstance;
+ }
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression deleteExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ if (LT(1) == IToken.tCOLONCOLON) {
+ // global scope
+ consume(IToken.tCOLONCOLON);
+ }
+
+ consume(IToken.t_delete);
+
+ boolean vectored = false;
+ if (LT(1) == IToken.tLBRACKET) {
+ // array delete
+ consume();
+ consume(IToken.tRBRACKET);
+ vectored = true;
+ }
+ IASTExpression castExpression = castExpression(scope, kind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope, (vectored
+ ? IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION
+ : IASTExpression.Kind.DELETE_CASTEXPRESSION),
+ castExpression, null, null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("deleteExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ return null;
+ }
+
+ /**
+ * Pazse a new-expression.
+ *
+ * @param expression
+ * @throws BacktrackException
+ *
+ *
+ * newexpression: ::? new newplacement? newtypeid newinitializer?
+ * ::? new newplacement? ( typeid ) newinitializer?
+ * newplacement: ( expressionlist )
+ * newtypeid: typespecifierseq newdeclarator?
+ * newdeclarator: ptroperator newdeclarator? | directnewdeclarator
+ * directnewdeclarator: [ expression ]
+ * directnewdeclarator [ constantexpression ]
+ * newinitializer: ( expressionlist? )
+ */
+ protected IASTExpression newExpression(IASTScope scope, KeywordSetKey key)
+ throws BacktrackException, EndOfFileException {
+ setCompletionValues(scope, CompletionKind.NEW_TYPE_REFERENCE,
+ KeywordSetKey.EMPTY);
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ if (LT(1) == IToken.tCOLONCOLON) {
+ // global scope
+ consume(IToken.tCOLONCOLON);
+ }
+ consume(IToken.t_new);
+ boolean typeIdInParen = false;
+ boolean placementParseFailure = true;
+ IToken beforeSecondParen = null;
+ IToken backtrackMarker = null;
+ IASTTypeId typeId = null;
+ ArrayList newPlacementExpressions = new ArrayList();
+ ArrayList newTypeIdExpressions = new ArrayList();
+ ArrayList newInitializerExpressions = new ArrayList();
+
+ if (LT(1) == IToken.tLPAREN) {
+ consume(IToken.tLPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+ try {
+ // Try to consume placement list
+ // Note: since expressionList and expression are the same...
+ backtrackMarker = mark();
+ newPlacementExpressions.add(expression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE, key));
+ consume(IToken.tRPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ } //pop 1st Parent
+ placementParseFailure = false;
+ if (LT(1) == IToken.tLPAREN) {
+ beforeSecondParen = mark();
+ consume(IToken.tLPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ } //push 2nd Paren
+ typeIdInParen = true;
+ }
+ } catch (BacktrackException e) {
+ backup(backtrackMarker);
+ }
+ if (placementParseFailure) {
+ // CASE: new (typeid-not-looking-as-placement) ...
+ // the first expression in () is not a placement
+ // - then it has to be typeId
+ typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE);
+ consume(IToken.tRPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ } //pop 1st Paren
+ } else {
+ if (!typeIdInParen) {
+ if (LT(1) == IToken.tLBRACKET) {
+ // CASE: new (typeid-looking-as-placement) [expr]...
+ // the first expression in () has been parsed as a placement;
+ // however, we assume that it was in fact typeId, and this
+ // new statement creates an array.
+ // Do nothing, fallback to array/initializer processing
+ } else {
+ // CASE: new (placement) typeid ...
+ // the first expression in () is parsed as a placement,
+ // and the next expression doesn't start with '(' or '['
+ // - then it has to be typeId
+ try {
+ backtrackMarker = mark();
+ typeId = typeId(scope, true,
+ CompletionKind.NEW_TYPE_REFERENCE);
+ } catch (BacktrackException e) {
+ // Hmmm, so it wasn't typeId after all... Then it is
+ // CASE: new (typeid-looking-as-placement)
+ backup(backtrackMarker);
+ // TODO fix this
+ return null;
+ }
+ }
+ } else {
+ // Tricky cases: first expression in () is parsed as a placement,
+ // and the next expression starts with '('.
+ // The problem is, the first expression might as well be a typeid
+ try {
+ typeId = typeId(scope, true,
+ CompletionKind.NEW_TYPE_REFERENCE);
+ consume(IToken.tRPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ } //popping the 2nd Paren
+
+ if (LT(1) == IToken.tLPAREN
+ || LT(1) == IToken.tLBRACKET) {
+ // CASE: new (placement)(typeid)(initializer)
+ // CASE: new (placement)(typeid)[] ...
+ // Great, so far all our assumptions have been correct
+ // Do nothing, fallback to array/initializer processing
+ } else {
+ // CASE: new (placement)(typeid)
+ // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid)
+ // Worst-case scenario - this cannot be resolved w/o more semantic information.
+ // Luckily, we don't need to know what was that - we only know that
+ // new-expression ends here.
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ setCompletionValues(scope,
+ CompletionKind.NO_SUCH_KIND,
+ KeywordSetKey.EMPTY);
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.NEW_TYPEID, null,
+ null, null, typeId, null, EMPTY_STRING,
+ astFactory.createNewDescriptor(
+ newPlacementExpressions,
+ newTypeIdExpressions,
+ newInitializerExpressions));
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "newExpression_1::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ }
+ } catch (BacktrackException e) {
+ // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
+ // Fallback to initializer processing
+ backup(beforeSecondParen);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }//pop that 2nd paren
+ }
+ }
+ }
+ } else {
+ // CASE: new typeid ...
+ // new parameters do not start with '('
+ // i.e it has to be a plain typeId
+ typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE);
+ }
+ while (LT(1) == IToken.tLBRACKET) {
+ // array new
+ consume();
+
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLBRACKET);
+ }
+
+ newTypeIdExpressions.add(assignmentExpression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE, key));
+ consume(IToken.tRBRACKET);
+
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ }
+ // newinitializer
+ if (LT(1) == IToken.tLPAREN) {
+ consume(IToken.tLPAREN);
+ setCurrentFunctionName(((typeId != null) ? typeId
+ .getFullSignatureCharArray() : EMPTY_STRING));
+ setCompletionValues(scope, CompletionKind.CONSTRUCTOR_REFERENCE);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+
+ //we want to know the difference between no newInitializer and an empty new Initializer
+ //if the next token is the RPAREN, then we have an Empty expression in our list.
+ newInitializerExpressions.add(expression(scope,
+ CompletionKind.CONSTRUCTOR_REFERENCE, key));
+
+ setCurrentFunctionName(EMPTY_STRING);
+ consume(IToken.tRPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ }
+ setCompletionValues(scope, CompletionKind.NO_SUCH_KIND,
+ KeywordSetKey.EMPTY);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.NEW_TYPEID, null, null, null, typeId,
+ null, EMPTY_STRING, astFactory.createNewDescriptor(
+ newPlacementExpressions, newTypeIdExpressions,
+ newInitializerExpressions));
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ return null;
+ } catch (Exception e) {
+ logException("newExpression_2::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ return null;
+ }
+
+ /**
+ * @param functionName
+ */
+ protected void setCurrentFunctionName(char[] functionName) {
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ public IASTExpression unaryExpression(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key) throws EndOfFileException, BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ switch (LT(1)) {
+ case IToken.tSTAR :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION, kind,
+ key);
+ case IToken.tAMPER :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION, kind,
+ key);
+ case IToken.tPLUS :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION, kind,
+ key);
+ case IToken.tMINUS :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION, kind,
+ key);
+ case IToken.tNOT :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION, kind, key);
+ case IToken.tCOMPL :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION, kind,
+ key);
+ case IToken.tINCR :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_INCREMENT, kind, key);
+ case IToken.tDECR :
+ consume();
+ return unaryOperatorCastExpression(scope,
+ IASTExpression.Kind.UNARY_DECREMENT, kind, key);
+ case IToken.t_sizeof :
+ consume(IToken.t_sizeof);
+ IToken mark = LA(1);
+ IASTTypeId d = null;
+ IASTExpression unaryExpression = null;
+ if (LT(1) == IToken.tLPAREN) {
+ try {
+ consume(IToken.tLPAREN);
+ d = typeId(scope, false,
+ CompletionKind.SINGLE_NAME_REFERENCE);
+ consume(IToken.tRPAREN);
+ } catch (BacktrackException bt) {
+ backup(mark);
+ unaryExpression = unaryExpression(scope, kind, key);
+ }
+ } else {
+ unaryExpression = unaryExpression(scope, kind, key);
+ }
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ if (unaryExpression == null)
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.UNARY_SIZEOF_TYPEID, null,
+ null, null, d, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION,
+ unaryExpression, null, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e1) {
+ throwBacktrack(e1.getProblem());
+ } catch (Exception e) {
+ logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ case IToken.t_new :
+ return newExpression(scope, key);
+ case IToken.t_delete :
+ return deleteExpression(scope, kind, key);
+ case IToken.tCOLONCOLON :
+ if (queryLookaheadCapability(2)) {
+ switch (LT(2)) {
+ case IToken.t_new :
+ return newExpression(scope, key);
+ case IToken.t_delete :
+ return deleteExpression(scope, kind, key);
+ default :
+ return postfixExpression(scope, kind, key);
+ }
+ }
+ default :
+ if (extension.isValidUnaryExpressionStart(LT(1))) {
+ IASTExpression extensionExpression = extension
+ .parseUnaryExpression(scope, this, kind, key);
+ if (extensionExpression != null)
+ return extensionExpression;
+ }
+ return postfixExpression(scope, kind, key);
+ }
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression postfixExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ IASTExpression firstExpression = null;
+ boolean isTemplate = false;
+
+ setCompletionValues(scope, kind, key);
+ switch (LT(1)) {
+ case IToken.t_typename :
+ consume(IToken.t_typename);
+
+ boolean templateTokenConsumed = false;
+ if (LT(1) == IToken.t_template) {
+ consume(IToken.t_template);
+ templateTokenConsumed = true;
+ }
+ ITokenDuple nestedName = name(scope,
+ CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY);
+
+ consume(IToken.tLPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+ IASTExpression expressionList = expression(scope,
+ CompletionKind.TYPE_REFERENCE, key);
+ int endOffset = consume(IToken.tRPAREN).getEndOffset();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+
+ try {
+ firstExpression = astFactory
+ .createExpression(
+ scope,
+ (templateTokenConsumed
+ ? IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID
+ : IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER),
+ expressionList, null, null, null,
+ nestedName, EMPTY_STRING, null);
+ } catch (ASTSemanticException ase) {
+ throwBacktrack(ase.getProblem());
+ } catch (Exception e) {
+ logException("postfixExpression_1::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ // simple-type-specifier ( assignment-expression , .. )
+ case IToken.t_char :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR, key);
+ break;
+ case IToken.t_wchar_t :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART, key);
+ break;
+ case IToken.t_bool :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL, key);
+ break;
+ case IToken.t_short :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT, key);
+ break;
+ case IToken.t_int :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT, key);
+ break;
+ case IToken.t_long :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG, key);
+ break;
+ case IToken.t_signed :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED, key);
+ break;
+ case IToken.t_unsigned :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED, key);
+ break;
+ case IToken.t_float :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT, key);
+ break;
+ case IToken.t_double :
+ firstExpression = simpleTypeConstructorExpression(scope,
+ IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE, key);
+ break;
+ case IToken.t_dynamic_cast :
+ firstExpression = specialCastExpression(scope,
+ IASTExpression.Kind.POSTFIX_DYNAMIC_CAST, key);
+ break;
+ case IToken.t_static_cast :
+ firstExpression = specialCastExpression(scope,
+ IASTExpression.Kind.POSTFIX_STATIC_CAST, key);
+ break;
+ case IToken.t_reinterpret_cast :
+ firstExpression = specialCastExpression(scope,
+ IASTExpression.Kind.POSTFIX_REINTERPRET_CAST, key);
+ break;
+ case IToken.t_const_cast :
+ firstExpression = specialCastExpression(scope,
+ IASTExpression.Kind.POSTFIX_CONST_CAST, key);
+ break;
+ case IToken.t_typeid :
+ consume();
+ consume(IToken.tLPAREN);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+ boolean isTypeId = true;
+ IASTExpression lhs = null;
+ IASTTypeId typeId = null;
+ try {
+ typeId = typeId(scope, false, CompletionKind.TYPE_REFERENCE);
+ } catch (BacktrackException b) {
+ isTypeId = false;
+ lhs = expression(scope, CompletionKind.TYPE_REFERENCE, key);
+ }
+ endOffset = consume(IToken.tRPAREN).getEndOffset();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ try {
+ firstExpression = astFactory
+ .createExpression(
+ scope,
+ (isTypeId
+ ? IASTExpression.Kind.POSTFIX_TYPEID_TYPEID
+ : IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION),
+ lhs, null, null, typeId, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e6) {
+ throwBacktrack(e6.getProblem());
+ } catch (Exception e) {
+ logException("postfixExpression_2::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ firstExpression = primaryExpression(scope, kind, key);
+ }
+ IASTExpression secondExpression = null;
+ for (;;) {
+ switch (LT(1)) {
+ case IToken.tLBRACKET :
+ // array access
+ consume(IToken.tLBRACKET);
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLBRACKET);
+ }
+ secondExpression = expression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE, key);
+ int endOffset = consume(IToken.tRBRACKET).getEndOffset();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.POSTFIX_SUBSCRIPT,
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e2) {
+ throwBacktrack(e2.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_3::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ case IToken.tLPAREN :
+ // function call
+ consume(IToken.tLPAREN);
+ IASTNode context = null;
+ if (firstExpression != null) {
+ if (firstExpression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION)
+ setCurrentFunctionName(firstExpression
+ .getIdExpressionCharArray());
+ else if (firstExpression.getRHSExpression() != null
+ && firstExpression.getRHSExpression()
+ .getIdExpressionCharArray() != null) {
+ setCurrentFunctionName(firstExpression
+ .getRHSExpression().getIdExpressionCharArray());
+ context = astFactory
+ .expressionToMostPreciseASTNode(scope,
+ firstExpression.getLHSExpression());
+ }
+ }
+
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+ setCompletionValues(scope,
+ CompletionKind.FUNCTION_REFERENCE, context);
+ secondExpression = expression(scope,
+ CompletionKind.FUNCTION_REFERENCE, key);
+ setCurrentFunctionName(EMPTY_STRING);
+ endOffset = consume(IToken.tRPAREN).getEndOffset();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.POSTFIX_FUNCTIONCALL,
+ firstExpression, secondExpression, null, null,
+ null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e3) {
+ throwBacktrack(e3.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_4::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ case IToken.tINCR :
+ endOffset = consume(IToken.tINCR).getEndOffset();
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.POSTFIX_INCREMENT,
+ firstExpression, null, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e1) {
+ throwBacktrack(e1.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_5::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ case IToken.tDECR :
+ endOffset = consume().getEndOffset();
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ IASTExpression.Kind.POSTFIX_DECREMENT,
+ firstExpression, null, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e4) {
+ throwBacktrack(e4.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_6::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ case IToken.tDOT :
+ // member access
+ consume(IToken.tDOT);
+
+ if (queryLookaheadCapability())
+ if (LT(1) == IToken.t_template) {
+ consume(IToken.t_template);
+ isTemplate = true;
+ }
+
+ Kind memberCompletionKind = (isTemplate
+ ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS
+ : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION);
+
+ setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE,
+ KeywordSetKey.EMPTY, firstExpression,
+ memberCompletionKind);
+ secondExpression = primaryExpression(scope,
+ CompletionKind.MEMBER_REFERENCE, key);
+ endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ if (secondExpression != null
+ && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION
+ && CharArrayUtils.indexOf( '~', secondExpression.getIdExpressionCharArray() ) != -1)
+ memberCompletionKind = Kind.POSTFIX_DOT_DESTRUCTOR;
+
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ memberCompletionKind, firstExpression,
+ secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e5) {
+ throwBacktrack(e5.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_7::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ case IToken.tARROW :
+ // member access
+ consume(IToken.tARROW);
+
+ if (queryLookaheadCapability())
+ if (LT(1) == IToken.t_template) {
+ consume(IToken.t_template);
+ isTemplate = true;
+ }
+
+ Kind arrowCompletionKind = (isTemplate
+ ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP
+ : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION);
+
+ setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE,
+ KeywordSetKey.EMPTY, firstExpression,
+ arrowCompletionKind);
+ secondExpression = primaryExpression(scope,
+ CompletionKind.MEMBER_REFERENCE, key);
+ endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ if (secondExpression != null
+ && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION
+ && CharArrayUtils.indexOf( '~', secondExpression.getIdExpressionCharArray() ) != -1)
+ arrowCompletionKind = Kind.POSTFIX_ARROW_DESTRUCTOR;
+ try {
+ firstExpression = astFactory.createExpression(scope,
+ arrowCompletionKind, firstExpression,
+ secondExpression, null, null, null,
+ EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "postfixExpression_8::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ break;
+ default :
+ return firstExpression;
+ }
+ }
+ }
+
+ /**
+ * @return
+ * @throws EndOfFileException
+ */
+ protected boolean queryLookaheadCapability(int count)
+ throws EndOfFileException {
+ //make sure we can look ahead one before doing this
+ boolean result = true;
+ try {
+ LA(count);
+ } catch (EndOfFileException olre) {
+ result = false;
+ }
+ return result;
+ }
+
+ protected boolean queryLookaheadCapability() throws EndOfFileException {
+ return queryLookaheadCapability(1);
+ }
+
+ protected void checkEndOfFile() throws EndOfFileException {
+ LA(1);
+ }
+
+ protected IASTExpression simpleTypeConstructorExpression(IASTScope scope,
+ Kind type, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ la = null;
+ char[] typeName = consume().getCharImage();
+ consume(IToken.tLPAREN);
+ setCurrentFunctionName(typeName);
+ IASTExpression inside = expression(scope,
+ CompletionKind.CONSTRUCTOR_REFERENCE, key);
+ setCurrentFunctionName(EMPTY_STRING);
+ int endOffset = consume(IToken.tRPAREN).getEndOffset();
+ try {
+ return astFactory.createExpression(scope, type, inside, null, null,
+ null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException(
+ "simpleTypeConstructorExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ return null;
+ }
+
+ /**
+ * @param expression
+ * @throws BacktrackException
+ */
+ protected IASTExpression primaryExpression(IASTScope scope,
+ CompletionKind kind, KeywordSetKey key) throws EndOfFileException,
+ BacktrackException {
+ IToken t = null;
+ switch (LT(1)) {
+ // TO DO: we need more literals...
+ case IToken.tINTEGER :
+ t = consume();
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_INTEGER_LITERAL, null,
+ null, null, null, null, t.getCharImage(), null);
+ } catch (ASTSemanticException e1) {
+ throwBacktrack(e1.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_1::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
+ }
+ case IToken.tFLOATINGPT :
+ t = consume();
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_FLOAT_LITERAL, null,
+ null, null, null, null, t.getCharImage(), null);
+ } catch (ASTSemanticException e2) {
+ throwBacktrack(e2.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_2::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
+ }
+ case IToken.tSTRING :
+ case IToken.tLSTRING :
+ t = consume();
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_STRING_LITERAL, null,
+ null, null, null, null, t.getCharImage(), null);
+ } catch (ASTSemanticException e5) {
+ throwBacktrack(e5.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_3::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
+ }
+
+ case IToken.t_false :
+ case IToken.t_true :
+ t = consume();
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL, null,
+ null, null, null, null, t.getCharImage(), null);
+ } catch (ASTSemanticException e3) {
+ throwBacktrack(e3.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_4::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename() );
+ }
+
+ case IToken.tCHAR :
+ case IToken.tLCHAR :
+
+ t = consume();
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_CHAR_LITERAL, null,
+ null, null, null, null, t.getCharImage(), null);
+ } catch (ASTSemanticException e4) {
+ throwBacktrack(e4.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_5::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
+ }
+
+ case IToken.t_this :
+ t = consume(IToken.t_this);
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_THIS, null, null, null,
+ null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e7) {
+ throwBacktrack(e7.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_6::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), t.getEndOffset(), t.getLineNumber(), t.getFilename());
+ }
+ case IToken.tLPAREN :
+ t = consume();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.push(IToken.tLPAREN);
+ }
+ IASTExpression lhs = expression(scope, kind, key);
+ int endOffset = consume(IToken.tRPAREN).getEndOffset();
+ if (templateIdScopes.size() > 0) {
+ templateIdScopes.pop();
+ }
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION,
+ lhs, null, null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e6) {
+ throwBacktrack(e6.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_7::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), endOffset, t.getLineNumber(), t.getFilename() );
+ }
+ case IToken.tIDENTIFIER :
+ case IToken.tCOLONCOLON :
+ case IToken.t_operator :
+ case IToken.tCOMPL :
+ ITokenDuple duple = null;
+ int startingOffset = LA(1).getOffset();
+ int line = LA(1).getLineNumber();
+ try {
+ duple = name(scope, kind, key);
+ } catch (BacktrackException bt) {
+ IToken mark = mark();
+ Declarator d = new Declarator(new DeclarationWrapper(scope,
+ mark.getOffset(), mark.getLineNumber(), null, mark.getFilename()));
+
+ if (LT(1) == IToken.tCOLONCOLON
+ || LT(1) == IToken.tIDENTIFIER) {
+ IToken start = consume();
+ IToken end = null;
+ if (start.getType() == IToken.tIDENTIFIER)
+ end = consumeTemplateParameters(end);
+ while (LT(1) == IToken.tCOLONCOLON
+ || LT(1) == IToken.tIDENTIFIER) {
+ end = consume();
+ if (end.getType() == IToken.tIDENTIFIER)
+ end = consumeTemplateParameters(end);
+ }
+ if (LT(1) == IToken.t_operator)
+ operatorId(d, start, null, kind);
+ else {
+ backup(mark);
+ throwBacktrack(startingOffset, end.getEndOffset(), end.getLineNumber(), t.getFilename());
+ }
+ } else if (LT(1) == IToken.t_operator)
+ operatorId(d, null, null, kind);
+
+ duple = d.getNameDuple();
+ }
+
+ endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope,
+ IASTExpression.Kind.ID_EXPRESSION, null, null,
+ null, null, duple, EMPTY_STRING, null);
+ } catch (ASTSemanticException e8) {
+ throwBacktrack(e8.getProblem());
+ } catch (Exception e) {
+ logException("primaryExpression_8::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, duple.getFilename());
+ }
+ default :
+ IToken la= LA(1);
+ startingOffset = la.getOffset();
+ line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ if (!queryLookaheadCapability(2)) {
+ if (LA(1).canBeAPrefix()) {
+ consume();
+ checkEndOfFile();
+ }
+ }
+ IASTExpression empty = null;
+ try {
+ empty = astFactory.createExpression(scope,
+ IASTExpression.Kind.PRIMARY_EMPTY, null, null,
+ null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e9) {
+ throwBacktrack( e9.getProblem() );
+ return null;
+ } catch (Exception e) {
+ logException("primaryExpression_9::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, 0, line, fn);
+ }
+ return empty;
+ }
+
+ }
+
+ /**
+ * Fetches a token from the scanner.
+ *
+ * @return the next token from the scanner
+ * @throws EndOfFileException thrown when the scanner.nextToken() yields no tokens
+ */
+ protected IToken fetchToken() throws EndOfFileException {
+ if (limitReached)
+ throw new EndOfFileException();
+
+ try {
+ IToken value = scanner.nextToken();
+ return value;
+ } catch (OffsetLimitReachedException olre) {
+ limitReached = true;
+ handleOffsetLimitException(olre);
+ return null;
+ }
+ }
+
+ /**
+ * @param value
+ */
+ protected void handleNewToken(IToken value) {
+ }
+
+ protected void handleOffsetLimitException(
+ OffsetLimitReachedException exception) throws EndOfFileException {
+ // unexpected, throw EOF instead (equivalent)
+ throw new EndOfFileException();
+ }
+
+ protected IASTExpression assignmentOperatorExpression(IASTScope scope,
+ IASTExpression.Kind kind, IASTExpression lhs,
+ CompletionKind completionKind, KeywordSetKey key)
+ throws EndOfFileException, BacktrackException {
+ IToken t = consume();
+ IASTExpression assignmentExpression = assignmentExpression(scope,
+ completionKind, key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope, kind, lhs,
+ assignmentExpression, null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("assignmentOperatorExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(t.getOffset(), endOffset, t.getLineNumber(), t.getFilename());
+ }
+ return null;
+ }
+
+ protected void setCompletionValues(IASTScope scope,
+ IASTCompletionNode.CompletionKind kind, KeywordSetKey key)
+ throws EndOfFileException {
+ }
+
+ protected void setCompletionValues(IASTScope scope,
+ IASTCompletionNode.CompletionKind kind, KeywordSetKey key,
+ IASTNode node, String prefix) throws EndOfFileException {
+ }
+
+ protected void setCompletionValues(IASTScope scope, CompletionKind kind,
+ KeywordSetKey key, IASTExpression firstExpression,
+ Kind expressionKind) throws EndOfFileException {
+ }
+
+ protected void setCompletionValues(IASTScope scope, CompletionKind kind,
+ IToken first, IToken last, KeywordSetKey key)
+ throws EndOfFileException {
+ }
+
+ protected IASTExpression unaryOperatorCastExpression(IASTScope scope,
+ IASTExpression.Kind kind, CompletionKind completionKind,
+ KeywordSetKey key) throws EndOfFileException, BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ la = null;
+ IASTExpression castExpression = castExpression(scope, completionKind,
+ key);
+ int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0;
+ try {
+ return astFactory.createExpression(scope, kind, castExpression,
+ null, null, null, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("unaryOperatorCastExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn);
+ }
+ return null;
+ }
+
+ protected IASTExpression specialCastExpression(IASTScope scope,
+ IASTExpression.Kind kind, KeywordSetKey key)
+ throws EndOfFileException, BacktrackException {
+ IToken la = LA(1);
+ int startingOffset = la.getOffset();
+ int line = la.getLineNumber();
+ char [] fn = la.getFilename();
+ la = null;
+
+ consume();
+ consume(IToken.tLT);
+ IASTTypeId duple = typeId(scope, false, CompletionKind.TYPE_REFERENCE);
+ consume(IToken.tGT);
+ consume(IToken.tLPAREN);
+ IASTExpression lhs = expression(scope,
+ CompletionKind.SINGLE_NAME_REFERENCE, key);
+ int endOffset = consume(IToken.tRPAREN).getEndOffset();
+ try {
+ return astFactory.createExpression(scope, kind, lhs, null, null,
+ duple, null, EMPTY_STRING, null);
+ } catch (ASTSemanticException e) {
+ throwBacktrack(e.getProblem());
+ } catch (Exception e) {
+ logException("specialCastExpression::createExpression()", e); //$NON-NLS-1$
+ throwBacktrack(startingOffset, endOffset, line, fn );
+ }
+ return null;
+ }
+
+
+ protected boolean isCancelled = false;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.IParserData#getLastToken()
+ */
+ public IToken getLastToken() {
+ return lastToken;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.IParserData#getParserLanguage()
+ */
+ public final ParserLanguage getParserLanguage() {
+ return language;
+ }
+ /**
+ * Parse an identifier.
+ *
+ * @throws BacktrackException request a backtrack
+ */
+ public IToken identifier() throws EndOfFileException, BacktrackException {
+ IToken first = consume(IToken.tIDENTIFIER); // throws backtrack if its not that
+ if( first instanceof ITokenDuple ) setGreaterNameContext((ITokenDuple) first);
+ return first;
+ }
+
+
+ public boolean validateCaches() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return scanner.toString(); //$NON-NLS-1$
+ }
+
+ /**
+ * @return Returns the backtrackCount.
+ */
+ public final int getBacktrackCount() {
+ return backtrackCount;
+ }
+
+ /**
+ * @param bt
+ */
+ protected void throwBacktrack(BacktrackException bt) throws BacktrackException {
+ throw bt;
+ }
+
+ /**
+ * @throws EndOfFileException
+ */
+ protected void errorHandling() throws EndOfFileException {
+ int depth = ( LT(1) == IToken.tLBRACE ) ? 1 : 0;
+ int type = consume().getType();
+ if( type == IToken.tSEMI ) return;
+ while (!((LT(1) == IToken.tSEMI && depth == 0)
+ || (LT(1) == IToken.tRBRACE && depth == 1)))
+ {
+ switch (LT(1))
+ {
+ case IToken.tLBRACE :
+ ++depth;
+ break;
+ case IToken.tRBRACE :
+ --depth;
+ break;
+ }
+ if( depth < 0 )
+ return;
+
+ consume();
+ }
+ // eat the SEMI/RBRACE as well
+ consume();
+ }
+
private static final int DEFAULT_DESIGNATOR_LIST_SIZE = 4;
protected ISourceElementRequestor requestor = null;
private IProblemFactory problemFactory = new ParserProblemFactory();
@@ -87,7 +2922,11 @@ public abstract class Parser extends ExpressionParser implements IParser
ParserLanguage language,
IParserLogService log, IParserExtension extension )
{
- super( scanner, language, log, extension );
+ this.scanner = scanner;
+ this.language = language;
+ this.log = log;
+ this.extension = extension;
+ setupASTFactory(scanner, language);
requestor = callback;
}
@@ -116,14 +2955,14 @@ public abstract class Parser extends ExpressionParser implements IParser
{
requestor.acceptProblem( bt.getProblem() );
}
- super.failParse();
+ failParse();
}
protected void failParse( IProblem problem ){
if( problem != null ){
requestor.acceptProblem( problem );
}
- super.failParse();
+ failParse();
}
// counter that keeps track of the number of times Parser.parse() is called