1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

created secondary parser for disambiguating template parameter declarations

This commit is contained in:
Mike Kucera 2008-05-08 19:44:40 +00:00
parent f55cab3c2e
commit 19b5878bd9
6 changed files with 5202 additions and 43 deletions

View file

@ -88,6 +88,10 @@
<antcall target="generate_cpp">
<param name="grammar_name" value="CPPNoFunctionDeclaratorParser"/>
</antcall>
<!-- Generate parser for disambiguating template parameters -->
<antcall target="generate_cpp">
<param name="grammar_name" value="CPPTemplateTypeParameterParser"/>
</antcall>
</target>

View file

@ -0,0 +1,47 @@
-----------------------------------------------------------------------------------
-- Copyright (c) 2006, 2008 IBM Corporation and others.
-- All rights reserved. This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License v1.0
-- which accompanies this distribution, and is available at
-- http://www.eclipse.org/legal/epl-v10.html
--
-- Contributors:
-- IBM Corporation - initial API and implementation
-----------------------------------------------------------------------------------
%options la=2
%options package=org.eclipse.cdt.internal.core.dom.lrparser.cpp
%options template=btParserTemplateD.g
-- This parser is a bit of a hack.
-- There are ambiguities between type_parameter and parameter_declaration
-- when parsing a template_parameter.
-- I believe the correct disambiguation is to simply favor type_parameter
-- over parameter_declaration.
-- I have tried to resolve this by refactoring the grammar file so that
-- the parser will give precedence to type_parameter, but I have failed.
-- So the hacky solution is to reparse the tokens as a type_parameter and if
-- it succeeds, throw away the paramter_declaration and use the type_parameter
-- in its place.
$Import
CPPGrammar.g
$End
$Start
type_parameter_start
$End
$Rules
type_parameter_start
::= type_parameter
| ERROR_TOKEN
/. $Build consumeDeclarationProblem(); $EndBuild ./
$End

View file

@ -96,6 +96,7 @@ import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPNoCastExpressionParser;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPNoFunctionDeclaratorParser;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPParsersym;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPSizeofExpressionParser;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPTemplateTypeParameterParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
@ -148,12 +149,20 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
return new CPPNoCastExpressionParser(parser.getOrderedTerminalSymbols());
}
@Override
protected IParser getSizeofExpressionParser() {
return new CPPSizeofExpressionParser(parser.getOrderedTerminalSymbols());
}
protected IParser getTemplateTypeParameterParser() {
return new CPPTemplateTypeParameterParser(parser.getOrderedTerminalSymbols());
}
protected IParser getNoFunctionDeclaratorParser() {
return new CPPNoFunctionDeclaratorParser(parser.getOrderedTerminalSymbols());
}
/**
@ -1264,13 +1273,14 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
if(!(declarator instanceof IASTFunctionDeclarator))
return;
IParser secondaryParser = new CPPNoFunctionDeclaratorParser(parser.getOrderedTerminalSymbols());
IParser secondaryParser = getNoFunctionDeclaratorParser();
IASTNode alternateDeclarator = runSecondaryParser(secondaryParser);
if(alternateDeclarator == null || alternateDeclarator instanceof IASTProblemDeclaration)
return;
astStack.pop();
// TODO create node factory method for this
IASTNode ambiguityNode = new CPPASTAmbiguousDeclarator(declarator, (IASTDeclarator)alternateDeclarator);
setOffsetAndLength(ambiguityNode);
@ -1751,56 +1761,24 @@ 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.
* Yes its a hack.
*/
public void consumeTemplateParamterDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
List<IToken> ruleTokens = parser.getRuleTokens();
IParser typeParameterParser = getTemplateTypeParameterParser();
IASTNode alternate = runSecondaryParser(typeParameterParser);
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(alternate == null || alternate instanceof IASTProblemDeclaration)
return;
astStack.pop(); // throw away the incorrect AST
astStack.push(alternate); // replace it with the correct AST
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

View file

@ -0,0 +1,272 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl_v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*********************************************************************************/
// This file was generated by LPG
package org.eclipse.cdt.internal.core.dom.lrparser.cpp;
public interface CPPTemplateTypeParameterParsersym {
public final static int
TK_asm = 62,
TK_auto = 49,
TK_bool = 15,
TK_break = 78,
TK_case = 79,
TK_catch = 119,
TK_char = 16,
TK_class = 63,
TK_const = 46,
TK_const_cast = 32,
TK_continue = 80,
TK_default = 81,
TK_delete = 65,
TK_do = 82,
TK_double = 17,
TK_dynamic_cast = 33,
TK_else = 122,
TK_enum = 69,
TK_explicit = 50,
TK_export = 75,
TK_extern = 12,
TK_false = 34,
TK_float = 18,
TK_for = 83,
TK_friend = 51,
TK_goto = 84,
TK_if = 85,
TK_inline = 52,
TK_int = 19,
TK_long = 20,
TK_mutable = 53,
TK_namespace = 59,
TK_new = 66,
TK_operator = 7,
TK_private = 114,
TK_protected = 115,
TK_public = 116,
TK_register = 54,
TK_reinterpret_cast = 35,
TK_return = 86,
TK_short = 21,
TK_signed = 22,
TK_sizeof = 36,
TK_static = 55,
TK_static_cast = 37,
TK_struct = 70,
TK_switch = 87,
TK_template = 29,
TK_this = 38,
TK_throw = 60,
TK_try = 76,
TK_true = 39,
TK_typedef = 56,
TK_typeid = 40,
TK_typename = 10,
TK_union = 71,
TK_unsigned = 23,
TK_using = 57,
TK_virtual = 41,
TK_void = 24,
TK_volatile = 47,
TK_wchar_t = 25,
TK_while = 77,
TK_integer = 42,
TK_floating = 43,
TK_charconst = 44,
TK_stringlit = 30,
TK_identifier = 1,
TK_Completion = 2,
TK_EndOfCompletion = 9,
TK_Invalid = 124,
TK_LeftBracket = 48,
TK_LeftParen = 3,
TK_LeftBrace = 58,
TK_Dot = 120,
TK_DotStar = 96,
TK_Arrow = 103,
TK_ArrowStar = 90,
TK_PlusPlus = 26,
TK_MinusMinus = 27,
TK_And = 8,
TK_Star = 6,
TK_Plus = 13,
TK_Minus = 14,
TK_Tilde = 5,
TK_Bang = 31,
TK_Slash = 91,
TK_Percent = 92,
TK_RightShift = 88,
TK_LeftShift = 89,
TK_LT = 28,
TK_GT = 61,
TK_LE = 93,
TK_GE = 94,
TK_EQ = 97,
TK_NE = 98,
TK_Caret = 99,
TK_Or = 100,
TK_AndAnd = 101,
TK_OrOr = 102,
TK_Question = 117,
TK_Colon = 72,
TK_ColonColon = 4,
TK_DotDotDot = 95,
TK_Assign = 67,
TK_StarAssign = 104,
TK_SlashAssign = 105,
TK_PercentAssign = 106,
TK_PlusAssign = 107,
TK_MinusAssign = 108,
TK_RightShiftAssign = 109,
TK_LeftShiftAssign = 110,
TK_AndAssign = 111,
TK_CaretAssign = 112,
TK_OrAssign = 113,
TK_Comma = 64,
TK_zero = 45,
TK_RightBracket = 118,
TK_RightParen = 73,
TK_RightBrace = 68,
TK_SemiColon = 11,
TK_ERROR_TOKEN = 74,
TK_original_namespace_name = 123,
TK_EOF_TOKEN = 121;
public final static String orderedTerminalSymbols[] = {
"",
"identifier",
"Completion",
"LeftParen",
"ColonColon",
"Tilde",
"Star",
"operator",
"And",
"EndOfCompletion",
"typename",
"SemiColon",
"extern",
"Plus",
"Minus",
"bool",
"char",
"double",
"float",
"int",
"long",
"short",
"signed",
"unsigned",
"void",
"wchar_t",
"PlusPlus",
"MinusMinus",
"LT",
"template",
"stringlit",
"Bang",
"const_cast",
"dynamic_cast",
"false",
"reinterpret_cast",
"sizeof",
"static_cast",
"this",
"true",
"typeid",
"virtual",
"integer",
"floating",
"charconst",
"zero",
"const",
"volatile",
"LeftBracket",
"auto",
"explicit",
"friend",
"inline",
"mutable",
"register",
"static",
"typedef",
"using",
"LeftBrace",
"namespace",
"throw",
"GT",
"asm",
"class",
"Comma",
"delete",
"new",
"Assign",
"RightBrace",
"enum",
"struct",
"union",
"Colon",
"RightParen",
"ERROR_TOKEN",
"export",
"try",
"while",
"break",
"case",
"continue",
"default",
"do",
"for",
"goto",
"if",
"return",
"switch",
"RightShift",
"LeftShift",
"ArrowStar",
"Slash",
"Percent",
"LE",
"GE",
"DotDotDot",
"DotStar",
"EQ",
"NE",
"Caret",
"Or",
"AndAnd",
"OrOr",
"Arrow",
"StarAssign",
"SlashAssign",
"PercentAssign",
"PlusAssign",
"MinusAssign",
"RightShiftAssign",
"LeftShiftAssign",
"AndAssign",
"CaretAssign",
"OrAssign",
"private",
"protected",
"public",
"Question",
"RightBracket",
"catch",
"Dot",
"EOF_TOKEN",
"else",
"original_namespace_name",
"Invalid"
};
public final static boolean isValidForParser = true;
}