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

expression parser for C++

This commit is contained in:
Mike Kucera 2008-02-14 19:59:12 +00:00
parent 5080d2ce65
commit e0716ec914
28 changed files with 7141 additions and 2062 deletions

View file

@ -29,7 +29,7 @@ public class C99SpecTests extends AST2CSpecTest {
@Override
protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
//parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings);
parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings);
parse(code, ParserLanguage.CPP, checkBindings, expectedProblemBindings);
}
@ -62,18 +62,6 @@ public class C99SpecTests extends AST2CSpecTest {
}
// offsetof does not work if <stddef.h> is not included!
@Override
public void test6_7_2_1s17() throws Exception {
try {
super.test6_7_2_1s17();
} catch(AssertionFailedError _) {
return;
}
fail();
}
// Tests from AST2CSpecFailingTests

View file

@ -30,40 +30,53 @@
</target>
<target name="cpp">
<description>Generate the C++ parser</description>
<antcall target="generate">
<param name="grammar_dir" value="cpp"/>
<param name="grammar_name" value="CPPParser"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/cpp"/>
</antcall>
</target>
<target name="c99">
<description>Generate the C99 parser</description>
<!-- Generate main parser -->
<antcall target="generate">
<param name="grammar_dir" value="c99"/>
<antcall target="generate-c99">
<param name="grammar_name" value="C99Parser"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/c99"/>
</antcall>
<!-- Generate parser for disambiguating declarations vs expression statements -->
<antcall target="generate">
<param name="grammar_dir" value="c99"/>
<antcall target="generate-c99">
<param name="grammar_name" value="C99ExpressionStatementParser"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/c99"/>
</antcall>
<!-- Generate parser for disambiguating cast expressions vs binary expressions-->
<antcall target="generate">
<param name="grammar_dir" value="c99"/>
<antcall target="generate-c99">
<param name="grammar_name" value="C99NoCastExpressionParser"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/c99"/>
</antcall>
<!-- Generate parser for disambiguating sizeof expressions -->
<antcall target="generate-c99">
<param name="grammar_name" value="C99SizeofExpressionParser"/>
</antcall>
</target>
<target name="cpp">
<description>Generate the C++ parser</description>
<antcall target="generate-cpp">
<param name="grammar_name" value="CPPParser"/>
</antcall>
<!-- Generate parser for disambiguating declarations vs expression statements -->
<antcall target="generate-cpp">
<param name="grammar_name" value="CPPExpressionStatementParser"/>
</antcall>
</target>
<target name="generate-c99">
<antcall target="generate">
<param name="grammar_dir" value="c99"/>
<param name="grammar_name" value="C99SizeofExpressionParser"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/c99"/>
<param name="grammar_name" value="${grammar_name}"/>
</antcall>
</target>
<target name="generate-cpp">
<antcall target="generate">
<param name="grammar_dir" value="cpp"/>
<param name="output_dir" value="org/eclipse/cdt/internal/core/dom/lrparser/cpp"/>
<param name="grammar_name" value="${grammar_name}"/>
</antcall>
</target>

View file

@ -15,9 +15,6 @@
-- All we need to do is import the main parser and redefine the start symbol.
$Define
$sym_class /. C99ExpressionStatementParsersym ./
$End
$Import
C99Grammar.g
@ -27,16 +24,6 @@ $Start
expression_parser_start
$End
$Headers
/.
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
./
$End
$Rules
expression_parser_start

View file

@ -11,8 +11,10 @@
-- TODO "complete" rules can be removed
-- TODO when the architecture has solidified try to move common
-- stuff between C99 and C++ into one file.
$Include
../common.g
common.g
$End
@ -111,7 +113,6 @@ $End
$Define
$build_action_class /. C99BuildASTParserAction ./
$resolve_action_class /. C99TypedefTrackerParserAction ./
$node_factory_create_expression /. C99ASTNodeFactory.DEFAULT_INSTANCE ./
$End

View file

@ -13,40 +13,19 @@
%options package=org.eclipse.cdt.internal.core.dom.lrparser.c99
%options template=btParserTemplateD.g
$Define
$sym_class /. C99NoCastExpressionParsersym ./
$End
$Import
C99Grammar.g
$DropRules
cast_expression
::= '(' type_name ')' cast_expression
-- The following rule remains in the grammar:
-- cast_expression ::= unary_expression
$End
$Start
no_cast_start
$End
$Headers
/.
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
./
$End
$Rules
no_cast_start

View file

@ -13,10 +13,8 @@
%options package=org.eclipse.cdt.internal.core.dom.lrparser.c99
%options template=btParserTemplateD.g
-- All we need to do is import the main parser and redefine the start symbol.
$Define
$sym_class /. C99Parsersym ./
$End
-- This file is needed because LPG won't allow redefinition of the
-- start symbol, so C99Grammar.g cannot define a start symbol.
$Import
C99Grammar.g

View file

@ -14,13 +14,8 @@
%options template=btParserTemplateD.g
$Define
$sym_class /. C99SizeofExpressionParsersym ./
$End
$Import
C99Grammar.g
$DropRules
unary_expression
@ -28,22 +23,10 @@ unary_expression
$End
$Start
no_sizeof_type_name_start
$End
$Headers
/.
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
./
$End
$Rules
no_sizeof_type_name_start

View file

@ -33,7 +33,8 @@ $Define
$ast_class /.Object./
$data_class /. Object ./ -- allow anything to be passed between actions
$additional_interfaces /. , IParserActionTokenProvider, IParser ./
$extra_interfaces /. ./
$additional_interfaces /. , IParserActionTokenProvider, IParser $extra_interfaces ./
$build_action_class /. ./
$resolve_action_class /. ./
@ -67,7 +68,7 @@ $Headers
private void initActions(IASTTranslationUnit tu) {
action = new $build_action_class($node_factory_create_expression, this, tu);
action.setTokenMap($sym_class.orderedTerminalSymbols);
action.setTokenMap($sym_type.orderedTerminalSymbols);
}
@ -99,6 +100,11 @@ $Headers
return Collections.unmodifiableList(getTokens().subList(getLeftSpan(), getRightSpan() + 1));
}
public IASTNode getSecondaryParseResult() {
return action.getSecondaryParseResult();
}
./
$End
@ -121,12 +127,14 @@ $Headers
token.setKind(tokenMap.mapKind(token.getKind()));
addToken(token);
}
addToken(new Token(null, 0, 0, $sym_class.TK_EOF_TOKEN));
addToken(new Token(null, 0, 0, $sym_type.TK_EOF_TOKEN));
}
public $action_type(String[] mapFrom) { // constructor
tokenMap = new TokenMap($sym_class.orderedTerminalSymbols, mapFrom);
tokenMap = new TokenMap($sym_type.orderedTerminalSymbols, mapFrom);
}
./
$End

View file

@ -0,0 +1,33 @@
-----------------------------------------------------------------------------------
-- 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
-- All we need to do is import the main parser and redefine the start symbol.
$Import
CPPGrammar.g
$End
$Start
expression_parser_start
$End
$Rules
expression_parser_start
::= expression ';'
| ERROR_TOKEN
/. $Build consumeExpressionProblem(); $EndBuild ./
$End

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.core.dom.lrparser;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -38,4 +39,10 @@ public interface IParser extends ITokenCollector {
*/
public IASTCompletionNode parse(IASTTranslationUnit tu);
/**
* Returns the result of a secondary parser.
*/
public IASTNode getSecondaryParseResult();
}

View file

@ -10,17 +10,43 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import java.util.List;
import lpg.lpgjavaruntime.IToken;
/**
* An LPG parser object is initialized with the list of tokens
* before parsing is invoked.
*
* This interface allows tokens to be "injected" into the parser
* before the parser is run.
*
* @author Mike Kucera
*/
public interface ITokenCollector {
/**
* Used to add one token at a time to the parser.
* If this method is used to add tokens then the dummy token
* and the EOF token must be added by the client.
*
* This is really just an optimization, no intermediate data structures
* are required between the preprocessor and the parser.
*
* @throws NullPointerException if token is null
*/
public void addToken(IToken token);
/**
* Set the list of tokens that will be parsed.
*
* The given list does not need to contain dummy and EOF tokens,
* these will be added automatically.
*
* This method causes any tokens already contained in the parser
* to be removed.
*
* This method is mainly used by secondary parsers that are called
* from a main parser.
*
* @throws NullPointerException if tokens is null
*/
public void setTokens(List<IToken> tokens);
}

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
@ -68,6 +69,7 @@ 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;
@ -129,6 +131,12 @@ public abstract class BuildASTParserAction {
protected abstract boolean isCompletionToken(IToken token);
/**
* Get the parser that will recognize expression statements.
*/
protected abstract IParser getExpressionStatementParser();
/**
* Create a new parser action.
* @param tu Root node of the AST, its list of declarations should be empty.
@ -186,8 +194,8 @@ public abstract class BuildASTParserAction {
/**
* Used to get the result of secondary parsers.
*/
public Object getSecondaryParseResult() {
return astStack.pop();
public IASTNode getSecondaryParseResult() {
return (IASTNode) astStack.pop();
}
@ -248,6 +256,16 @@ public abstract class BuildASTParserAction {
}
/**
* Runs the given parser on the tokens that make up the current rule.
*/
protected IASTNode runSecondaryParser(IParser secondaryParser) {
secondaryParser.setTokens(parser.getRuleTokens());
// need to pass tu because any completion nodes need to be linked directly to the root
IASTCompletionNode compNode = secondaryParser.parse(tu);
addNameToCompletionNode(compNode);
return secondaryParser.getSecondaryParseResult();
}
/*************************************************************************************************************
@ -261,8 +279,6 @@ public abstract class BuildASTParserAction {
* in order to create a new scope in the AST stack.
*/
public void openASTScope() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
astStack.openScope();
}
@ -365,6 +381,41 @@ public abstract class BuildASTParserAction {
}
/**
* block_item ::= declaration | statement
*
* Wrap a declaration in a DeclarationStatement.
*/
public void consumeStatementDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclaration decl = (IASTDeclaration) astStack.pop();
IASTDeclarationStatement declarationStatement = nodeFactory.newDeclarationStatement(decl);
setOffsetAndLength(declarationStatement);
// attempt to also parse the tokens as an expression
IASTExpressionStatement expressionStatement = null;
if(decl instanceof IASTSimpleDeclaration) {
IParser expressionParser = getExpressionStatementParser();
IASTExpression expr = (IASTExpression) runSecondaryParser(expressionParser);
if(expr != null && !(expr instanceof IASTProblemExpression)) { // the parse may fail
expressionStatement = nodeFactory.newExpressionStatement(expr);
setOffsetAndLength(expressionStatement);
}
}
if(expressionStatement == null)
astStack.push(declarationStatement);
else
astStack.push(nodeFactory.newAmbiguousStatement(declarationStatement, expressionStatement));
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* @param kind One of the kind flags from IASTLiteralExpression or ICPPASTLiteralExpression
@ -499,16 +550,13 @@ public abstract class BuildASTParserAction {
setOffsetAndLength(expr);
// try parsing as non-cast to resolve ambiguities
C99NoCastExpressionParser alternateParser = new C99NoCastExpressionParser(C99Parsersym.orderedTerminalSymbols);
alternateParser.setTokens(parser.getRuleTokens());
IASTCompletionNode compNode = alternateParser.parse(tu);
addNameToCompletionNode(compNode);
IASTExpression alternateExpr = alternateParser.getParseResult();
IParser secondaryParser = new C99NoCastExpressionParser(C99Parsersym.orderedTerminalSymbols);
IASTNode alternateExpr = runSecondaryParser(secondaryParser);
if(alternateExpr == null || alternateExpr instanceof IASTProblemExpression)
astStack.push(expr);
else
astStack.push(nodeFactory.newAmbiguousExpression(expr, alternateExpr));
astStack.push(nodeFactory.newAmbiguousExpression(expr, (IASTExpression)alternateExpr));
if(TRACE_AST_STACK) System.out.println(astStack);
@ -923,8 +971,19 @@ public abstract class BuildASTParserAction {
* Even if there is potential for reuse it still may be cleaner to leave the
* common stuff to just simple expressions and statements.
*
* For C99:
*
* declaration ::= declaration_specifiers <openscope> init_declarator_list ';'
* declaration ::= declaration_specifiers ';'
*
*
* For C++:
*
* simple_declaration
* ::= declaration_specifiers_opt <openscope-ast> init_declarator_list_opt ';'
*
*
* TODO Make both grammars the same here.
*/
public void consumeDeclarationSimple(boolean hasDeclaratorList) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
@ -932,6 +991,11 @@ public abstract class BuildASTParserAction {
List<Object> declarators = (hasDeclaratorList) ? astStack.closeScope() : Collections.emptyList();
IASTDeclSpecifier declSpecifier = (IASTDeclSpecifier) astStack.pop(); // may be null
if(declSpecifier == null) { // can happen if implicit int is used
declSpecifier = nodeFactory.newSimpleDeclSpecifier();
setOffsetAndLength(declSpecifier, parser.getLeftIToken().getStartOffset(), 0);
}
IASTSimpleDeclaration declaration = nodeFactory.newSimpleDeclaration(declSpecifier);
for(Object declarator : declarators)

View file

@ -179,4 +179,6 @@ public interface IASTNodeFactory {
public IASTAmbiguousExpression newAmbiguousExpression(IASTExpression... expressions);
public IASTDeclSpecifier newSimpleDeclSpecifier();
}

View file

@ -404,6 +404,10 @@ public class C99ASTNodeFactory implements IC99ASTNodeFactory {
return new CASTEnumerationSpecifier(name);
}
public IASTDeclSpecifier newSimpleDeclSpecifier() {
return newCSimpleDeclSpecifier();
}
}

View file

@ -53,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
@ -78,6 +79,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.dom.lrparser.IParser;
import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider;
import org.eclipse.cdt.core.dom.lrparser.action.BuildASTParserAction;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
@ -136,6 +138,12 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
}
@Override
protected IParser getExpressionStatementParser() {
return new C99ExpressionStatementParser(C99Parsersym.orderedTerminalSymbols);
}
@ -191,16 +199,13 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
setOffsetAndLength(expr);
// try parsing as an expression to resolve ambiguities
C99SizeofExpressionParser alternateParser = new C99SizeofExpressionParser(C99Parsersym.orderedTerminalSymbols);
alternateParser.setTokens(parser.getRuleTokens());
IASTCompletionNode completionNode = alternateParser.parse(tu);
addNameToCompletionNode(completionNode);
IASTExpression alternateExpr = alternateParser.getParseResult();
C99SizeofExpressionParser secondaryParser = new C99SizeofExpressionParser(C99Parsersym.orderedTerminalSymbols);
IASTNode alternateExpr = runSecondaryParser(secondaryParser);
if(alternateExpr == null || alternateExpr instanceof IASTProblemExpression)
astStack.push(expr);
else
astStack.push(nodeFactory.newAmbiguousExpression(expr, alternateExpr));
astStack.push(nodeFactory.newAmbiguousExpression(expr, (IASTExpression)alternateExpr));
if(TRACE_AST_STACK) System.out.println(astStack);
}
@ -251,38 +256,15 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
@Deprecated public void consumeDeclaratorComplete(/*IBinding binding*/) {
// if(DEBUG) DebugUtil.printMethodTrace();
//
// IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
//
// IASTDeclarator nested;
// while((nested = declarator.getNestedDeclarator()) != null) {
// declarator = nested;
// }
//
// //declarator.getName().setBinding(binding);
}
/**
* type_qualifier ::= const | restrict | volatile
*/
private void collectArrayModifierTypeQualifiers(ICASTArrayModifier arrayModifier) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
for(Object o : astStack.closeScope()) {
switch(asC99Kind((IToken)o)) {
case TK_const:
arrayModifier.setConst(true);
break;
case TK_restrict:
arrayModifier.setRestrict(true);
break;
case TK_volatile:
arrayModifier.setVolatile(true);
break;
case TK_const: arrayModifier.setConst(true); break;
case TK_restrict: arrayModifier.setRestrict(true); break;
case TK_volatile: arrayModifier.setVolatile(true); break;
}
}
}
@ -326,11 +308,6 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
}
@Deprecated public void consumeDeclaratorCompleteField(/*IBinding binding*/) {
//IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
//declarator.getName().setBinding(binding);
}
/**
* direct_declarator ::= direct_declarator '(' <openscope> identifier_list ')'
@ -405,19 +382,6 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
@Deprecated public void consumeDeclaratorCompleteParameter(/*IBinding binding*/) {
//if(DEBUG) DebugUtil.printMethodTrace();
//IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
//declarator.getName().setBinding(binding);
}
/**
* direct_abstract_declarator
* ::= '(' ')'
@ -680,93 +644,6 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
}
/**
* block_item ::= declaration | statement
*
* Wrap a declaration in a DeclarationStatement.
*/
public void consumeStatementDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclaration decl = (IASTDeclaration) astStack.pop();
IASTDeclarationStatement declarationStatement = nodeFactory.newDeclarationStatement(decl);
setOffsetAndLength(declarationStatement);
// attempt to also parse the tokens as an expression
IASTExpressionStatement expressionStatement = null;
if(decl instanceof IASTSimpleDeclaration) {
// TODO this probably has bad performance
C99ExpressionStatementParser expressionParser = new C99ExpressionStatementParser(C99Parsersym.orderedTerminalSymbols);
expressionParser.setTokens(parser.getRuleTokens());
// need to pass tu because any completion nodes need to be linked directly to the root
IASTCompletionNode compNode = expressionParser.parse(tu);
addNameToCompletionNode(compNode);
IASTExpression expr = expressionParser.getParseResult();
if(expr != null && !(expr instanceof IASTProblemExpression)) { // the parse may fail
expressionStatement = nodeFactory.newExpressionStatement(expr);
setOffsetAndLength(expressionStatement);
}
}
if(expressionStatement == null) {
astStack.push(declarationStatement);
}
else {
astStack.push(nodeFactory.newAmbiguousStatement(declarationStatement, expressionStatement));
}
if(TRACE_AST_STACK) System.out.println(astStack);
}
//
// /**
// * Kludgy way to disambiguate a certain case.
// * An identifier alone on a line will be parsed as a declaration
// * but it probably should be an expression.
// * eg) i;
// *
// * This only happens in the presence of a completion token.
// *
// * @return true if the hack was applied
// */
// private boolean disambiguateHackIdentifierExpression(IASTDeclaration decl) {
// if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
//
// // this is only meant to work with content assist
// List<IToken> tokens = parser.getRuleTokens();
// if(tokens.size() != 2 || tokens.get(0).getKind() == TK_typedef)
// return false;
//
// if(decl instanceof IASTSimpleDeclaration) {
// IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) decl;
// if(declaration.getDeclarators() == IASTDeclarator.EMPTY_DECLARATOR_ARRAY) {
// IASTDeclSpecifier declSpec = declaration.getDeclSpecifier();
// if(declSpec instanceof ICASTTypedefNameSpecifier) {
// ICASTTypedefNameSpecifier typedefNameSpec = (ICASTTypedefNameSpecifier) declSpec;
// IASTName name = typedefNameSpec.getName();
//
// if(offset(name) == offset(typedefNameSpec) && length(name) == length(typedefNameSpec)) {
// IASTIdExpression idExpr = nodeFactory.newIdExpression(name);
// IASTExpressionStatement stat = nodeFactory.newExpressionStatement(idExpr);
//
// setOffsetAndLength(stat);
// astStack.push(stat);
// return true;
// }
// }
// }
// }
// return false;
// }
/**
* selection_statement ::= switch '(' expression ')' statement
*/
@ -833,14 +710,6 @@ public class C99BuildASTParserAction extends BuildASTParserAction {
@Deprecated public void consumeFunctionDefinitionHeader(/*IBinding binding*/) {
// Object o = astStack.peek();
// if(o instanceof IASTFunctionDeclarator) {
// ((IASTFunctionDeclarator)o).getName().setBinding(binding);
// }
}
/**
* function_definition
* ::= declaration_specifiers <openscope> declarator

View file

@ -10,15 +10,11 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;

View file

@ -551,4 +551,8 @@ public class CPPASTNodeFactory implements ICPPASTNodeFactory {
return new CPPASTAmbiguousStatement(statements);
}
public IASTDeclSpecifier newSimpleDeclSpecifier() {
return newCPPSimpleDeclSpecifier();
}
}

View file

@ -82,9 +82,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.lrparser.IParser;
import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider;
import org.eclipse.cdt.core.dom.lrparser.action.BuildASTParserAction;
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.CPPParsersym;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
/**
@ -110,12 +115,18 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
this.nodeFactory = nodeFactory;
}
@Override protected boolean isCompletionToken(IToken token) {
@Override
protected boolean isCompletionToken(IToken token) {
// TODO Auto-generated method stub
return false;
}
@Override
protected IParser getExpressionStatementParser() {
return new CPPExpressionStatementParser(CPPParsersym.orderedTerminalSymbols);
}
// /**
// * Used only for debugging purposes.
// *
@ -536,24 +547,6 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
}
/**
* block_item ::= declaration | statement
*
* Wrap a declaration in a DeclarationStatement.
*/
public void consumeStatementDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclaration decl = (IASTDeclaration) astStack.pop();
IASTDeclarationStatement stat = nodeFactory.newDeclarationStatement(decl);
setOffsetAndLength(stat);
astStack.push(stat);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* try_block
* ::= 'try' compound_statement <openscope-ast> handler_seq
@ -1181,6 +1174,9 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
className = createQualifiedName(nestedNames, false);
}
if(className == null)
className = nodeFactory.newName();
ICPPASTCompositeTypeSpecifier classSpecifier = nodeFactory.newCPPCompositeTypeSpecifier(key, className);
for(Object base : baseSpecifiers)

View file

@ -205,6 +205,11 @@ public List getRuleTokens() {
}
public IASTNode getSecondaryParseResult() {
return action.getSecondaryParseResult();
}
private ITokenMap tokenMap = null;
@ -223,9 +228,6 @@ public C99ExpressionStatementParser(String[] mapFrom) { // constructor
}
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
public void ruleAction(int ruleNumber)
{

View file

@ -205,6 +205,11 @@ public List getRuleTokens() {
}
public IASTNode getSecondaryParseResult() {
return action.getSecondaryParseResult();
}
private ITokenMap tokenMap = null;
@ -223,9 +228,6 @@ public C99NoCastExpressionParser(String[] mapFrom) { // constructor
}
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
public void ruleAction(int ruleNumber)
{

View file

@ -205,6 +205,11 @@ public List getRuleTokens() {
}
public IASTNode getSecondaryParseResult() {
return action.getSecondaryParseResult();
}
private ITokenMap tokenMap = null;
@ -223,6 +228,7 @@ public C99Parser(String[] mapFrom) { // constructor
}
public void ruleAction(int ruleNumber)
{
switch (ruleNumber)

View file

@ -205,6 +205,11 @@ public List getRuleTokens() {
}
public IASTNode getSecondaryParseResult() {
return action.getSecondaryParseResult();
}
private ITokenMap tokenMap = null;
@ -223,9 +228,6 @@ public C99SizeofExpressionParser(String[] mapFrom) { // constructor
}
public IASTExpression getParseResult() {
return (IASTExpression) action.getSecondaryParseResult();
}
public void ruleAction(int ruleNumber)
{

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 CPPExpressionStatementParsersym {
public final static int
TK_asm = 67,
TK_auto = 49,
TK_bool = 13,
TK_break = 76,
TK_case = 77,
TK_catch = 115,
TK_char = 14,
TK_class = 57,
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 = 62,
TK_explicit = 50,
TK_export = 73,
TK_extern = 42,
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 = 63,
TK_new = 41,
TK_operator = 6,
TK_private = 116,
TK_protected = 117,
TK_public = 118,
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 = 64,
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 = 65,
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 = 58,
TK_Dot = 114,
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 = 66,
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 = 43,
TK_ERROR_TOKEN = 44,
TK_EOF_TOKEN = 119;
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",
"extern",
"SemiColon",
"ERROR_TOKEN",
"template",
"virtual",
"const",
"volatile",
"auto",
"explicit",
"friend",
"inline",
"mutable",
"register",
"static",
"typedef",
"class",
"LeftBrace",
"LeftBracket",
"using",
"LT",
"enum",
"namespace",
"struct",
"union",
"GT",
"asm",
"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",
"Dot",
"catch",
"private",
"protected",
"public",
"EOF_TOKEN",
"else",
"Completion",
"EndOfCompletion",
"Invalid"
};
public final static boolean isValidForParser = true;
}

View file

@ -25,6 +25,9 @@ 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.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.dom.lrparser.action.TokenMap;
public class CPPParser extends PrsStream implements RuleAction , IParserActionTokenProvider, IParser
{
private static ParseTable prs = new CPPParserprs();
@ -186,13 +189,6 @@ public void addToken(IToken token) {
}
public void setTokens(List<IToken> tokens) {
resetTokenStream();
for(IToken token : tokens) {
addToken(token);
}
}
public IASTCompletionNode parse(IASTTranslationUnit tu) {
// this has to be done, or... kaboom!
setStreamLength(getSize());
@ -205,7 +201,7 @@ public IASTCompletionNode parse(IASTTranslationUnit tu) {
// the completion node may be null
IASTCompletionNode compNode = action.builder.getASTCompletionNode();
action = null;
//action = null; // causes getSecondaryParseResult() to fail
// Comment this line to use with backtracking parser
//parserAction = null;
@ -240,6 +236,28 @@ public List getRuleTokens() {
}
public IASTNode getSecondaryParseResult() {
return action.builder.getSecondaryParseResult();
}
private ITokenMap tokenMap = null;
public void setTokens(List<IToken> tokens) {
resetTokenStream();
addToken(new Token(null, 0, 0, 0)); // dummy token
for(IToken token : tokens) {
token.setKind(tokenMap.mapKind(token.getKind()));
addToken(token);
}
addToken(new Token(null, 0, 0, CPPParsersym.TK_EOF_TOKEN));
}
public CPPParser(String[] mapFrom) { // constructor
tokenMap = new TokenMap(CPPParsersym.orderedTerminalSymbols, mapFrom);
}
public void ruleAction(int ruleNumber)
{