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

fixed several bugs in new C++ parser

This commit is contained in:
Mike Kucera 2008-03-10 21:34:29 +00:00
parent 4ae9346289
commit 900ae2cb4b
16 changed files with 9668 additions and 9349 deletions

View file

@ -5583,8 +5583,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
struct A { struct A {
virtual void f(); virtual void f();
}; };
struct B1 : A { // note nonvirtual struct B1 : A { // note nonvirtual derivation
derivation
void f(); void f();
}; };
struct B2 : A { struct B2 : A {
@ -5609,8 +5608,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("struct A {\n"); //$NON-NLS-1$ buffer.append("struct A {\n"); //$NON-NLS-1$
buffer.append("virtual void f();\n"); //$NON-NLS-1$ buffer.append("virtual void f();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$ buffer.append("};\n"); //$NON-NLS-1$
buffer.append("struct B1 : A { // note nonvirtual\n"); //$NON-NLS-1$ buffer.append("struct B1 : A { // note nonvirtual derivation\n"); //$NON-NLS-1$
buffer.append("derivation\n"); //$NON-NLS-1$
buffer.append("void f();\n"); //$NON-NLS-1$ buffer.append("void f();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$ buffer.append("};\n"); //$NON-NLS-1$
buffer.append("struct B2 : A {\n"); //$NON-NLS-1$ buffer.append("struct B2 : A {\n"); //$NON-NLS-1$
@ -5741,20 +5739,21 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, 0); parse(buffer.toString(), ParserLanguage.CPP, true, 0);
} }
/** // Not legal C++
[--Start Example(CPP 10.4-2b): // /**
struct C { // [--Start Example(CPP 10.4-2b):
virtual void f() { }=0; // illformed // struct C {
}; // virtual void f() { }=0; // illformed
--End Example] // };
*/ // --End Example]
public void test10_4s2b() throws Exception { // */
StringBuffer buffer = new StringBuffer(); // public void test10_4s2b() throws Exception {
buffer.append("struct C {\n"); //$NON-NLS-1$ // StringBuffer buffer = new StringBuffer();
buffer.append("virtual void f() { }=0; // illformed\n"); //$NON-NLS-1$ // buffer.append("struct C {\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$ // buffer.append("virtual void f() { }=0; // illformed\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0); // buffer.append("};\n"); //$NON-NLS-1$
} // parse(buffer.toString(), ParserLanguage.CPP, true, 0);
// }
/** /**
[--Start Example(CPP 10.4-3): [--Start Example(CPP 10.4-3):

View file

@ -0,0 +1,40 @@
package org.eclipse.cdt.core.lrparser.tests.cpp;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.lrparser.tests.c99.ParseHelper;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPSpecTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class ISOCPPSpecTest extends AST2CPPSpecTest {
public ISOCPPSpecTest() { }
public ISOCPPSpecTest(String name) { super(name); }
@Override
protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings);
parse(code, ParserLanguage.CPP, checkBindings, expectedProblemBindings);
}
@Override
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
ILanguage language = lang.isCPP() ? getCPPLanguage() : getCLanguage();
return ParseHelper.parse(code, language, true, checkBindings, expectedProblemBindings );
}
protected BaseExtensibleLanguage getCLanguage() {
return C99Language.getDefault();
}
protected BaseExtensibleLanguage getCPPLanguage() {
return ISOCPPLanguage.getDefault();
}
}

View file

@ -805,8 +805,6 @@ constant_expression_opt
-- Statements -- Statements
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
-- TODO: declarations in conditions
statement statement
::= labeled_statement ::= labeled_statement
| expression_statement | expression_statement
@ -895,9 +893,13 @@ jump_statement
/. $Build consumeStatementGoto(); $EndBuild ./ /. $Build consumeStatementGoto(); $EndBuild ./
-- Nested functions are not part of the C++ spec, but several
-- of the parser test cases expect them to work.
declaration_statement declaration_statement
::= block_declaration ::= block_declaration
/. $Build consumeStatementDeclaration(); $EndBuild ./ /. $Build consumeStatementDeclaration(); $EndBuild ./
| function_definition -- not spec
/. $Build consumeStatementDeclaration(); $EndBuild ./
@ -908,20 +910,20 @@ declaration_statement
declaration declaration
::= block_declaration ::= block_declaration
| function_definition -- done | function_definition
| template_declaration -- done | template_declaration
| explicit_instantiation -- done | explicit_instantiation
| explicit_specialization -- done | explicit_specialization
| linkage_specification -- done | linkage_specification
| namespace_definition -- done | namespace_definition
block_declaration block_declaration
::= simple_declaration -- done ::= simple_declaration
| asm_definition -- done | asm_definition
| namespace_alias_definition -- done | namespace_alias_definition
| using_declaration -- done | using_declaration
| using_directive -- done | using_directive
declaration_seq declaration_seq
@ -1573,30 +1575,31 @@ base_specifier_list
| base_specifier_list ',' base_specifier | base_specifier_list ',' base_specifier
-- make this more lenient, allow virtual both before and after
base_specifier base_specifier
::= dcolon_opt nested_name_specifier_opt class_name ::= dcolon_opt nested_name_specifier_opt class_name
/. $Build consumeBaseSpecifier(false); $EndBuild ./ /. $Build consumeBaseSpecifier(false, false); $EndBuild ./
| virtual_opt access_specifier_keyword virtual_opt dcolon_opt nested_name_specifier_opt class_name | 'virtual' access_specifier_keyword_opt dcolon_opt nested_name_specifier_opt class_name
/. $Build consumeBaseSpecifier(true); $EndBuild ./ /. $Build consumeBaseSpecifier(true, true); $EndBuild ./
| access_specifier_keyword 'virtual' dcolon_opt nested_name_specifier_opt class_name
/. $Build consumeBaseSpecifier(true, true); $EndBuild ./
| access_specifier_keyword dcolon_opt nested_name_specifier_opt class_name
/. $Build consumeBaseSpecifier(true, false); $EndBuild ./
virtual_opt
::= 'virtual'
/. $Build consumePlaceHolder(); $EndBuild ./
| $empty
/. $Build consumeEmpty(); $EndBuild ./
access_specifier_keyword access_specifier_keyword
::= 'private' ::= 'private'
/. $Build consumeAccessKeywordToken(); $EndBuild ./
| 'protected' | 'protected'
/. $Build consumeAccessKeywordToken(); $EndBuild ./
| 'public' | 'public'
/. $Build consumeAccessKeywordToken(); $EndBuild ./
access_specifier_keyword_opt access_specifier_keyword_opt
::= access_specifier_keyword ::= access_specifier_keyword
| $empty | $empty
/. $Build consumeEmpty(); $EndBuild ./
conversion_function_id_name conversion_function_id_name
@ -1684,9 +1687,16 @@ template_parameter_list
| template_parameter_list ',' template_parameter | template_parameter_list ',' template_parameter
-- TODO There is an ambiguity in the spec grammar here,
-- "class X" should be parsed as a type_parameter
-- and not as a parameter_declaration. Here precedence is used to disambiguate
-- but it would be better to refactor the grammar to remove the conflict.
template_parameter template_parameter
::= type_parameter ::=? type_parameter
| parameter_declaration
template_parameter
::= parameter_declaration
type_parameter type_parameter

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.CPPParsersym; 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.CPPSizeofExpressionParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
/** /**
@ -389,6 +390,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
} }
@SuppressWarnings("restriction")
private static OverloadableOperator getOverloadableOperator(List<IToken> tokens) { private static OverloadableOperator getOverloadableOperator(List<IToken> tokens) {
if(tokens.size() == 1) { if(tokens.size() == 1) {
// TODO this is a hack that I did to save time // TODO this is a hack that I did to save time
@ -401,6 +403,12 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
else if(matchTokens(tokens, TK_delete, TK_LeftBracket, TK_RightBracket)) { else if(matchTokens(tokens, TK_delete, TK_LeftBracket, TK_RightBracket)) {
return OverloadableOperator.DELETE_ARRAY; return OverloadableOperator.DELETE_ARRAY;
} }
else if(matchTokens(tokens, TK_LeftBracket, TK_RightBracket)) {
return OverloadableOperator.BRACKET;
}
else if(matchTokens(tokens, TK_LeftParen, TK_RightParen)) {
return OverloadableOperator.PAREN;
}
return null; return null;
} }
@ -678,6 +686,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
/** /**
* Creates a qualified name from a list of names (that must be in reverse order). * Creates a qualified name from a list of names (that must be in reverse order).
*/ */
@SuppressWarnings("restriction")
private IASTName createQualifiedName(LinkedList<IASTName> nestedNames, boolean startsWithColonColon) { private IASTName createQualifiedName(LinkedList<IASTName> nestedNames, boolean startsWithColonColon) {
if(!startsWithColonColon && nestedNames.size() == 1) { // its actually an unqualified name if(!startsWithColonColon && nestedNames.size() == 1) { // its actually an unqualified name
return nestedNames.get(0); return nestedNames.get(0);
@ -686,8 +695,17 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName(); ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName();
qualifiedName.setFullyQualified(startsWithColonColon); qualifiedName.setFullyQualified(startsWithColonColon);
for(IASTName name : reverseIterable(nestedNames)) StringBuilder signature = new StringBuilder(startsWithColonColon ? "::" : ""); //$NON-NLS-1$ //$NON-NLS-2$
boolean first = true;
for(IASTName name : reverseIterable(nestedNames)) {
qualifiedName.addName(name); qualifiedName.addName(name);
if(!first)
signature.append("::"); //$NON-NLS-1$
signature.append(name.toString());
first = false;
}
((CPPASTQualifiedName)qualifiedName).setSignature(signature.toString());
int startOffset = offset(nestedNames.getLast()); int startOffset = offset(nestedNames.getLast());
int length = endOffset(nestedNames.getFirst()) - startOffset; int length = endOffset(nestedNames.getFirst()) - startOffset;
@ -863,7 +881,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
List<Object> declarations = astStack.closeScope(); List<Object> declarations = astStack.closeScope();
IASTName namespaceName = (hasName) ? (IASTName) astStack.pop() : null; IASTName namespaceName = hasName ? (IASTName)astStack.pop() : nodeFactory.newName();
ICPPASTNamespaceDefinition definition = nodeFactory.newNamespaceDefinition(namespaceName); ICPPASTNamespaceDefinition definition = nodeFactory.newNamespaceDefinition(namespaceName);
@ -1077,7 +1095,8 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeVisibilityLabel() { public void consumeVisibilityLabel() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
int visibility = getAccessSpecifier(parser.getLeftIToken()); IToken specifier = (IToken)astStack.pop();
int visibility = getAccessSpecifier(specifier);
ICPPASTVisiblityLabel visibilityLabel = nodeFactory.newVisibilityLabel(visibility); ICPPASTVisiblityLabel visibilityLabel = nodeFactory.newVisibilityLabel(visibility);
setOffsetAndLength(visibilityLabel); setOffsetAndLength(visibilityLabel);
astStack.push(visibilityLabel); astStack.push(visibilityLabel);
@ -1098,23 +1117,21 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
/** /**
* base_specifier * base_specifier
* ::= dcolon_opt nested_name_specifier_opt class_name * ::= dcolon_opt nested_name_specifier_opt class_name
* | virtual_opt access_specifier_keyword virtual_opt dcolon_opt nested_name_specifier_opt class_name * | 'virtual' access_specifier_keyword_opt dcolon_opt nested_name_specifier_opt class_name
* | access_specifier_keyword 'virtual' dcolon_opt nested_name_specifier_opt class_name
* | access_specifier_keyword dcolon_opt nested_name_specifier_opt class_name
*/ */
public void consumeBaseSpecifier(boolean hasAccessSpecifier) { public void consumeBaseSpecifier(boolean hasAccessSpecifier, boolean isVirtual) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = subRuleQualifiedName(false); IASTName name = subRuleQualifiedName(false);
boolean isVirtual = false;
int visibility = 0; // this is the default value that the DOM parser uses
int visibility = 0; // this is the default value that the DOM parser uses
if(hasAccessSpecifier) { if(hasAccessSpecifier) {
boolean hasVirtualKeyword2 = astStack.pop() == PLACE_HOLDER; IToken accessSpecifierToken = (IToken) astStack.pop();
boolean hasVirtualKeyword1 = astStack.pop() == PLACE_HOLDER; if(accessSpecifierToken != null)
isVirtual = hasVirtualKeyword1 | hasVirtualKeyword2; visibility = getAccessSpecifier(accessSpecifierToken);
IToken accessSpecifierToken = parser.getRuleTokens().get(hasVirtualKeyword1 ? 1 : 0);
visibility = getAccessSpecifier(accessSpecifierToken);
} }
ICPPASTBaseSpecifier baseSpecifier = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); ICPPASTBaseSpecifier baseSpecifier = nodeFactory.newBaseSpecifier(name, visibility, isVirtual);
@ -1125,6 +1142,18 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
} }
/**
* Gets the current token and places it on the stack for later consumption.
*/
public void consumeAccessKeywordToken() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
astStack.push(parser.getRightIToken());
if(TRACE_AST_STACK) System.out.println(astStack);
}
/** /**
* class_specifier * class_specifier
* ::= class_head '{' <openscope-ast> member_declaration_list_opt '}' * ::= class_head '{' <openscope-ast> member_declaration_list_opt '}'

View file

@ -20,7 +20,7 @@ public interface CPPExpressionStatementParsersym {
TK_bool = 15, TK_bool = 15,
TK_break = 77, TK_break = 77,
TK_case = 78, TK_case = 78,
TK_catch = 117, TK_catch = 120,
TK_char = 16, TK_char = 16,
TK_class = 59, TK_class = 59,
TK_const = 48, TK_const = 48,
@ -49,9 +49,9 @@ public interface CPPExpressionStatementParsersym {
TK_namespace = 67, TK_namespace = 67,
TK_new = 43, TK_new = 43,
TK_operator = 7, TK_operator = 7,
TK_private = 118, TK_private = 116,
TK_protected = 119, TK_protected = 117,
TK_public = 120, TK_public = 118,
TK_register = 55, TK_register = 55,
TK_reinterpret_cast = 31, TK_reinterpret_cast = 31,
TK_return = 86, TK_return = 86,
@ -89,7 +89,7 @@ public interface CPPExpressionStatementParsersym {
TK_LeftBracket = 66, TK_LeftBracket = 66,
TK_LeftParen = 3, TK_LeftParen = 3,
TK_LeftBrace = 64, TK_LeftBrace = 64,
TK_Dot = 116, TK_Dot = 119,
TK_DotStar = 96, TK_DotStar = 96,
TK_Arrow = 103, TK_Arrow = 103,
TK_ArrowStar = 90, TK_ArrowStar = 90,
@ -256,11 +256,11 @@ public interface CPPExpressionStatementParsersym {
"OrAssign", "OrAssign",
"Question", "Question",
"RightBracket", "RightBracket",
"Dot",
"catch",
"private", "private",
"protected", "protected",
"public", "public",
"Dot",
"catch",
"EOF_TOKEN", "EOF_TOKEN",
"else", "else",
"Invalid" "Invalid"

View file

@ -20,7 +20,7 @@ public interface CPPNoCastExpressionParsersym {
TK_bool = 15, TK_bool = 15,
TK_break = 77, TK_break = 77,
TK_case = 78, TK_case = 78,
TK_catch = 118, TK_catch = 121,
TK_char = 16, TK_char = 16,
TK_class = 60, TK_class = 60,
TK_const = 48, TK_const = 48,
@ -49,9 +49,9 @@ public interface CPPNoCastExpressionParsersym {
TK_namespace = 67, TK_namespace = 67,
TK_new = 43, TK_new = 43,
TK_operator = 7, TK_operator = 7,
TK_private = 119, TK_private = 117,
TK_protected = 120, TK_protected = 118,
TK_public = 121, TK_public = 119,
TK_register = 55, TK_register = 55,
TK_reinterpret_cast = 31, TK_reinterpret_cast = 31,
TK_return = 86, TK_return = 86,
@ -89,7 +89,7 @@ public interface CPPNoCastExpressionParsersym {
TK_LeftBracket = 66, TK_LeftBracket = 66,
TK_LeftParen = 3, TK_LeftParen = 3,
TK_LeftBrace = 61, TK_LeftBrace = 61,
TK_Dot = 117, TK_Dot = 120,
TK_DotStar = 96, TK_DotStar = 96,
TK_Arrow = 103, TK_Arrow = 103,
TK_ArrowStar = 90, TK_ArrowStar = 90,
@ -257,11 +257,11 @@ public interface CPPNoCastExpressionParsersym {
"Question", "Question",
"RightBracket", "RightBracket",
"EOF_TOKEN", "EOF_TOKEN",
"Dot",
"catch",
"private", "private",
"protected", "protected",
"public", "public",
"Dot",
"catch",
"else", "else",
"Invalid" "Invalid"
}; };

View file

@ -20,7 +20,7 @@ public interface CPPParsersym {
TK_bool = 13, TK_bool = 13,
TK_break = 78, TK_break = 78,
TK_case = 79, TK_case = 79,
TK_catch = 117, TK_catch = 120,
TK_char = 14, TK_char = 14,
TK_class = 59, TK_class = 59,
TK_const = 48, TK_const = 48,
@ -49,9 +49,9 @@ public interface CPPParsersym {
TK_namespace = 65, TK_namespace = 65,
TK_new = 44, TK_new = 44,
TK_operator = 7, TK_operator = 7,
TK_private = 118, TK_private = 116,
TK_protected = 119, TK_protected = 117,
TK_public = 120, TK_public = 118,
TK_register = 55, TK_register = 55,
TK_reinterpret_cast = 31, TK_reinterpret_cast = 31,
TK_return = 86, TK_return = 86,
@ -89,7 +89,7 @@ public interface CPPParsersym {
TK_LeftBracket = 68, TK_LeftBracket = 68,
TK_LeftParen = 3, TK_LeftParen = 3,
TK_LeftBrace = 66, TK_LeftBrace = 66,
TK_Dot = 116, TK_Dot = 119,
TK_DotStar = 96, TK_DotStar = 96,
TK_Arrow = 103, TK_Arrow = 103,
TK_ArrowStar = 90, TK_ArrowStar = 90,
@ -256,11 +256,11 @@ public interface CPPParsersym {
"OrAssign", "OrAssign",
"Question", "Question",
"RightBracket", "RightBracket",
"Dot",
"catch",
"private", "private",
"protected", "protected",
"public", "public",
"Dot",
"catch",
"EOF_TOKEN", "EOF_TOKEN",
"else", "else",
"Invalid" "Invalid"

View file

@ -20,7 +20,7 @@ public interface CPPSizeofExpressionParsersym {
TK_bool = 15, TK_bool = 15,
TK_break = 77, TK_break = 77,
TK_case = 78, TK_case = 78,
TK_catch = 118, TK_catch = 121,
TK_char = 16, TK_char = 16,
TK_class = 60, TK_class = 60,
TK_const = 48, TK_const = 48,
@ -49,9 +49,9 @@ public interface CPPSizeofExpressionParsersym {
TK_namespace = 65, TK_namespace = 65,
TK_new = 43, TK_new = 43,
TK_operator = 7, TK_operator = 7,
TK_private = 119, TK_private = 117,
TK_protected = 120, TK_protected = 118,
TK_public = 121, TK_public = 119,
TK_register = 56, TK_register = 56,
TK_reinterpret_cast = 31, TK_reinterpret_cast = 31,
TK_return = 86, TK_return = 86,
@ -89,7 +89,7 @@ public interface CPPSizeofExpressionParsersym {
TK_LeftBracket = 63, TK_LeftBracket = 63,
TK_LeftParen = 3, TK_LeftParen = 3,
TK_LeftBrace = 61, TK_LeftBrace = 61,
TK_Dot = 117, TK_Dot = 120,
TK_DotStar = 96, TK_DotStar = 96,
TK_Arrow = 103, TK_Arrow = 103,
TK_ArrowStar = 90, TK_ArrowStar = 90,
@ -257,11 +257,11 @@ public interface CPPSizeofExpressionParsersym {
"Question", "Question",
"RightBracket", "RightBracket",
"EOF_TOKEN", "EOF_TOKEN",
"Dot",
"catch",
"private", "private",
"protected", "protected",
"public", "public",
"Dot",
"catch",
"else", "else",
"Invalid" "Invalid"
}; };