diff options
author | Mike Kucera | 2008-05-02 15:30:01 +0000 |
---|---|---|
committer | Mike Kucera | 2008-05-02 15:30:01 +0000 |
commit | 749ea1343156dcd1b1af8fc58f5323b853914e4a (patch) | |
tree | 372221817fa977ae3d86b895e82781551b59985d /lrparser/org.eclipse.cdt.core.lrparser/src | |
parent | 0c05265d7d2c385e958506b4696ecd5d1c7aa173 (diff) | |
download | org.eclipse.cdt-749ea1343156dcd1b1af8fc58f5323b853914e4a.tar.gz org.eclipse.cdt-749ea1343156dcd1b1af8fc58f5323b853914e4a.tar.xz org.eclipse.cdt-749ea1343156dcd1b1af8fc58f5323b853914e4a.zip |
fixed problem with "template<class T, class U = T>" not parsing correctly
Diffstat (limited to 'lrparser/org.eclipse.cdt.core.lrparser/src')
3 files changed, 54 insertions, 15 deletions
diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java index 8547b421228..906a87f26d3 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java @@ -297,12 +297,12 @@ public abstract class BuildASTParserAction { * * @throws NullPointerException if source or pattern is null */ - public static boolean matchTokens(List<IToken> source, Integer ... pattern) { + public static boolean matchTokens(List<IToken> source, ITokenMap tokenMap, Integer ... pattern) { if(source.size() != pattern.length) // throws NPE if either parameter is null return false; for(int i = 0, n = pattern.length; i < n; i++) { - if(source.get(i).getKind() != pattern[i].intValue()) + if(tokenMap.mapKind(source.get(i).getKind()) != pattern[i].intValue()) return false; } return true; @@ -352,7 +352,6 @@ public abstract class BuildASTParserAction { * was not parsed. */ public void consumeEmpty() { - if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); astStack.push(null); } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ScopedStack.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ScopedStack.java index e04cdd09fd4..e0606d6f93e 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ScopedStack.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ScopedStack.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.lrparser.action; import static org.eclipse.cdt.core.parser.util.CollectionUtils.reverseIterable; +import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; @@ -79,11 +80,11 @@ public class ScopedStack<T> { } /** - * Marks the stack then pushes all the items in the given list. + * Opens a scope then pushes all the items in the given list. * * @throws NullPointerException if items is null */ - public void openScope(List<T> items) { + public void openScope(Collection<T> items) { openScope(); for(T item : items) push(item); diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java index 110e6013eab..85c0b9c2084 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java @@ -409,22 +409,22 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { - private static OverloadableOperator getOverloadableOperator(List<IToken> tokens) { + private OverloadableOperator getOverloadableOperator(List<IToken> tokens) { if(tokens.size() == 1) { // TODO this is a hack that I did to save time LPGTokenAdapter coreToken = (LPGTokenAdapter) tokens.get(0); return OverloadableOperator.valueOf(coreToken.getWrappedToken()); } - else if(matchTokens(tokens, TK_new, TK_LeftBracket, TK_RightBracket)) { + else if(matchTokens(tokens, tokenMap, TK_new, TK_LeftBracket, TK_RightBracket)) { return OverloadableOperator.NEW_ARRAY; } - else if(matchTokens(tokens, TK_delete, TK_LeftBracket, TK_RightBracket)) { + else if(matchTokens(tokens, tokenMap, TK_delete, TK_LeftBracket, TK_RightBracket)) { return OverloadableOperator.DELETE_ARRAY; } - else if(matchTokens(tokens, TK_LeftBracket, TK_RightBracket)) { + else if(matchTokens(tokens, tokenMap, TK_LeftBracket, TK_RightBracket)) { return OverloadableOperator.BRACKET; } - else if(matchTokens(tokens, TK_LeftParen, TK_RightParen)) { + else if(matchTokens(tokens, tokenMap, TK_LeftParen, TK_RightParen)) { return OverloadableOperator.PAREN; } @@ -1209,7 +1209,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { List<IToken> ruleTokens = parser.getRuleTokens(); // do not generate nodes for extra EOC tokens - if(matchTokens(ruleTokens, CPPParsersym.TK_EndOfCompletion)) { + if(matchTokens(ruleTokens, tokenMap, TK_EndOfCompletion)) { return; } if(declSpecifier == null) { // can happen if implicit int is used @@ -1715,6 +1715,9 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { IASTTypeId typeId = hasTypeId ? (IASTTypeId)astStack.pop() : null; IASTName name = (IASTName)astStack.pop(); + if(name == null) + name = nodeFactory.newName(); + int type = getTemplateParameterType(parser.getLeftIToken()); ICPPASTSimpleTypeTemplateParameter templateParameter = nodeFactory.newSimpleTypeTemplateParameter(type, name, typeId); @@ -1746,21 +1749,57 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { * * This method detects the incorrect parse, throws away the incorrect AST fragment, * and replaces it with the correct AST fragment. + * + * Yes its a hack, but it took way less time to just do this than to refactor the grammar. + * + * TODO: there are more ambiguities with templates, maybe some double parsing is in order. */ public void consumeTemplateParamterDeclaration() { if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); + + List<IToken> ruleTokens = parser.getRuleTokens(); - if(matchTokens(parser.getRuleTokens(), TK_class, TK_identifier)) { - astStack.pop(); // throw away the ICPPASTParameterDeclaration - IASTName name = createName(parser.getRightIToken()); - astStack.push(name); + if(matchTokens(ruleTokens, tokenMap, TK_class)) { + astStack.pop(); + astStack.push(null); consumeSimpleTypeTemplateParameter(false); } + else if(matchTokens(ruleTokens, tokenMap, TK_class, TK_identifier)) { + astStack.pop(); + astStack.push(createName(ruleTokens.get(1))); + consumeSimpleTypeTemplateParameter(false); + } + else if(matchTokens(ruleTokens, tokenMap, TK_class, TK_Assign, TK_identifier)) { + astStack.pop(); + IASTName typeName = createName(ruleTokens.get(3)); + fixTemplateParameterDeclarationWithInitializer(null, typeName); + } + else if(matchTokens(ruleTokens, tokenMap, TK_class, TK_identifier, TK_Assign, TK_identifier)) { + astStack.pop(); + IASTName name = createName(ruleTokens.get(1)); + IASTName typeName = createName(ruleTokens.get(3)); + fixTemplateParameterDeclarationWithInitializer(name, typeName); + } if(TRACE_AST_STACK) System.out.println(astStack); } + /** + * Manually create the AST for a template parameter with initializer. + */ + private void fixTemplateParameterDeclarationWithInitializer(IASTName name, IASTName typeName) { + astStack.push(name); + ICPPASTNamedTypeSpecifier namedTypeSpecifier = nodeFactory.newCPPNamedTypeSpecifier(typeName, false); + setOffsetAndLength(namedTypeSpecifier, offset(typeName), length(typeName)); + IASTDeclarator declarator = nodeFactory.newDeclarator(nodeFactory.newName()); + IASTTypeId typeId = nodeFactory.newTypeId(namedTypeSpecifier, declarator); + setOffsetAndLength(typeId, offset(typeName), length(typeName)); + astStack.push(typeId); + consumeSimpleTypeTemplateParameter(true); + } + + /** * type_parameter |