1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

secondary parser to solve cast ambiguity in C++

This commit is contained in:
Mike Kucera 2008-02-14 22:31:55 +00:00
parent 743d1d04ee
commit 30fa8e597b
9 changed files with 5085 additions and 18 deletions

View file

@ -18,6 +18,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.c99.C99Language;
import org.eclipse.cdt.core.dom.lrparser.cpp.ISOCPPLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2Tests;
import org.eclipse.cdt.internal.core.parser.ParserException;
@ -39,18 +41,21 @@ public class C99Tests extends AST2Tests {
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
if(lang != ParserLanguage.C)
return super.parse(code, lang, useGNUExtensions, expectNoProblems);
return ParseHelper.parse(code, getLanguage(), expectNoProblems);
@Override
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
ILanguage language = lang.isCPP() ? getCPPLanguage() : getC99Language();
return ParseHelper.parse(code, language, expectNoProblems);
}
protected BaseExtensibleLanguage getLanguage() {
protected ILanguage getC99Language() {
return C99Language.getDefault();
}
protected ILanguage getCPPLanguage() {
return ISOCPPLanguage.getDefault();
}
public void testMultipleHashHash() throws Exception {
String code = "#define TWICE(a) int a##tera; int a##ther; \n TWICE(pan)";

View file

@ -60,6 +60,10 @@
<antcall target="generate-cpp">
<param name="grammar_name" value="CPPExpressionStatementParser"/>
</antcall>
<!-- Generate parser for disambiguating cast expressions vs binary expressions-->
<antcall target="generate-cpp">
<param name="grammar_name" value="CPPNoCastExpressionParser"/>
</antcall>
</target>

View file

@ -0,0 +1,36 @@
-----------------------------------------------------------------------------------
-- 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
$Import
CPPGrammar.g
$DropRules
cast_expression
::= '(' type_id ')' cast_expression
$End
$Start
no_cast_start
$End
$Rules
no_cast_start
::= expression
| ERROR_TOKEN
/. $Build consumeExpressionProblem(); $EndBuild ./
$End

View file

@ -52,7 +52,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
@ -65,18 +64,12 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.lrparser.IParser;
import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider;
import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99NoCastExpressionParser;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTAmbiguity;
/**
@ -137,6 +130,14 @@ public abstract class BuildASTParserAction {
protected abstract IParser getExpressionStatementParser();
/**
* Expression parser that does not recognize cast expressions,
* used to disambiguate casts.
*/
protected abstract IParser getNoCastExpressionParser();
/**
* Create a new parser action.
* @param tu Root node of the AST, its list of declarations should be empty.
@ -538,8 +539,6 @@ public abstract class BuildASTParserAction {
/**
* @param operator constant for {@link ICPPASTCastExpression}
*
* TODO Remove C99 specific code
*/
public void consumeExpressionCast(int operator) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
@ -550,7 +549,7 @@ public abstract class BuildASTParserAction {
setOffsetAndLength(expr);
// try parsing as non-cast to resolve ambiguities
IParser secondaryParser = new C99NoCastExpressionParser(C99Parsersym.orderedTerminalSymbols);
IParser secondaryParser = getNoCastExpressionParser();
IASTNode alternateExpr = runSecondaryParser(secondaryParser);
if(alternateExpr == null || alternateExpr instanceof IASTProblemExpression)
@ -881,7 +880,7 @@ public abstract class BuildASTParserAction {
decl = nodeFactory.newDeclarator(nodeFactory.newName());
for(Object pointer : astStack.closeScope())
decl.addPointerOperator((IASTPointer)pointer);
decl.addPointerOperator((IASTPointerOperator)pointer);
setOffsetAndLength(decl);
astStack.push(decl);

View file

@ -143,7 +143,10 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
return new C99ExpressionStatementParser(C99Parsersym.orderedTerminalSymbols);
}
@Override
protected IParser getNoCastExpressionParser() {
return new C99NoCastExpressionParser(C99Parsersym.orderedTerminalSymbols);
}
@ -152,6 +155,9 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
********************************************************************/
/**
* postfix_expression ::= postfix_expression '.' ident
* postfix_expression ::= postfix_expression '->' ident

View file

@ -89,6 +89,7 @@ import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99ExpressionStatementParser;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPExpressionStatementParser;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPNoCastExpressionParser;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPParsersym;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
@ -127,6 +128,12 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
return new CPPExpressionStatementParser(CPPParsersym.orderedTerminalSymbols);
}
@Override
protected IParser getNoCastExpressionParser() {
return new CPPNoCastExpressionParser(CPPParsersym.orderedTerminalSymbols);
}
// /**
// * Used only for debugging purposes.
// *
@ -155,6 +162,8 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
/**
* new_expression
* ::= dcolon_opt 'new' new_placement_opt new_type_id <openscope-ast> new_array_expressions_op new_initializer_opt

View file

@ -0,0 +1,270 @@
/*******************************************************************************
* 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 CPPNoCastExpressionParsersym {
public final static int
TK_asm = 64,
TK_auto = 49,
TK_bool = 13,
TK_break = 76,
TK_case = 77,
TK_catch = 116,
TK_char = 14,
TK_class = 58,
TK_const = 47,
TK_const_cast = 26,
TK_continue = 78,
TK_default = 79,
TK_delete = 40,
TK_do = 80,
TK_double = 15,
TK_dynamic_cast = 27,
TK_else = 120,
TK_enum = 65,
TK_explicit = 50,
TK_export = 73,
TK_extern = 43,
TK_false = 28,
TK_float = 16,
TK_for = 81,
TK_friend = 51,
TK_goto = 82,
TK_if = 83,
TK_inline = 52,
TK_int = 17,
TK_long = 18,
TK_mutable = 53,
TK_namespace = 62,
TK_new = 41,
TK_operator = 6,
TK_private = 117,
TK_protected = 118,
TK_public = 119,
TK_register = 54,
TK_reinterpret_cast = 29,
TK_return = 84,
TK_short = 19,
TK_signed = 20,
TK_sizeof = 30,
TK_static = 55,
TK_static_cast = 31,
TK_struct = 66,
TK_switch = 85,
TK_template = 45,
TK_this = 32,
TK_throw = 39,
TK_try = 74,
TK_true = 33,
TK_typedef = 56,
TK_typeid = 34,
TK_typename = 10,
TK_union = 67,
TK_unsigned = 21,
TK_using = 60,
TK_virtual = 46,
TK_void = 22,
TK_volatile = 48,
TK_wchar_t = 23,
TK_while = 75,
TK_integer = 35,
TK_floating = 36,
TK_charconst = 37,
TK_stringlit = 24,
TK_identifier = 1,
TK_Completion = 121,
TK_EndOfCompletion = 122,
TK_Invalid = 123,
TK_LeftBracket = 59,
TK_LeftParen = 2,
TK_LeftBrace = 57,
TK_Dot = 115,
TK_DotStar = 94,
TK_Arrow = 101,
TK_ArrowStar = 88,
TK_PlusPlus = 11,
TK_MinusMinus = 12,
TK_And = 7,
TK_Star = 5,
TK_Plus = 8,
TK_Minus = 9,
TK_Tilde = 4,
TK_Bang = 25,
TK_Slash = 89,
TK_Percent = 90,
TK_RightShift = 86,
TK_LeftShift = 87,
TK_LT = 61,
TK_GT = 63,
TK_LE = 91,
TK_GE = 92,
TK_EQ = 95,
TK_NE = 96,
TK_Caret = 97,
TK_Or = 98,
TK_AndAnd = 99,
TK_OrOr = 100,
TK_Question = 112,
TK_Colon = 70,
TK_ColonColon = 3,
TK_DotDotDot = 93,
TK_Assign = 69,
TK_StarAssign = 102,
TK_SlashAssign = 103,
TK_PercentAssign = 104,
TK_PlusAssign = 105,
TK_MinusAssign = 106,
TK_RightShiftAssign = 107,
TK_LeftShiftAssign = 108,
TK_AndAssign = 109,
TK_CaretAssign = 110,
TK_OrAssign = 111,
TK_Comma = 68,
TK_zero = 38,
TK_RightBracket = 113,
TK_RightParen = 72,
TK_RightBrace = 71,
TK_SemiColon = 42,
TK_ERROR_TOKEN = 44,
TK_EOF_TOKEN = 114;
public final static String orderedTerminalSymbols[] = {
"",
"identifier",
"LeftParen",
"ColonColon",
"Tilde",
"Star",
"operator",
"And",
"Plus",
"Minus",
"typename",
"PlusPlus",
"MinusMinus",
"bool",
"char",
"double",
"float",
"int",
"long",
"short",
"signed",
"unsigned",
"void",
"wchar_t",
"stringlit",
"Bang",
"const_cast",
"dynamic_cast",
"false",
"reinterpret_cast",
"sizeof",
"static_cast",
"this",
"true",
"typeid",
"integer",
"floating",
"charconst",
"zero",
"throw",
"delete",
"new",
"SemiColon",
"extern",
"ERROR_TOKEN",
"template",
"virtual",
"const",
"volatile",
"auto",
"explicit",
"friend",
"inline",
"mutable",
"register",
"static",
"typedef",
"LeftBrace",
"class",
"LeftBracket",
"using",
"LT",
"namespace",
"GT",
"asm",
"enum",
"struct",
"union",
"Comma",
"Assign",
"Colon",
"RightBrace",
"RightParen",
"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",
"Question",
"RightBracket",
"EOF_TOKEN",
"Dot",
"catch",
"private",
"protected",
"public",
"else",
"Completion",
"EndOfCompletion",
"Invalid"
};
public final static boolean isValidForParser = true;
}