initial commit of new C99 and C++ parsers (work in progress)

This commit is contained in:
Mike Kucera 2008-01-22 19:16:30 +00:00
parent 6c58a96029
commit 17f8a38f4e
116 changed files with 31235 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.core.parser.c99.tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,3 @@
#Fri Oct 05 11:17:36 EDT 2007
eclipse.preferences.version=1
internal.default.compliance=default

View file

@ -0,0 +1,16 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name.0
Bundle-SymbolicName: org.eclipse.cdt.core.lrparser.tests
Bundle-Version: 4.0.0.qualifier
Bundle-Activator: org.eclipse.cdt.core.lrparser.tests.c99.Activator
Require-Bundle: org.eclipse.core.runtime,
org.junit,
org.eclipse.cdt.core.tests,
org.eclipse.cdt.core,
org.eclipse.core.resources,
org.eclipse.cdt.core.lrparser;bundle-version="4.0.1"
Eclipse-LazyStart: true
Export-Package: org.eclipse.cdt.core.lrparser.tests.c99
Bundle-Vendor: %Bundle-Vendor.0
Bundle-Localization: plugin

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>February 8, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
</body></html>

View file

@ -0,0 +1,16 @@
###############################################################################
# Copyright (c) 2007 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
###############################################################################
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
plugin.properties

View file

@ -0,0 +1,15 @@
###############################################################################
# Copyright (c) 2007 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
###############################################################################
# properties file for org.eclipse.cdt.core.parser.c99.tests
Bundle-Vendor.0 = Eclipse.org
Bundle-Name.0 = C99 Parser Tests Plug-in
upcSourceName=UPC Source File

View file

@ -0,0 +1,29 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import org.eclipse.cdt.core.dom.lrparser.action.c99.SymbolTableTests;
import junit.framework.Test;
import junit.framework.TestSuite;
public class ActionTestSuite extends TestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(SymbolTableTests.class);
suite.addTestSuite(ResolverActionTests.class);
return suite;
}
}

View file

@ -0,0 +1,129 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_identifier;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_int;
import java.util.ArrayList;
import java.util.List;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import lpg.lpgjavaruntime.IToken;
import lpg.lpgjavaruntime.Token;
import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable;
public class ResolverActionTests extends TestCase {
/**
* We are testing the parser actions in isolation without running
* an actual parser, therefore we need to mock out the parser object.
*/
private static class MockParser implements IParserActionTokenProvider {
public List<IToken> ruleTokens;
public MockParser(Object ... tokenTypes) {
this.ruleTokens = tokens(tokenTypes);
}
public List<IToken> getCommentTokens() {
return null;
}
public IToken getEOFToken() {
return null;
}
public IToken getLeftIToken() {
return ruleTokens.get(0);
}
public IToken getRightIToken() {
return ruleTokens.get(ruleTokens.size()-1);
}
public List<IToken> getRuleTokens() {
return ruleTokens;
}
public void setRuleTokens(Object ... tokenTypes) {
this.ruleTokens = tokens(tokenTypes);
}
static List<IToken> tokens(Object[] tokenTypes) {
List<IToken> tokens = new ArrayList<IToken>();
if(tokenTypes == null)
return tokens;
for(final Object o : tokenTypes) {
IToken token;
if(o instanceof Integer)
token = new Token(0, 0, ((Integer)o).intValue());
else if(o instanceof String)
token = new Token(0, 0, TK_identifier) {
@Override public String toString() {
return o.toString();
}
};
else
throw new AssertionFailedError();
tokens.add(token);
}
return tokens;
}
}
/**
* Parsing: int x;, then undo, then parse again
*/
@SuppressWarnings("deprecation")
public void testResolverActions1() {
MockParser mockParser = new MockParser();
C99ResolveParserAction action = new C99ResolveParserAction(mockParser);
mockParser.setRuleTokens(TK_int);
action.openDeclarationScope();
action.consumeDeclSpecToken();
mockParser.setRuleTokens("x");
action.consumeDirectDeclaratorIdentifier();
action.consumeDeclaratorComplete();
action.closeDeclarationScope();
C99SymbolTable symbolTable;
symbolTable = action.getSymbolTable();
assertEquals(1, symbolTable.size());
C99Variable binding = (C99Variable) symbolTable.lookup(CNamespace.IDENTIFIER, "x");
assertEquals("x", binding.getName());
// cool, now undo!
assertEquals(5, action.undoStackSize());
action.undo(5);
assertEquals(0, action.undoStackSize());
assertEquals(0, action.getDeclarationStack().size());
symbolTable = action.getSymbolTable();
assertTrue(symbolTable.isEmpty());
// rerun
mockParser.setRuleTokens(TK_int);
action.openDeclarationScope();
action.consumeDeclSpecToken();
mockParser.setRuleTokens("x");
action.consumeDirectDeclaratorIdentifier();
action.consumeDeclaratorComplete();
action.closeDeclarationScope();
symbolTable = action.getSymbolTable();
assertEquals(1, symbolTable.size());
binding = (C99Variable) symbolTable.lookup(CNamespace.IDENTIFIER, "x");
assertEquals("x", binding.getName());
}
}

View file

@ -0,0 +1,152 @@
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import junit.framework.TestCase;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.lrparser.action.FunctionalMap;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Label;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Structure;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable;
@SuppressWarnings("deprecation")
public class SymbolTableTests extends TestCase {
// TODO write tests for imperative symbol table
private final String[] KEYS = { "pantera", "soulfly", "inflames", "megadeth", "archenemy", "carcass" };
public void testPersistence() {
FunctionalMap<String,Integer> st0 = FunctionalMap.emptyMap();
assertTrue(st0.isEmpty());
FunctionalMap<String,Integer> st1 = st0.insert(KEYS[0], 1);
// empty symbol table does not change
assertTrue(st0.isEmpty());
assertNull(st0.lookup(KEYS[1]));
// a new symbol table was created
assertFalse(st1.isEmpty());
assertEquals(new Integer(1), st1.lookup(KEYS[0]));
FunctionalMap<String,Integer> st2 = st1.insert(KEYS[1], 2);
FunctionalMap<String,Integer> st3 = st2.insert(KEYS[2], 3);
FunctionalMap<String,Integer> st4 = st3.insert(KEYS[3], 4);
FunctionalMap<String,Integer> st5 = st4.insert(KEYS[4], 5);
assertMap(st0, KEYS, new Integer[] {null, null, null, null, null, null} );
assertMap(st1, KEYS, new Integer[] {1, null, null, null, null, null} );
assertMap(st2, KEYS, new Integer[] {1, 2, null, null, null, null} );
assertMap(st3, KEYS, new Integer[] {1, 2, 3, null, null, null} );
assertMap(st4, KEYS, new Integer[] {1, 2, 3, 4, null, null} );
assertMap(st5, KEYS, new Integer[] {1, 2, 3, 4, 5, null} );
}
public void testOverride() {
FunctionalMap<String,Integer> map1 = FunctionalMap.emptyMap();
for(int i = 0; i < KEYS.length; i++) {
map1 = map1.insert(KEYS[i], i);
}
assertMap(map1, KEYS, new Integer[] {0, 1, 2, 3, 4, 5});
FunctionalMap<String,Integer> map2 = map1.insert(KEYS[5], 999);
FunctionalMap<String,Integer> map3 = map2.insert(KEYS[5], null);
assertEquals(new Integer(5), map1.lookup(KEYS[5]));
assertEquals(new Integer(999), map2.lookup(KEYS[5]));
assertNull(map3.lookup(KEYS[5]));
}
private static void assertMap(FunctionalMap map, Comparable[] keys, Object[] vals) {
assert keys.length == vals.length;
for(int i = 0; i < keys.length; i++) {
assertEquals( "the key '" + keys[i] + "' did not match", vals[i], map.lookup((keys[i])));
if(vals[i] != null) {
assertTrue("key '" + keys[i] + "' not in map", map.containsKey(keys[i]));
}
}
}
public void testFunctionalSymbolTable1() {
C99SymbolTable st = C99SymbolTable.EMPTY_TABLE;
for(String key : KEYS) {
st = st.insert(CNamespace.IDENTIFIER, key, new C99Variable(key));
}
for(String key : KEYS) {
st = st.insert(CNamespace.GOTO_LABEL, key, new C99Label(key));
}
for(String key : KEYS) {
st = st.insert(CNamespace.STRUCT_TAG, key, new C99Structure(key));
}
assertFunctionalSymbolTableContainsAllThePairs(st);
}
public void testFunctionalSymbolTable2() {
C99SymbolTable st = C99SymbolTable.EMPTY_TABLE;
// same test as above but this time we insert the keys in a different order
for(String key : KEYS) {
st = st.insert(CNamespace.IDENTIFIER, key, new C99Variable(key));
st = st.insert(CNamespace.GOTO_LABEL, key, new C99Label(key));
st = st.insert(CNamespace.STRUCT_TAG, key, new C99Structure(key));
}
assertFunctionalSymbolTableContainsAllThePairs(st);
}
private void assertFunctionalSymbolTableContainsAllThePairs(C99SymbolTable st) {
assertEquals(KEYS.length * 3, st.size());
for(String key : KEYS) {
IBinding b = st.lookup(CNamespace.IDENTIFIER, key);
assertNotNull(b);
C99Variable x = (C99Variable)b;
assertEquals(key, x.getName());
}
for(String key : KEYS) {
IBinding b = st.lookup(CNamespace.GOTO_LABEL, key);
assertNotNull(b);
C99Label x = (C99Label)b;
assertEquals(key, x.getName());
}
for(String key : KEYS) {
IBinding b = st.lookup(CNamespace.STRUCT_TAG, key);
assertNotNull(b);
C99Structure x = (C99Structure)b;
assertEquals(key, x.getName());
}
}
public void testProperFail() {
FunctionalMap<Integer,Integer> map = FunctionalMap.emptyMap();
try {
map.insert(null, 99);
fail();
} catch (NullPointerException _) {}
try {
map.containsKey(null);
fail();
} catch (NullPointerException _) {}
try {
map.lookup(null);
fail();
} catch (NullPointerException _) {}
C99SymbolTable table = C99SymbolTable.EMPTY_TABLE;
try {
table.insert(null, null, new C99Variable("blah")); //$NON-NLS-1$
fail();
} catch (NullPointerException _) {}
}
}

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.cdt.core.parser.c99.tests";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.CommentTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99CommentTests extends CommentTests {
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);
}
protected IASTTranslationUnit parse(String code, ParserLanguage lang,
boolean useGNUExtensions, boolean expectNoProblems,
boolean parseComments) throws ParserException {
if(lang != ParserLanguage.C)
return super.parse(code, lang, useGNUExtensions, expectNoProblems, parseComments);
return ParseHelper.commentParse(code, getLanguage());
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
public void testBug191266() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append("#define MACRO 1000000000000 \n");
sb.append("int x = MACRO; \n");
sb.append("//comment\n");
String code = sb.toString();
IASTTranslationUnit tu = parse(code, ParserLanguage.C, false, false, true);
IASTComment[] comments = tu.getComments();
assertEquals(1, comments.length);
IASTFileLocation location = comments[0].getFileLocation();
assertEquals(code.indexOf("//"), location.getNodeOffset());
assertEquals("//comment".length(), location.getNodeLength());
}
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.CompleteParser2Tests;
public class C99CompleteParser2Tests extends CompleteParser2Tests {
protected IASTTranslationUnit parse(String code, boolean expectedToPass,
ParserLanguage lang, boolean gcc) throws Exception {
if(lang != ParserLanguage.C)
return super.parse(code, expectedToPass, lang, gcc);
return ParseHelper.parse(code, getLanguage(), expectedToPass);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// Tests that are failing at this point
public void testBug39676_tough() { // is this C99?
try {
super.testBug39676_tough();
} catch(AssertionFailedError _) {
return;
} catch(Exception _) {
return;
}
fail();
}
// public void testPredefinedSymbol_bug70928_infinite_loop_test1() throws Exception { // gcc extension
// try {
// super.testPredefinedSymbol_bug70928_infinite_loop_test1();
// fail();
// } catch(AssertionError _) { }
// }
//
// public void testPredefinedSymbol_bug70928_infinite_loop_test2() throws Exception { // gcc extension
// try {
// super.testPredefinedSymbol_bug70928_infinite_loop_test2();
// fail();
// } catch(AssertionError _) { }
// }
//
//
// public void testBug102376() throws Exception { // gcc extension
// try {
// super.testBug102376();
// fail();
// } catch(AssertionError _) { }
// }
}

View file

@ -0,0 +1,88 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.c99.C99Language;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.prefix.BasicCompletionTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99CompletionBasicTest extends BasicCompletionTest {
public C99CompletionBasicTest() { }
protected IASTCompletionNode getCompletionNode(String code,
ParserLanguage lang, boolean useGNUExtensions)
throws ParserException {
if(ParserLanguage.C == lang) {
return ParseHelper.getCompletionNode(code, getLanguage());
}
else {
// TODO: parsing of C++
return super.getCompletionNode(code, lang, useGNUExtensions);
}
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// The C99 parser currently doesn't support ambiguity nodes.
// Therefore calling IASTCompletionNode.getNames() will
// never return more than one name.
@Override
public void testFunction() throws Exception {
StringBuffer code = new StringBuffer();
code.append("void func(int x) { }");//$NON-NLS-1$
code.append("void func2() { fu");//$NON-NLS-1$
// C
IASTCompletionNode node = getGCCCompletionNode(code.toString());
IASTName[] names = node.getNames();
// There is only one name, for now
assertEquals(1, names.length);
// The expression points to our functions
IBinding[] bindings = sortBindings(names[0].getCompletionContext().findBindings(names[0], true));
// There should be two since they both start with fu
assertEquals(2, bindings.length);
assertEquals("func", ((IFunction)bindings[0]).getName());//$NON-NLS-1$
assertEquals("func2", ((IFunction)bindings[1]).getName());//$NON-NLS-1$
}
@Override
public void testTypedef() throws Exception {
StringBuffer code = new StringBuffer();
code.append("typedef int blah;");//$NON-NLS-1$
code.append("bl");//$NON-NLS-1$
// C
IASTCompletionNode node = getGCCCompletionNode(code.toString());
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = names[0].getCompletionContext().findBindings(names[0], true);
assertEquals(1, bindings.length);
assertEquals("blah", ((ITypedef)bindings[0]).getName());//$NON-NLS-1$
}
}

View file

@ -0,0 +1,424 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import java.util.Arrays;
import java.util.Comparator;
import junit.framework.TestCase;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.c99.C99Language;
/**
* Reuse the completion parse tests from the old parser for now.
*
* This test suite is specific to C99.
*/
public class C99CompletionParseTest extends TestCase {
public C99CompletionParseTest() { }
public C99CompletionParseTest(String name) { super(name); }
protected IASTCompletionNode parse(String code, int offset) throws Exception {
return ParseHelper.getCompletionNode(code, getLanguage(), offset);
}
private static class BindingsComparator implements Comparator {
public int compare(Object o1, Object o2) {
IBinding b1 = (IBinding)o1;
IBinding b2 = (IBinding)o2;
return b1.getName().compareTo(b2.getName());
}
}
private static BindingsComparator bindingsComparator = new BindingsComparator();
protected IBinding[] sortBindings(IBinding[] bindings) {
Arrays.sort(bindings, bindingsComparator);
return bindings;
}
protected IBinding[] getBindings(IASTName[] names) {
return sortBindings(names[0].getCompletionContext().findBindings(names[0], true));
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// First steal tests from CompletionParseTest
public void testCompletionStructField() throws Exception
{
StringBuffer sb = new StringBuffer();
sb.append( "int aVar; " ); //$NON-NLS-1$
sb.append( "struct D{ " ); //$NON-NLS-1$
sb.append( " int aField1; " ); //$NON-NLS-1$
sb.append( " int aField2; " ); //$NON-NLS-1$
sb.append( "}; " ); //$NON-NLS-1$
sb.append( "void foo(){" ); //$NON-NLS-1$
sb.append( " struct D d; " ); //$NON-NLS-1$
sb.append( " d.a " ); //$NON-NLS-1$
sb.append( "}\n" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf( "d.a" ); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index + 3 );
assertNotNull( node );
String prefix = node.getPrefix();
assertNotNull( prefix );
assertEquals( prefix, "a" ); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("aField1", ((IField)bindings[0]).getName());
assertEquals("aField2", ((IField)bindings[1]).getName());
}
public void testCompletionStructFieldPointer() throws Exception
{
StringBuffer sb = new StringBuffer();
sb.append("struct Cube { "); //$NON-NLS-1$
sb.append(" int nLen; "); //$NON-NLS-1$
sb.append(" int nWidth; "); //$NON-NLS-1$
sb.append(" int nHeight; "); //$NON-NLS-1$
sb.append("}; "); //$NON-NLS-1$
sb.append("int volume( struct Cube * pCube ) { "); //$NON-NLS-1$
sb.append(" pCube->SP "); //$NON-NLS-1$
String code = sb.toString();
IASTCompletionNode node = parse( code, code.indexOf("SP")); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("nHeight", ((IField)bindings[0]).getName());
assertEquals("nLen", ((IField)bindings[1]).getName());
assertEquals("nWidth", ((IField)bindings[2]).getName());
}
public void testCompletionParametersAsLocalVariables() throws Exception{
StringBuffer sb = new StringBuffer();
sb.append( "int foo( int aParameter ){" ); //$NON-NLS-1$
sb.append( " int aLocal;" ); //$NON-NLS-1$
sb.append( " if( aLocal != 0 ){" ); //$NON-NLS-1$
sb.append( " int aBlockLocal;" ); //$NON-NLS-1$
sb.append( " a \n" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf( " a " ); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index + 2 );
assertNotNull( node );
assertEquals("a", node.getPrefix()); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("aBlockLocal", ((IVariable)bindings[0]).getName());
assertEquals("aLocal", ((IVariable)bindings[1]).getName());
assertEquals("aParameter", ((IVariable)bindings[2]).getName());
}
public void testCompletionTypedef() throws Exception{
StringBuffer sb = new StringBuffer();
sb.append( "typedef int Int; "); //$NON-NLS-1$
sb.append( "InSP" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf( "SP" ); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index );
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
assertEquals("In", node.getPrefix());
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("Int", ((ITypedef)bindings[0]).getName());
}
public void testCompletion() throws Exception
{
StringBuffer sb = new StringBuffer();
sb.append("#define GL_T 0x2001\n"); //$NON-NLS-1$
sb.append("#define GL_TRUE 0x1\n"); //$NON-NLS-1$
sb.append("typedef unsigned char GLboolean;\n"); //$NON-NLS-1$
sb.append("static GLboolean should_rotate = GL_T"); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf("= GL_T"); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index + 6);
assertNotNull(node);
assertEquals("GL_T", node.getPrefix()); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(1, names.length);
}
public void testCompletionInTypeDef() throws Exception{
StringBuffer sb = new StringBuffer();
sb.append( "struct A { int name; }; \n" ); //$NON-NLS-1$
sb.append( "typedef struct A * PA; \n" ); //$NON-NLS-1$
sb.append( "int main() { \n" ); //$NON-NLS-1$
sb.append( " PA a; \n" ); //$NON-NLS-1$
sb.append( " a->SP \n" ); //$NON-NLS-1$
sb.append( "} \n" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf("SP"); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index );
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("name", ((IField)bindings[0]).getName());
}
public void _testCompletionFunctionCall() throws Exception
{
StringBuffer sb = new StringBuffer();
sb.append( "struct A { \n" ); //$NON-NLS-1$
sb.append( " int f2; \n" ); //$NON-NLS-1$
sb.append( " int f4; \n" ); //$NON-NLS-1$
sb.append( "}; \n" ); //$NON-NLS-1$
sb.append( "const A * foo(){} \n" ); //$NON-NLS-1$
sb.append( "void main( ) \n" ); //$NON-NLS-1$
sb.append( "{ \n" ); //$NON-NLS-1$
sb.append( " foo()->SP \n" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf( "SP" ); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index );
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("f2", ((IField)bindings[0]).getName());
assertEquals("f4", ((IField)bindings[1]).getName());
}
public void _testCompletionSizeof() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "int f() {\n" ); //$NON-NLS-1$
sb.append( "short blah;\n" ); //$NON-NLS-1$
sb.append( "int x = sizeof(bl" ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf( "of(bl" ); //$NON-NLS-1$
IASTCompletionNode node = parse( code, index + 5);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("blah", ((IVariable)bindings[0]).getName());
}
public void testCompletionForLoop() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "int f() {\n" ); //$NON-NLS-1$
sb.append( " int biSizeImage = 5;\n" ); //$NON-NLS-1$
sb.append( "for (int i = 0; i < bi " ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf("< bi");
IASTCompletionNode node = parse( code, index + 4);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("biSizeImage", ((IVariable)bindings[0]).getName());
}
public void testCompletionStructPointer() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append(" struct Temp { char * total; };" );
sb.append(" int f(struct Temp * t) {" );
sb.append(" t->t[5] = t->" );
String code = sb.toString();
int index = code.indexOf("= t->");
IASTCompletionNode node = parse( code, index + 5);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("total", ((IVariable)bindings[0]).getName());
}
public void testCompletionEnum() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "typedef int DWORD;\n" ); //$NON-NLS-1$
sb.append( "typedef char BYTE;\n"); //$NON-NLS-1$
sb.append( "#define MAKEFOURCC(ch0, ch1, ch2, ch3) \\\n"); //$NON-NLS-1$
sb.append( "((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \\\n"); //$NON-NLS-1$
sb.append( "((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))\n"); //$NON-NLS-1$
sb.append( "enum e {\n"); //$NON-NLS-1$
sb.append( "blah1 = 5,\n"); //$NON-NLS-1$
sb.append( "blah2 = MAKEFOURCC('a', 'b', 'c', 'd'),\n"); //$NON-NLS-1$
sb.append( "blah3\n"); //$NON-NLS-1$
sb.append( "};\n"); //$NON-NLS-1$
sb.append( "e mye = bl\n"); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf("= bl");
IASTCompletionNode node = parse( code, index + 4);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("blah1", ((IEnumerator)bindings[0]).getName());
assertEquals("blah2", ((IEnumerator)bindings[1]).getName());
assertEquals("blah3", ((IEnumerator)bindings[2]).getName());
}
public void testCompletionStructArray() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "struct packet { int a; int b; };\n" ); //$NON-NLS-1$
sb.append( "struct packet buffer[5];\n" ); //$NON-NLS-1$
sb.append( "int main(int argc, char **argv) {\n" ); //$NON-NLS-1$
sb.append( " buffer[2]." ); //$NON-NLS-1$
String code = sb.toString();
int index = code.indexOf("[2].");
IASTCompletionNode node = parse( code, index + 4);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("a", ((IField)bindings[0]).getName());
assertEquals("b", ((IField)bindings[1]).getName());
}
public void testCompletionPreprocessorDirective() throws Exception {
IASTCompletionNode node = parse("#", 1);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
assertEquals("#", node.getPrefix());
}
public void testCompletionPreprocessorMacro() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "#define AMACRO 99 \n");
sb.append( "int main() { \n");
sb.append( " int AVAR; \n");
sb.append( " int x = A \n");
String code = sb.toString();
int index = code.indexOf("= A");
IASTCompletionNode node = parse( code, index + 3);
assertNotNull( node );
IASTName[] names = node.getNames();
assertEquals(1, names.length);
assertEquals("A", node.getPrefix());
}
public void testCompletionInsidePreprocessorDirective() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append( "#define MAC1 99 \n");
sb.append( "#define MAC2 99 \n");
sb.append( "#ifdef MA");
String code = sb.toString();
int index = code.length();
IASTCompletionNode node = parse( code, index );
assertNotNull( node );
assertEquals("MA", node.getPrefix());
}
}

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import java.util.Collections;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
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.parser.CodeReader;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.tests.ast2.DOMLocationInclusionTests;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
import org.eclipse.core.resources.IFile;
public class C99DOMLocationInclusionTests extends DOMLocationInclusionTests {
public C99DOMLocationInclusionTests() {
}
public C99DOMLocationInclusionTests(String name, Class className) {
super(name, className);
}
public C99DOMLocationInclusionTests(String name) {
super(name);
}
protected IASTTranslationUnit parse(IFile code, IScannerInfo s)
throws Exception {
CodeReader codeReader = new CodeReader(code.getLocation().toOSString());
BaseExtensibleLanguage lang = getLanguage();
IASTTranslationUnit tu = lang.getASTTranslationUnit(codeReader, s, SavedCodeReaderFactory.getInstance(), null, BaseExtensibleLanguage.OPTION_ADD_COMMENTS, ParserUtil.getParserLogService());
return tu;
}
protected IASTTranslationUnit parse(IFile code) throws Exception {
return parse(code, new ExtendedScannerInfo());
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
}

View file

@ -0,0 +1,65 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.DOMLocationMacroTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99DOMLocationMacroTests extends DOMLocationMacroTests {
public C99DOMLocationMacroTests() {
super();
}
public C99DOMLocationMacroTests(String name) {
super(name);
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
if(lang == ParserLanguage.C) {
return ParseHelper.parse(code, getLanguage(), expectNoProblems);
}
else
return super.parse(code, lang, useGNUExtensions, expectNoProblems);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
/**
* Tests GCC specific stuff, not applicable at this point
*/
public void testStdioBug() throws ParserException {
try {
super.testStdioBug();
fail();
}
catch(Throwable e) { }
}
}

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.DOMLocationTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99DOMLocationTests extends DOMLocationTests {
public C99DOMLocationTests() { }
public C99DOMLocationTests(String name) { super(name); }
@Override
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// this one fails because the C99 parser does error recovery differently
public void test162180_1() throws Exception {
try {
super.test162180_1();
fail();
}
catch(AssertionFailedError e) {}
}
public void test162180_3() throws Exception {
try {
super.test162180_3();
fail();
}
catch(AssertionFailedError e) {}
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.DOMPreprocessorInformationTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99DOMPreprocessorInformationTest extends DOMPreprocessorInformationTest {
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
}

View file

@ -0,0 +1,175 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.TestCase;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.c99.C99Language;
public class C99DigraphTrigraphTests extends TestCase {
public C99DigraphTrigraphTests() { }
public C99DigraphTrigraphTests(String name) { super(name); }
protected IASTTranslationUnit parse(String code) {
return ParseHelper.parse(code, getLanguage(), true);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
public void testTrigraphSequences() {
StringBuffer sb = new StringBuffer();
sb.append("??=define SIZE ??/ \n"); // trigraph used as backslash to ignore newline
sb.append("99 \n");
sb.append("int main(void)??< \n");
sb.append(" int arr??(SIZE??); \n");
sb.append(" arr??(4??) = '0' - (??-0 ??' 1 ??! 2); \n");
sb.append(" printf(\"%c??/n\", arr??(4??)); \n");
sb.append("??> \n");
String code = sb.toString();
IASTTranslationUnit tu = parse(code);
assertNotNull(tu);
IASTPreprocessorStatement[] defines = tu.getAllPreprocessorStatements();
assertEquals(1, defines.length);
IASTPreprocessorMacroDefinition macro = (IASTPreprocessorMacroDefinition)defines[0];
assertEquals("SIZE", macro.getName().toString());
//assertEquals("99", macro.getExpansion());
IASTFunctionDefinition main = (IASTFunctionDefinition)tu.getDeclarations()[0];
IASTCompoundStatement body = (IASTCompoundStatement) main.getBody();
IASTStatement[] statements = body.getStatements();
assertEquals(3, statements.length);
// int arr??(SIZE??);
IASTSimpleDeclaration arr = (IASTSimpleDeclaration)((IASTDeclarationStatement)statements[0]).getDeclaration();
IASTArrayDeclarator arr_decl = (IASTArrayDeclarator)arr.getDeclarators()[0];
IASTArrayModifier modifier = arr_decl.getArrayModifiers()[0];
IASTLiteralExpression lit = (IASTLiteralExpression)modifier.getConstantExpression();
assertEquals(IASTLiteralExpression.lk_integer_constant, lit.getKind());
// arr??(4??) = '0' - (??-0 ??' 1 ??! 2);
IASTBinaryExpression expr = (IASTBinaryExpression)((IASTExpressionStatement)statements[1]).getExpression();
assertEquals(IASTBinaryExpression.op_assign, expr.getOperator());
IASTArraySubscriptExpression arr_op = (IASTArraySubscriptExpression)expr.getOperand1();
assertEquals("4", ((IASTLiteralExpression)arr_op.getSubscriptExpression()).toString());
IASTBinaryExpression cond = (IASTBinaryExpression)((IASTUnaryExpression)((IASTBinaryExpression)expr.getOperand2()).getOperand2()).getOperand();
assertEquals(IASTBinaryExpression.op_binaryOr, cond.getOperator());
IASTBinaryExpression cond2 = (IASTBinaryExpression)cond.getOperand1();
assertEquals(IASTBinaryExpression.op_binaryXor, cond2.getOperator());
IASTUnaryExpression not = (IASTUnaryExpression)cond2.getOperand1();
assertEquals(IASTUnaryExpression.op_tilde, not.getOperator());
// printf(\"%c??/n\", arr??(4??));
IASTFunctionCallExpression expr2 = (IASTFunctionCallExpression)((IASTExpressionStatement)statements[2]).getExpression();
IASTExpressionList params = (IASTExpressionList) expr2.getParameterExpression();
IASTArraySubscriptExpression arr_op2 = (IASTArraySubscriptExpression)params.getExpressions()[1];
assertEquals("4", ((IASTLiteralExpression)arr_op2.getSubscriptExpression()).toString());
}
public void testTrigraphEscapeSequences() {
// a ??/ trigraph should act just like a backslash in a string literal
StringBuffer sb = new StringBuffer();
sb.append("int main(void)??< \n");
sb.append(" char str[] = \"??/\"??/n\"; \n");
sb.append(" char c = '??/u0000'; \n");
sb.append("??> \n");
String code = sb.toString();
parse(code); // will throw an exception if there are parse errors
}
public void testDigraphSequences() {
StringBuffer sb = new StringBuffer();
sb.append("%:define join(a, b) a %:%: b \n");
sb.append("int main() <% \n");
sb.append(" int arr<:5:>; \n");
sb.append("%> \n");
String code = sb.toString();
IASTTranslationUnit tu = parse(code); // will throw an exception if there are parse errors
IASTFunctionDefinition main = (IASTFunctionDefinition)tu.getDeclarations()[0];
IASTCompoundStatement body = (IASTCompoundStatement) main.getBody();
IASTStatement[] statements = body.getStatements();
assertEquals(1, statements.length);
IASTSimpleDeclaration arr = (IASTSimpleDeclaration)((IASTDeclarationStatement)statements[0]).getDeclaration();
IASTArrayDeclarator arr_decl = (IASTArrayDeclarator)arr.getDeclarators()[0];
IASTArrayModifier modifier = arr_decl.getArrayModifiers()[0];
IASTLiteralExpression lit = (IASTLiteralExpression)modifier.getConstantExpression();
assertEquals("5", lit.toString());
}
public void testTrigraphAndDigraphSequecesInPreprocessorDirectives() {
StringBuffer sb = new StringBuffer();
sb.append("%:define join1(a, b) a %:%: b \n");
sb.append("%:define str1(a) %: a \n");
sb.append("??=define join2(a, b) a ??=??= b \n");
sb.append("??=define str2(a) ??= a \n");
sb.append("int main() <% \n");
sb.append(" int join1(x, y) = str1(its all good); \n");
sb.append(" int join2(a, b) = str2(its still good); \n");
sb.append("%> \n");
String code = sb.toString();
IASTTranslationUnit tu = parse(code); // will throw an exception if there are parse errors
IASTFunctionDefinition main = (IASTFunctionDefinition)tu.getDeclarations()[0];
IASTCompoundStatement body = (IASTCompoundStatement) main.getBody();
IASTStatement[] statements = body.getStatements();
assertEquals(2, statements.length);
IASTSimpleDeclaration decl1 = (IASTSimpleDeclaration)((IASTDeclarationStatement)statements[0]).getDeclaration();
IASTDeclarator declarator1 = decl1.getDeclarators()[0];
assertEquals("xy", declarator1.getName().toString());
IASTLiteralExpression expr1 = (IASTLiteralExpression)((IASTInitializerExpression)declarator1.getInitializer()).getExpression();
assertEquals(IASTLiteralExpression.lk_string_literal, expr1.getKind());
assertEquals("\"its all good\"", expr1.toString());
IASTSimpleDeclaration decl2 = (IASTSimpleDeclaration)((IASTDeclarationStatement)statements[1]).getDeclaration();
IASTDeclarator declarator2 = decl2.getDeclarators()[0];
assertEquals("ab", declarator2.getName().toString());
IASTLiteralExpression expr2 = (IASTLiteralExpression)((IASTInitializerExpression)declarator2.getInitializer()).getExpression();
assertEquals(IASTLiteralExpression.lk_string_literal, expr2.getKind());
assertEquals("its still good", expr2.toString());
}
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.GCCTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99GCCTests extends GCCTests {
public C99GCCTests() {}
public C99GCCTests(String name) { super(name); }
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
}

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2KnRTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
* @author Mike Kucera
*/
public class C99KnRTests extends AST2KnRTests {
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
if(lang == ParserLanguage.C) {
return ParseHelper.parse(code, getLanguage(), expectNoProblems);
}
else
return super.parse(code, lang, useGNUExtensions, expectNoProblems);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// TODO: Failing tests, will get around to fixing these bugs
public void testKRCProblem3() throws Exception {
try {
super.testKRCProblem3();
fail();
} catch(Throwable _) { }
}
public void testKRCProblem4() throws Exception {
try {
super.testKRCProblem4();
fail();
} catch(Throwable _) { }
}
public void testKRCProblem5() throws Exception {
try {
super.testKRCProblem5();
fail();
} catch(Throwable _) { }
}
public void testKRCProblem2() throws Exception {
try {
super.testKRCProblem2();
fail();
} catch(Throwable _) { }
}
}

View file

@ -0,0 +1,165 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import java.util.Collections;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
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.parser.CodeReader;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.tests.ast2.AST2SelectionParseTest;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
import org.eclipse.cdt.internal.core.parser.ParserException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
public class C99SelectionParseTest extends AST2SelectionParseTest {
public C99SelectionParseTest() {}
public C99SelectionParseTest(String name) { super(name); }
protected IASTNode parse(String code, ParserLanguage lang, int offset, int length) throws ParserException {
if(lang == ParserLanguage.C)
return parse(code, lang, false, false, offset, length);
else
return super.parse(code, lang, offset, length);
}
protected IASTNode parse(IFile file, ParserLanguage lang, int offset, int length) throws ParserException {
if(lang == ParserLanguage.C) {
IASTTranslationUnit tu = parse(file, lang, false, false);
return tu.selectNodeForLocation(tu.getFilePath(), offset, length);
}
else
return super.parse(file, lang, offset, length);
}
protected IASTNode parse(String code, ParserLanguage lang, int offset, int length, boolean expectedToPass) throws ParserException {
if(lang == ParserLanguage.C)
return parse(code, lang, false, expectedToPass, offset, length);
else
return super.parse(code, lang, offset, length, expectedToPass);
}
protected IASTNode parse(String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems, int offset, int length) throws ParserException {
if(lang == ParserLanguage.C) {
IASTTranslationUnit tu = ParseHelper.parse(code, getLanguage(), useGNUExtensions, expectNoProblems, 0);
return tu.selectNodeForLocation(tu.getFilePath(), offset, length);
}
else
return super.parse(code, lang, useGNUExtensions, expectNoProblems, offset, length);
}
protected IASTTranslationUnit parse( IFile file, ParserLanguage lang, IScannerInfo scanInfo, boolean useGNUExtensions, boolean expectNoProblems )
throws ParserException {
if(lang != ParserLanguage.C)
return super.parse(file, lang, useGNUExtensions, expectNoProblems);
String fileName = file.getLocation().toOSString();
ICodeReaderFactory fileCreator = SavedCodeReaderFactory.getInstance();
CodeReader reader = fileCreator.createCodeReaderForTranslationUnit(fileName);
return ParseHelper.parse(reader, getLanguage(), scanInfo, fileCreator, expectNoProblems, true, 0);
}
protected IASTTranslationUnit parse( IFile file, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems )
throws ParserException {
return parse(file, lang, new ScannerInfo(), useGNUExtensions, expectNoProblems);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
// public void testBug193185_IncludeNext() throws Exception
// {
// String baseFile = "int zero; \n#include \"foo.h\""; //$NON-NLS-1$
// String i1Next = "int one; \n#include_next <foo.h>"; //$NON-NLS-1$
// String i2Next = "int two; \n#include_next \"foo.h\""; //$NON-NLS-1$
// String i3Next = "int three; \n"; //$NON-NLS-1$
//
//
// IFile base = importFile( "base.c", baseFile ); //$NON-NLS-1$
// importFile( "foo.h", i1Next ); //$NON-NLS-1$
// IFolder twof = importFolder("two"); //$NON-NLS-1$
// IFolder threef = importFolder("three"); //$NON-NLS-1$
// importFile( "two/foo.h", i2Next ); //$NON-NLS-1$
// importFile( "three/foo.h", i3Next ); //$NON-NLS-1$
//
// String[] path = new String[] {
// twof.getRawLocation().toOSString(),
// threef.getRawLocation().toOSString()
// };
//
// IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, path, new String[0], path );
//
// IASTTranslationUnit tu = parse(base, ParserLanguage.C, scannerInfo, false, true);
//
// IASTDeclaration[] decls = tu.getDeclarations();
// assertEquals(4, decls.length);
//
// IASTSimpleDeclaration declaration = (IASTSimpleDeclaration)decls[0];
// assertEquals("zero", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
//
// declaration = (IASTSimpleDeclaration)decls[1];
// assertEquals("one", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
//
// declaration = (IASTSimpleDeclaration)decls[2];
// assertEquals("two", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
//
// declaration = (IASTSimpleDeclaration)decls[3];
// assertEquals("three", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
// }
//
//
// public void testBug193366() throws Exception
// {
// String baseFile =
// "#define FOOH <foo.h> \n" + //$NON-NLS-1$
// "#define bar blahblahblah \n" + //$NON-NLS-1$
// "#include FOOH \n" + //$NON-NLS-1$
// "#include <bar.h> \n"; //$NON-NLS-1$
//
// String fooFile = "int x; \n"; //$NON-NLS-1$
// String barFile = "int y; \n"; //$NON-NLS-1$
//
//
// IFile base = importFile( "base.c", baseFile ); //$NON-NLS-1$
// IFolder include = importFolder("inc"); //$NON-NLS-1$
// importFile( "inc/foo.h", fooFile ); //$NON-NLS-1$
// importFile( "inc/bar.h", barFile ); //$NON-NLS-1$
//
// String[] path = new String[] { include.getRawLocation().toOSString() };
// IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, path, new String[0], path );
//
// IASTTranslationUnit tu = parse(base, ParserLanguage.C, scannerInfo, false, true);
//
// IASTDeclaration[] decls = tu.getDeclarations();
// assertEquals(2, decls.length);
//
// IASTSimpleDeclaration declaration = (IASTSimpleDeclaration)decls[0];
// assertEquals("x", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
//
// declaration = (IASTSimpleDeclaration)decls[1];
// assertEquals("y", declaration.getDeclarators()[0].getName().toString()); //$NON-NLS-1$
// }
}

View file

@ -0,0 +1,211 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CSpecTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99SpecTests extends AST2CSpecTest {
public C99SpecTests() { }
public C99SpecTests(String name) { super(name); }
/**
* Only parses it as C actually
* @throws ParserException
*/
protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings);
parse(code, ParserLanguage.CPP, checkBindings, expectedProblemBindings);
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
if(lang == ParserLanguage.C)
return ParseHelper.parse(code, getLanguage(), true, checkBindings, expectedProblemBindings );
else
return super.parse(code, lang, checkBindings, expectedProblemBindings);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
//Assignment statements cannot exists outside of a function body
@Override
public void test5_1_2_3s15() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("//#include <stdio.h>\n"); //$NON-NLS-1$
buffer.append("int foo() { \n"); //$NON-NLS-1$
buffer.append("int sum;\n"); //$NON-NLS-1$
buffer.append("char *p;\n"); //$NON-NLS-1$
buffer.append("sum = sum * 10 - '0' + (*p++ = getchar());\n"); //$NON-NLS-1$
buffer.append("sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));\n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
parseCandCPP(buffer.toString(), false, 0);
}
// 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
/**
* TODO: This one fails, it can't resolve one of the bindings (const t) I think
*
[--Start Example(C 6.7.7-6):
typedef signed int t;
typedef int plain;
struct tag {
unsigned t:4;
const t:5;
plain r:5;
};
t f(t (t));
long t;
--End Example]
*/
public void test6_7_7s6() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("typedef signed int t;\n"); //$NON-NLS-1$
buffer.append("typedef int plain;\n"); //$NON-NLS-1$
buffer.append("struct tag {\n"); //$NON-NLS-1$
buffer.append("unsigned t:4;\n"); //$NON-NLS-1$
buffer.append("const t:5;\n"); //$NON-NLS-1$
buffer.append("plain r:5;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("t f(t (t));\n"); //$NON-NLS-1$
buffer.append("long t;\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.C, true, 0);
} catch(AssertionFailedError _) {
// there should be an error
}
}
/**
[--Start Example(C 6.10.3.5-5):
#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
#define p() int
#define q(x) x
#define r(x,y) x ## y
#define str(x) # x
int foo() {
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
}
--End Example]
*/
@Override
public void test6_10_3_5s5() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("#define x 3\n"); //$NON-NLS-1$
buffer.append("#define f(a) f(x * (a))\n"); //$NON-NLS-1$
buffer.append("#undef x\n"); //$NON-NLS-1$
buffer.append("#define x 2\n"); //$NON-NLS-1$
buffer.append("#define g f\n"); //$NON-NLS-1$
buffer.append("#define z z[0]\n"); //$NON-NLS-1$
buffer.append("#define h g(~\n"); //$NON-NLS-1$
buffer.append("#define m(a) a(w)\n"); //$NON-NLS-1$
buffer.append("#define w 0,1\n"); //$NON-NLS-1$
buffer.append("#define t(a) a\n"); //$NON-NLS-1$
buffer.append("#define p() int\n"); //$NON-NLS-1$
buffer.append("#define q(x) x\n"); //$NON-NLS-1$
buffer.append("#define r(x,y) x ## y\n"); //$NON-NLS-1$
buffer.append("#define str(x) # x\n"); //$NON-NLS-1$
buffer.append("int foo() {\n"); //$NON-NLS-1$
buffer.append("p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };\n"); //$NON-NLS-1$
buffer.append("char c[2][6] = { str(hello), str() };\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
//parseCandCPP(buffer.toString(), true, 0);
// TODO: this only works on the C99 parser for now
parse(buffer.toString(), ParserLanguage.C, true, 0);
}
/**
[--Start Example(C 6.10.3.5-7):
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };
--End Example]
*/
@Override
public void test6_10_3_5s7() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("#define t(x,y,z) x ## y ## z\n"); //$NON-NLS-1$
buffer.append("int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),\n"); //$NON-NLS-1$
buffer.append("t(10,,), t(,11,), t(,,12), t(,,) };\n"); //$NON-NLS-1$
// TODO: this only works on the C99 parser for now
parse(buffer.toString(), ParserLanguage.C, true, 0);
}
/**
* This test seems to be incorrect in AST2SpecTests
*/
@Override
public void test4s6() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */\n"); //$NON-NLS-1$
buffer.append("fesetround(FE_UPWARD);\n"); //$NON-NLS-1$
buffer.append("#endif\n"); //$NON-NLS-1$
parseCandCPP(buffer.toString(), false, 0);
}
@Override
public void test6_7_8s24() throws Exception { // complex isn't declared as a typedef
try {
super.test6_7_8s24();
fail();
} catch(AssertionFailedError _) { }
}
@Override
public void test6_7_8s34() throws Exception { // div_t isn't declared as a typedef
try {
super.test6_7_8s34();
fail();
} catch(AssertionFailedError _) { }
}
}

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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.TaskParserTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99TaskParserTest extends TaskParserTest {
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
}

View file

@ -0,0 +1,164 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2Tests;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
*
* @author Mike Kucera
*
*/
public class C99Tests extends AST2Tests {
public static TestSuite suite() {
return suite(C99Tests.class);
}
public C99Tests(String name) {
super(name);
}
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
public void testMultipleHashHash() throws Exception {
String code = "#define TWICE(a) int a##tera; int a##ther; \n TWICE(pan)";
parseAndCheckBindings(code, ParserLanguage.C);
}
public void testBug191279() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append(" /**/ \n");
sb.append("# define YO 99 /**/ \n");
sb.append("# undef YO /**/ ");
sb.append(" /* $ */ ");
String code = sb.toString();
parseAndCheckBindings(code, ParserLanguage.C);
}
public void testBug191324() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append("int x$y = 99; \n");
sb.append("int $q = 100; \n"); // can use $ as first character in identifier
sb.append("#ifndef SS$_INVFILFOROP \n");
sb.append("int z; \n");
sb.append("#endif \n");
String code = sb.toString();
parseAndCheckBindings(code, ParserLanguage.C);
}
public void testBug192009_implicitInt() throws Exception {
String code = "main() { int x; }";
IASTTranslationUnit tu = parse(code, ParserLanguage.C, false, true);
IASTDeclaration[] declarations = tu.getDeclarations();
assertEquals(1, declarations.length);
IASTFunctionDefinition main = (IASTFunctionDefinition) declarations[0];
ICASTSimpleDeclSpecifier declSpec = (ICASTSimpleDeclSpecifier) main.getDeclSpecifier();
assertEquals(0, declSpec.getType());
assertEquals("main", main.getDeclarator().getName().toString());
}
public void testBug93980() { // some wierd gcc extension I think
try {
super.testBug93980();
fail();
} catch(Throwable _) { }
}
public void testBug95866() { // gcc extension
try {
super.testBug95866();
fail();
} catch(Throwable _) { }
}
public void testBug80171() throws Exception { // implicit int not supported
try {
super.testBug80171();
fail();
} catch(Throwable _) { }
}
public void testBug196468_emptyArrayInitializer() { // empty array initializer is a gcc extension
try {
super.testBug196468_emptyArrayInitializer();
fail();
} catch(Throwable _) { }
}
public void testBug75340() { // not legal c99
try {
super.testBug75340();
fail();
} catch(Throwable _) { }
}
public void test92791() { // I think the test is wrong, the second code snippet contains a redeclaration
try {
super.test92791();
fail();
} catch(Throwable _) { }
}
public void testBug192165() { // gcc extension: typeof
try {
super.testBug192165();
fail();
} catch(Throwable _) { }
}
public void testBug191450_attributesInBetweenPointers() { // gcc extension: attributes
try {
super.testBug191450_attributesInBetweenPointers();
fail();
} catch(Throwable _) { }
}
}

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2UtilOldTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99UtilOldTests extends AST2UtilOldTests {
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
public void testCastExpression() throws Exception { // A not typedefed
try {
super.testCastExpression();
fail();
} catch(AssertionFailedError _) {}
}
}

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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
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.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2UtilTests;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class C99UtilTests extends AST2UtilTests {
protected IASTTranslationUnit parse( String code, ParserLanguage lang ) throws ParserException {
if(lang != ParserLanguage.C)
return super.parse(code, lang);
return parse(code, lang, false, true );
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions ) throws ParserException {
if(lang != ParserLanguage.C)
return super.parse(code, lang, useGNUExtensions);
return parse( code, lang, useGNUExtensions, true );
}
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);
}
protected BaseExtensibleLanguage getLanguage() {
return C99Language.getDefault();
}
}

View file

@ -0,0 +1,135 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.AssertionFailedError;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.core.runtime.CoreException;
/**
* Utility methods for parsing test code using the C99 LPG parser.
*
* @author Mike Kucera
*/
public class ParseHelper {
static int testsRun = 0;
private static class C99NameResolver extends ASTVisitor {
{
shouldVisitNames = true;
}
public int numProblemBindings=0;
public int numNullBindings=0;
public int visit( IASTName name ){
IBinding binding = name.resolveBinding();
if (binding instanceof IProblemBinding)
numProblemBindings++;
if (binding == null)
numNullBindings++;
return PROCESS_CONTINUE;
}
}
public static IASTTranslationUnit parse(char[] code, BaseExtensibleLanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
CodeReader codeReader = new CodeReader(code);
return parse(codeReader, lang, new ScannerInfo(), null, expectNoProblems, checkBindings, expectedProblemBindings);
}
public static IASTTranslationUnit parse(String code, BaseExtensibleLanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
return parse(code.toCharArray(), lang, expectNoProblems, checkBindings, expectedProblemBindings);
}
public static IASTTranslationUnit parse(String code, BaseExtensibleLanguage lang, boolean expectNoProblems) {
return parse(code, lang, expectNoProblems, false, 0);
}
public static IASTTranslationUnit parse(CodeReader codeReader, BaseExtensibleLanguage language, IScannerInfo scanInfo,
ICodeReaderFactory fileCreator, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
testsRun++;
IASTTranslationUnit tu;
try {
tu = language.getASTTranslationUnit(codeReader, scanInfo, fileCreator, null, ParserUtil.getParserLogService());
} catch (CoreException e) {
throw new AssertionFailedError(e.toString());
}
// should parse correctly first before we look at the bindings
if(expectNoProblems )
{
if (CVisitor.getProblems(tu).length != 0) {
throw new AssertionFailedError(" CVisitor has AST Problems " ); //$NON-NLS-1$
}
// TODO: actually collect preprocessor problems
if (tu.getPreprocessorProblems().length != 0) {
throw new AssertionFailedError(" C TranslationUnit has Preprocessor Problems " ); //$NON-NLS-1$
}
}
// resolve all bindings
if (checkBindings) {
C99NameResolver res = new C99NameResolver();
tu.accept( res );
if (res.numProblemBindings != expectedProblemBindings )
throw new AssertionFailedError("Expected " + expectedProblemBindings + " problem(s), encountered " + res.numProblemBindings ); //$NON-NLS-1$ //$NON-NLS-2$
}
return tu;
}
public static IASTTranslationUnit commentParse(String code, BaseExtensibleLanguage language) {
CodeReader codeReader = new CodeReader(code.toCharArray());
IASTTranslationUnit tu;
try {
tu = language.getASTTranslationUnit(codeReader, new ScannerInfo(), null, null, AbstractLanguage.OPTION_ADD_COMMENTS, ParserUtil.getParserLogService());
} catch (CoreException e) {
throw new AssertionFailedError(e.toString());
}
return tu;
}
public static IASTCompletionNode getCompletionNode(String code, BaseExtensibleLanguage lang) {
return getCompletionNode(code, lang, code.length());
}
public static IASTCompletionNode getCompletionNode(String code, BaseExtensibleLanguage language, int offset) {
CodeReader reader = new CodeReader(code.toCharArray());
return language.getCompletionNode(reader, new ScannerInfo(), null, null, ParserUtil.getParserLogService(), offset);
}
}

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.Test;
import junit.framework.TestSuite;
public class ParserTestSuite extends TestSuite {
// TODO: the following test are not being reused
//
// DOMGCCSelectionParseExtensionsTest
// DOMSelectionParseTest
// GCCCompleteParseExtensionsTest
// QuickParser2Tests
//
// and perhaps others
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(C99Tests.class); // has some tests that do fail
suite.addTestSuite(C99SpecTests.class); // a couple of failures
suite.addTestSuite(C99KnRTests.class); // mostly fail due to ambiguities
// The majority of the content assist test are in the ui tests plugin
suite.addTestSuite(C99CompletionBasicTest.class);
// this one still has a lot of failing tests though
suite.addTestSuite(C99SelectionParseTest.class);
suite.addTestSuite(C99DOMLocationInclusionTests.class);
suite.addTestSuite(C99DOMLocationTests.class);
suite.addTestSuite(C99DOMLocationMacroTests.class);
suite.addTestSuite(C99DOMPreprocessorInformationTest.class);
suite.addTestSuite(C99CommentTests.class);
suite.addTestSuite(C99DigraphTrigraphTests.class);
suite.addTestSuite(C99GCCTests.class);
suite.addTestSuite(C99UtilOldTests.class);
suite.addTestSuite(C99UtilTests.class);
suite.addTestSuite(C99CompleteParser2Tests.class);
suite.addTestSuite(C99TaskParserTest.class);
return suite;
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.core.parser.c99</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>net.sourceforge.metrics.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>net.sourceforge.metrics.nature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,12 @@
#Mon Jul 30 15:15:28 EDT 2007
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -0,0 +1,17 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name.1
Bundle-SymbolicName: org.eclipse.cdt.core.lrparser;singleton:=true
Bundle-Version: 4.0.1.qualifier
Bundle-ClassPath: .
Require-Bundle: org.eclipse.cdt.core,
net.sourceforge.lpg.lpgjavaruntime;bundle-version="1.1.0";visibility:=reexport,
org.eclipse.core.runtime
Export-Package: org.eclipse.cdt.core.dom.lrparser,
org.eclipse.cdt.core.dom.lrparser.action,
org.eclipse.cdt.core.dom.lrparser.action.c99,
org.eclipse.cdt.core.dom.lrparser.c99,
org.eclipse.cdt.internal.core.dom.lrparser.c99;x-internal:=true,
org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor.0

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 22, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
</body></html>

View file

@ -0,0 +1,24 @@
# about.ini
# contains information about a feature
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# "%key" are externalized strings defined in about.properties
# This file does not need to be translated.
# Property "aboutText" contains blurb for "About" dialog (translated)
aboutText=%blurb
# Property "windowImage" contains path to window icon (16x16)
# needed for primary features only
# Property "featureImage" contains path to feature image (32x32)
featureImage=eclipse32.gif
# Property "aboutImage" contains path to product image (500x330 or 115x164)
# needed for primary features only
# Property "appName" contains name of the application (translated)
# needed for primary features only
# Property "welcomePerspective" contains the id of the perspective in which the
# welcome page is to be opened.
# optional

View file

@ -0,0 +1,9 @@
# about.mappings
# contains fill-ins for about.properties
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# This file does not need to be translated.
# The following should contain the build version.
# e.g. "0=20020612"
# This value will be added automaticaly via the build scripts
0=@build@

View file

@ -0,0 +1,25 @@
###############################################################################
# Copyright (c) 2007 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
###############################################################################
# about.properties
# contains externalized strings for about.ini
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# fill-ins are supplied by about.mappings
# This file should be translated.
# NOTE TO TRANSLATOR: Please do not translate the featureVersion variable.
blurb=CDT C99 Parser Support\n\
\n\
Version: {featureVersion}\n\
Build id: {0}\n\
\n\
(c) Copyright Eclipse contributors and others, 2007. All rights reserved.\n\
Visit http://www.eclipse.org/cdt

View file

@ -0,0 +1,21 @@
###############################################################################
# Copyright (c) 2007 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
###############################################################################
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
plugin.properties,\
plugin.xml,\
eclipse32.gif,\
about.ini,\
about.mappings,\
about.properties

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,18 @@
###############################################################################
# Copyright (c) 2007 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
###############################################################################
Bundle-Name.0 = LR Parser Plug-in
Bundle-Vendor.0 = Eclipse.org
Bundle-Name.1 = LR Parser Plug-in
# built-in languages
language.name.c99= C99
language.name.isocpp= ISO C++

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension point="org.eclipse.cdt.core.language">
<language
class="org.eclipse.cdt.core.dom.lrparser.c99.C99Language"
id="c99"
name="%language.name.c99">
</language>
<language
class="org.eclipse.cdt.core.dom.lrparser.cpp.ISOCPPLanguage"
id="isocpp"
name="%language.name.isocpp">
</language>
<pdomLinkageFactory
class="org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCLinkageFactory"
id="c99"/>
<pdomLinkageFactory
class="org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkageFactory"
id="isocpp"/>
</extension>
</plugin>

View file

@ -0,0 +1,178 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.GCCScannerExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.model.ICLanguageKeywords;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTranslationUnit;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCLinkageFactory;
import org.eclipse.core.runtime.CoreException;
/**
* Implementation of the ILanguage extension point,
* provides the ability to add LPG based languages to CDT.
*
* @author Mike Kucera
*/
@SuppressWarnings("restriction")
public abstract class BaseExtensibleLanguage extends AbstractLanguage implements ILanguage, ICLanguageKeywords {
/**
* Retrieve the parser (runs after the preprocessor runs).
*
* Can be overridden in subclasses to provide a different parser
* for a language extension.
*/
protected abstract IParser getParser();
/**
* A token map is used to map tokens from the DOM preprocessor
* to the tokens defined by an LPG parser.
*/
protected abstract ITokenMap getTokenMap();
/**
* Normally all the AST nodes are created by the parser, but we
* need the root node ahead of time.
*
* The preprocessor is responsible for creating preprocessor AST nodes,
* so the preprocessor needs access to the translation unit so that it can
* set the parent pointers on the AST nodes it creates.
*
* @return an IASTTranslationUnit object thats empty and will be filled in by the parser
*/
protected abstract IASTTranslationUnit createASTTranslationUnit();
/**
* Returns the ParserLanguage value that is to be used when creating
* an instance of CPreprocessor.
*
*/
protected abstract ParserLanguage getParserLanguageForPreprocessor();
@Override
public Object getAdapter(Class adapter) {
if (adapter == IPDOMLinkageFactory.class)
return new PDOMCLinkageFactory();
return super.getAdapter(adapter);
}
@SuppressWarnings("nls")
@Override
public IASTTranslationUnit getASTTranslationUnit(CodeReader reader, IScannerInfo scanInfo,
ICodeReaderFactory fileCreator, IIndex index, int options, IParserLogService log) throws CoreException {
ILanguage gccLanguage = GCCLanguage.getDefault();
IASTTranslationUnit gtu = gccLanguage.getASTTranslationUnit(reader, scanInfo, fileCreator, index, log);
System.out.println();
System.out.println("********************************************************");
System.out.println("GCC AST:");
DebugUtil.printAST(gtu);
System.out.println();
//IParseResult parseResult = parse(reader, scanInfo, fileCreator, index, null, null);
//IASTTranslationUnit tu = parseResult.getTranslationUnit();
// TODO temporary
IScannerExtensionConfiguration config = new GCCScannerExtensionConfiguration();
ParserLanguage pl = getParserLanguageForPreprocessor();
IScanner preprocessor = new CPreprocessor(reader, scanInfo, pl, log, config, fileCreator);
preprocessor.setScanComments((options & OPTION_ADD_COMMENTS) != 0);
preprocessor.setComputeImageLocations((options & AbstractLanguage.OPTION_NO_IMAGE_LOCATIONS) == 0);
IParser parser = getParser();
IASTTranslationUnit tu = createTranslationUnit(index, preprocessor);
CPreprocessorAdapter.runCPreprocessor(preprocessor, parser, getTokenMap(), tu);
parser.parse(tu); // the parser will fill in the rest of the AST
System.out.println("Base Extensible Language AST:");
//DebugUtil.printAST(tu);
return tu;
}
public IASTTranslationUnit getASTTranslationUnit(CodeReader reader,
IScannerInfo scanInfo, ICodeReaderFactory fileCreator,
IIndex index, IParserLogService log) throws CoreException {
return getASTTranslationUnit(reader, scanInfo, fileCreator, index, 0, log);
}
public IASTCompletionNode getCompletionNode(CodeReader reader,
IScannerInfo scanInfo, ICodeReaderFactory fileCreator,
IIndex index, IParserLogService log, int offset) {
// TODO temporary
IScannerExtensionConfiguration config = new GCCScannerExtensionConfiguration();
ParserLanguage pl = getParserLanguageForPreprocessor();
IScanner preprocessor = new CPreprocessor(reader, scanInfo, pl, log, config, fileCreator);
preprocessor.setContentAssistMode(offset);
IParser parser = getParser();
IASTTranslationUnit tu = createTranslationUnit(index, preprocessor);
CPreprocessorAdapter.runCPreprocessor(preprocessor, parser, getTokenMap(), tu);
// the parser will fill in the rest of the AST
IASTCompletionNode completionNode = parser.parse(tu);
return completionNode;
}
/**
* Gets the translation unit object and sets the index and the location resolver.
*/
private IASTTranslationUnit createTranslationUnit(IIndex index, IScanner preprocessor) {
IASTTranslationUnit tu = createASTTranslationUnit();
tu.setIndex(index);
if(tu instanceof CASTTranslationUnit) {
((CASTTranslationUnit)tu).setLocationResolver(preprocessor.getLocationResolver());
}
return tu;
}
}

View file

@ -0,0 +1,107 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import lpg.lpgjavaruntime.IToken;
import lpg.lpgjavaruntime.Token;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IScanner;
/**
* Adapts the CPreprocessor from the CDT core for use with LPG based parsers.
*
* @author Mike Kucera
*
*/
class CPreprocessorAdapter {
/**
* During content assist the preprocessor may return a completion token
* which represents the identifier on which the user invoked content assist.
* The the preprocessor normally returns arbitrarily many end-of-completion
* (EOC) tokens.
*
* A bottom-up parser cannot know ahead of time how many EOC tokens are
* needed in order for the parse to complete successfully. So we pick
* a number that seems arbitrarily large enough.
*/
private static final int NUM_EOC_TOKENS = 50;
private static final int DUMMY_TOKEN_KIND = 0;
private static final int tCOMPLETION = org.eclipse.cdt.core.parser.IToken.tCOMPLETION;
private static final int tEND_OF_INPUT = org.eclipse.cdt.core.parser.IToken.tEND_OF_INPUT;
private static final int tEOC = org.eclipse.cdt.core.parser.IToken.tEOC;
/**
* Collect the tokens generated by the preprocessor.
*
* TODO: should preprocessor.nextTokenRaw() be called instead?
*/
@SuppressWarnings("restriction")
public static void runCPreprocessor(IScanner preprocessor, ITokenCollector tokenCollector, ITokenMap tokenMap, IASTTranslationUnit tu) {
// LPG requires that the token stream start with a dummy token
tokenCollector.addToken(createDummyToken());
preprocessor.getLocationResolver().setRootNode(tu);
try {
while(true) {
org.eclipse.cdt.core.parser.IToken domToken = preprocessor.nextToken(); // throws EndOfFileException
int type = domToken.getType();
IToken token = new LPGTokenAdapter(domToken, tokenMap.mapKind(type));
tokenCollector.addToken(token);
if(type == tCOMPLETION) {
// the token after the completion token must be an EOC token
org.eclipse.cdt.core.parser.IToken domEocToken = preprocessor.nextToken();
assert domEocToken.getType() == tEOC;
IToken eocToken = createEOCToken(domEocToken, tokenMap);
for(int i = 0; i < NUM_EOC_TOKENS; i++)
tokenCollector.addToken(eocToken); // reuse the same reference, no need to create several objects
break;
}
}
} catch (EndOfFileException e) {
// just break out of the loop
}
// LPG requires that the token stream end with an EOF token
tokenCollector.addToken(createEOFToken(tokenMap));
}
private static IToken createEOCToken(org.eclipse.cdt.core.parser.IToken domEocToken, ITokenMap tokenMap) {
return new LPGTokenAdapter(domEocToken, tokenMap.mapKind(domEocToken.getType()));
}
private static IToken createDummyToken() {
return new Token(null, 0, 0, DUMMY_TOKEN_KIND);
}
private static IToken createEOFToken(ITokenMap tokenMap) {
return new Token(null, 0, 0, tokenMap.mapKind(tEND_OF_INPUT));
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
/**
* Represents a parser that can be used by BaseExtensibleLanguage.
*
* @author Mike Kucera
*/
public interface IParser extends ITokenCollector {
/**
* Performs the actual parse.
*
* The given translation unit is assumed to not have any children, during the parse
* it will have its declaration fields filled in, resulting in a complete AST.
*
* If there were any errors during the parse these will be represented in the
* AST as problem nodes.
*
* If the parser encounters a completion token then a completion node
* is returned, null is returned otherwise.
*
* @param tu An IASTTranslationUnit instance that will have its declarators filled in.
* @return a completion node if a completion token is encountered during the parser, null otherwise.
*/
public IASTCompletionNode parse(IASTTranslationUnit tu);
}

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import java.util.List;
import lpg.lpgjavaruntime.IToken;
/**
* Provides an interface to the token stream that
* can be used by the parser semantic actions.
*
* Allows the semantic actions to directly inspect the token
* stream. Used to calculate AST node offsets and for
* other purposes.
*
* TODO There are still issues with getLeftIToken() and
* getRightIToken(), they should return null when used with
* an empty rule but currently they don't.
*
* @author Mike Kucera
*/
public interface IParserActionTokenProvider {
/**
* Returns the tokens that were parsed to recognized
* the currently executing rule.
*
* @returns a read-only list of tokens, will not be null but may be empty
*/
public List<IToken> getRuleTokens();
/**
* Usually equivalent to getRuleTokens().get(0); but more efficient.
*
* However, when called during an empty rule it will return the token to the
* left of the location of the empty rule.
*/
public IToken getLeftIToken();
/**
* Usually equivalent to getRuleTokens().get(getRuleTokens().size()-1); but more efficient.
*
* However, when called during an empty rule it will return the token to the
* right of the location of the empty rule.
*/
public IToken getRightIToken();
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
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 {
public void addToken(IToken token);
}

View file

@ -0,0 +1,121 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser;
import lpg.lpgjavaruntime.PrsStream;
/**
* The CPreprocessor from the CDT core returns tokens that
* are of the type org.eclipse.cdt.core.parser.IToken,
* however LPG wants the tokens to be of the type lpg.lpgjavaruntime.IToken.
*
* So these adapter objects are used to wrap the tokens returned
* by CPreprocessor so that they can be used with LPG.
*
* @author Mike Kucera
*/
class LPGTokenAdapter implements lpg.lpgjavaruntime.IToken {
/** The token object that is being wrapped */
private final org.eclipse.cdt.core.parser.IToken token;
private int tokenIndex;
private int adjunctIndex;
private int kind;
public LPGTokenAdapter(org.eclipse.cdt.core.parser.IToken token, int parserKind) {
this.token = token;
this.kind = parserKind;
}
public int getAdjunctIndex() {
return adjunctIndex;
}
public int getColumn() {
return 0;
}
public int getEndColumn() {
return 0;
}
public int getEndLine() {
return 0;
}
public int getEndOffset() {
return token.getEndOffset();
}
public lpg.lpgjavaruntime.IToken[] getFollowingAdjuncts() {
return null;
}
public int getKind() {
return kind;
}
public int getLine() {
return 0;
}
public lpg.lpgjavaruntime.IToken[] getPrecedingAdjuncts() {
return null;
}
public PrsStream getPrsStream() {
return null;
}
public int getStartOffset() {
return token.getOffset();
}
public int getTokenIndex() {
return tokenIndex;
}
@Deprecated
public String getValue(char[] arg0) {
return toString();
}
public void setAdjunctIndex(int adjunctIndex) {
this.adjunctIndex = adjunctIndex;
}
public void setEndOffset(int arg0) {
throw new UnsupportedOperationException();
}
public void setKind(int kind) {
this.kind = kind;
}
public void setStartOffset(int arg0) {
throw new UnsupportedOperationException();
}
public void setTokenIndex(int tokenIndex) {
this.tokenIndex = tokenIndex;
}
@Override
public String toString() {
return token.toString();
}
}

View file

@ -0,0 +1,94 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
import java.util.LinkedList;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
/**
* An AST node that represents the location of content assist
* in the source file.
*
* This node may contain the prefix text of an identifier up to the point. If
* there is no prefix, the completion occurred at the point where a new token
* would have begun.
*
* Contains a list of name nodes, each name represents an identifier
* at the point where content assist was invoked. There is usually
* a single name node, however if an ambiguity is detected then that section
* of the source may be interpreted in more than one way (for example, as an expression then as a declaration).
* This results in an ambiguity node in the tree and one name node for each of the ways it can be interpreted.
*
* The full AST may be accessed via getTranslationUnit() or by following
* the parent pointers of the name nodes.
*
* @author Mike Kucera
*/
public class ASTCompletionNode implements IASTCompletionNode {
private final LinkedList<IASTName> names = new LinkedList<IASTName>();
private final String prefix;
private final IASTTranslationUnit tu;
/**
* Creates a completion node.
* @throws NullPointerException if tu is null
* @throws IllegalArgumentException if prefix is the empty string, it should be null instead
*/
public ASTCompletionNode(String prefix, IASTTranslationUnit tu) {
if("".equals(prefix)) //$NON-NLS-1$
throw new IllegalArgumentException("prefix cannot be the empty string"); //$NON-NLS-1$
if(tu == null)
throw new NullPointerException("tu is null"); //$NON-NLS-1$
this.prefix = prefix;
this.tu = tu;
}
public void addName(IASTName name) {
names.add(name);
}
/**
* Returns the length of the prefix.
*/
public int getLength() {
return prefix == null ? 0 : prefix.length();
}
public IASTName[] getNames() {
return names.toArray(new IASTName[0]);
}
/**
* If the point of completion was at the end of a potential identifier, this
* string contains the text of that identifier.
*
* @returns a string of length >= 1 or null
*/
public String getPrefix() {
return prefix;
}
public IASTTranslationUnit getTranslationUnit() {
return tu;
}
}

View file

@ -0,0 +1,292 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
/**
* An immutable map, like you would find in a functional programming language.
*
* Inserting a new pair into the map leaves the original map untouched,
* instead a new map that contains the pair is returned. Therefore
* an assignment is needed to "modify" the map (just like with Strings).
*
* <code>
* myMap = myMap.insert(key,value);
* </code>
*
* There is no remove() method because it is not needed. In order to
* "delete" a pair from the map simply save a reference to an old version
* of the map and restore the map from that old reference. This makes
* "undo" operations trivial to implement.
*
* <code>
* FunctionalMap oldMap = myMap; // save a reference
* myMap = myMap.insert(key,value); // insert the pair into the map
* myMap = oldMap; // delete the pair from the map
* </code>
*
* This map is implemented as a red-black tree data structure,
* and is based on the implementation found at:
* http://www.eecs.usma.edu/webs/people/okasaki/jfp99.ps
*
* @author Mike Kucera
*/
public class FunctionalMap<K extends Comparable<K>, V> {
// better than an enum because enum variables can be null
private static final boolean RED = true, BLACK = false;
private static class Node<K, V> {
final K key;
final V val;
Node<K,V> left;
Node<K,V> right;
boolean color;
public Node(K key, V val, boolean color, Node<K,V> left, Node<K,V> right) {
this.key = key;
this.val = val;
this.left = left;
this.right = right;
this.color = color;
}
@Override public String toString() {
return "Node(" + key + "," + val + "," + (color ? "R" : "B") + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
}
}
private Node<K,V> root = null;
private FunctionalMap() {
// private constructor, use static factory method to instantiate
}
// factory method makes it cleaner to instantiate objects
public static <K extends Comparable<K>,V> FunctionalMap<K,V> emptyMap() {
return new FunctionalMap<K,V>();
}
/**
* Returns a new map that contains the key-value pair.
* @throws NullPointerException if key is null
*/
public FunctionalMap<K,V> insert(K key, V val) {
if(key == null)
throw new NullPointerException();
FunctionalMap<K,V> newMap = new FunctionalMap<K,V>();
newMap.root = insert(this.root, key, val);
newMap.root.color = BLACK; // force the root to be black
assert checkInvariants(newMap.root);
return newMap;
}
private Node<K,V> insert(Node<K,V> n, K key, V val) {
if(n == null)
return new Node<K,V>(key, val, RED, null, null); // new nodes are always red
int c = key.compareTo(n.key);
if(c < 0)
return balance(n.key, n.val, n.color, insert(n.left, key, val), n.right);
else if(c > 0)
return balance(n.key, n.val, n.color, n.left, insert(n.right, key, val));
else // equal, create a new node that overwrites the old value
return new Node<K,V>(key, val, n.color, n.left, n.right);
}
private Node<K,V> balance(K key, V val, boolean color, Node<K,V> left, Node<K,V> right) {
if(color == RED)
return new Node<K,V>(key, val, color, left, right);
final Node<K,V> newLeft, newRight;
// now for the madness...
if(left != null && left.color == RED) {
if(left.left != null && left.left.color == RED) {
newLeft = new Node<K,V>(left.left.key, left.left.val, BLACK, left.left.left, left.left.right);
newRight = new Node<K,V>(key, val, BLACK, left.right, right);
return new Node<K,V>(left.key, left.val, RED, newLeft, newRight);
}
if(left.right != null && left.right.color == RED) {
newLeft = new Node<K,V>(left.key, left.val, BLACK, left.left, left.right.left);
newRight = new Node<K,V>(key, val, BLACK, left.right.right, right);
return new Node<K,V>(left.right.key, left.right.val, RED, newLeft, newRight);
}
}
if(right != null && right.color == RED) {
if(right.left != null && right.left.color == RED) {
newLeft = new Node<K,V>(key, val, BLACK, left, right.left.left);
newRight = new Node<K,V>(right.key, right.val, BLACK, right.left.right, right.right);
return new Node<K,V>(right.left.key, right.left.val, RED, newLeft, newRight);
}
if(right.right != null && right.right.color == RED) {
newLeft = new Node<K,V>(key, val, BLACK, left, right.left);
newRight = new Node<K,V>(right.right.key, right.right.val, BLACK, right.right.left, right.right.right);
return new Node<K,V>(right.key, right.val, RED, newLeft, newRight);
}
}
return new Node<K,V>(key, val, BLACK, left, right);
}
/**
* Returns the value if it is in the map, null otherwise.
* @throws NullPointerException if key is null
*/
public V lookup(K key) {
if(key == null)
throw new NullPointerException();
// no need for recursion here
Node<K,V> n = root;
while(n != null) {
int x = key.compareTo(n.key); // throws NPE if key is null
if(x == 0)
return n.val;
n = (x < 0) ? n.left : n.right;
}
return null;
}
/**
* Returns true if there exists a mapping with the given key
* in this map.
* @throws NullPointerException if key is null
*/
public boolean containsKey(K key) {
if(key == null)
throw new NullPointerException();
// lookup uses an iterative algorithm
Node<K,V> n = root;
while(n != null) {
int x = key.compareTo(n.key); // throws NPE if key is null
if(x == 0)
return true;
n = (x < 0) ? n.left : n.right;
}
return false;
}
public boolean isEmpty() {
return root == null;
}
@Override public String toString() {
StringBuilder sb = new StringBuilder('[');
inorderPrint(root, sb);
sb.append(']');
return sb.toString();
}
private static <K,V> void inorderPrint(Node<K,V> n, StringBuilder sb) {
if(n == null)
return;
inorderPrint(n.left, sb);
if(sb.length() > 1)
sb.append(", ");//$NON-NLS-1$
sb.append(n.toString());
inorderPrint(n.right, sb);
}
void printStructure() {
if(root == null)
System.out.println("empty map"); //$NON-NLS-1$
else
printStructure(root, 0);
}
private static <K,V> void printStructure(Node<K,V> node, int level) {
for(int i = 0; i < level; i++)
System.out.print("--");//$NON-NLS-1$
if(node == null) {
System.out.println("null");//$NON-NLS-1$
}
else if(node.right == null && node.left == null) {
System.out.println(node);
}
else {
System.out.println(node);
printStructure(node.right, level + 1);
printStructure(node.left, level + 1);
}
}
private static <K,V> int depth(Node<K,V> node) {
if(node == null)
return 0;
return Math.max(depth(node.left), depth(node.right)) + 1;
}
/**
* Warning, this is a linear operation.
*/
public int size() {
return size(root);
}
private static <K,V> int size(Node<K,V> node) {
if(node == null)
return 0;
return size(node.left) + size(node.right) + 1;
}
/**********************************************************************************************
* Built-in testing
**********************************************************************************************/
private boolean checkInvariants(Node<K,V> n) {
// the number of black nodes on every path through the tree is the same
assertBalanced(n);
return true;
}
// not exactly sure if this is right
private int assertBalanced(Node<K,V> node) {
if(node == null)
return 1; // nulls are considered as black children
// both children of every red node are black
if(node.color == RED) {
assert node.left == null || node.left.color == BLACK;
assert node.right == null || node.right.color == BLACK;
}
int left = assertBalanced(node.left);
int right = assertBalanced(node.right);
assert left == right;
return left + (node.color == BLACK ? 1 : 0);
}
}

View file

@ -0,0 +1,168 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
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;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
/**
* Abstract factory interface for creating AST node objects.
*
* @author Mike Kucera
*/
public interface IASTNodeFactory {
public IASTName newName(char[] name);
public IASTName newName();
// TODO this should return IASTCompletionNode
public ASTCompletionNode newCompletionNode(String prefix, IASTTranslationUnit tu);
public IASTLiteralExpression newLiteralExpression(int kind, String rep);
public IASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand);
public IASTIdExpression newIdExpression(IASTName name);
public IASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript);
public IASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList);
public IASTExpressionList newExpressionList();
public IASTCastExpression newCastExpression(int operator, IASTTypeId typeId, IASTExpression operand);
public IASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2);
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3);
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement);
public IASTCaseStatement newCaseStatement(IASTExpression expr);
public IASTDefaultStatement newDefaultStatement();
public IASTExpressionStatement newExpressionStatement(IASTExpression expression);
public IASTNullStatement newNullStatement();
public IASTCompoundStatement newCompoundStatement();
public IASTSwitchStatement newSwitchStatment(IASTExpression controller, IASTStatement body);
public IASTIfStatement newIfStatement(IASTExpression condition, IASTStatement then, IASTStatement elseClause);
public IASTWhileStatement newWhileStatement(IASTExpression condition, IASTStatement body);
public IASTDoStatement newDoStatement(IASTStatement body, IASTExpression condition);
public IASTGotoStatement newGotoStatement(IASTName name);
public IASTContinueStatement newContinueStatement();
public IASTBreakStatement newBreakStatement();
public IASTReturnStatement newReturnStatement(IASTExpression retValue);
public IASTForStatement newForStatement(IASTStatement init, IASTExpression condition,
IASTExpression iterationExpression, IASTStatement body);
public IASTDeclarationStatement newDeclarationStatement(IASTDeclaration declaration);
public IASTTypeIdExpression newTypeIdExpression(int operator, IASTTypeId typeId);
public IASTTypeId newTypeId(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator);
public IASTDeclarator newDeclarator(IASTName name);
public IASTSimpleDeclaration newSimpleDeclaration(IASTDeclSpecifier declSpecifier);
public IASTInitializerExpression newInitializerExpression(IASTExpression expression);
public IASTInitializerList newInitializerList();
public IASTFunctionDefinition newFunctionDefinition(IASTDeclSpecifier declSpecifier,
IASTFunctionDeclarator declarator, IASTStatement bodyStatement);
public IASTTranslationUnit newTranslationUnit();
public IASTStandardFunctionDeclarator newFunctionDeclarator(IASTName name);
public IASTASMDeclaration newASMDeclaration(String assembly);
public IASTProblemDeclaration newProblemDeclaration();
public IASTProblemStatement newProblemStatement();
public IASTProblemExpression newProblemExpression();
public IASTProblem newProblem(int id, char[] arg, boolean warn, boolean error);
public IASTEnumerationSpecifier newEnumerationSpecifier(IASTName name);
public IASTEnumerator newEnumerator(IASTName name, IASTExpression value);
public IASTElaboratedTypeSpecifier newElaboratedTypeSpecifier(int kind, IASTName name);
public IASTArrayModifier newArrayModifier(IASTExpression expr);
public IASTArrayDeclarator newArrayDeclarator(IASTName name);
}

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
*********************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
/**
* Maps tokens defined in parser extensions back to the token kinds
* defined in the lr parsers.
*
* When LPG is used to generate a parser extension it will
* generate all-new token kinds. In order for the semantic actions to be able
* to interpret these token kinds correctly they will be mapped back
* to the token kinds defined in C99Parsersym.
*
* @author Mike Kucera
*/
public interface ITokenMap {
/**
* Maps the given token kind back to the same token kind defined in C99Parsersym.
*/
int mapKind(int kind);
}

View file

@ -0,0 +1,207 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
import static org.eclipse.cdt.core.dom.lrparser.util.CollectionUtils.reverseIterable;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* A stack that can be "marked", that is the stack can be divided
* into chunks that can be conveniently processed. There is always at
* least one open scope.
*
*
* This stack was designed to be used to store AST nodes while
* the AST is built during the parse, however it is useful for other
* purposes as well.
*
* Some grammar rules have arbitrary length lists on the right side.
* For example the rule for compound statements (where block_item_list is any
* number of statements or declarations):
*
* compound-statement ::= '{' <openscope-ast> block_item_list '}'
*
* There is a problem when trying to build the AST node for the compound statement...
* you don't know how many block_items are contained in the compound statement, so
* you don't know how many times to pop the AST stack.
*
* One inelegant solution is to count the block-items as they are parsed. This
* is inelegant because nested compound-statements are allowed so you would
* have to maintain several counts at the same time.
*
* Another solution would be to build the list of block-items as part of the
* block_item_list rule, but just using this stack is simpler.
*
* This class can be used as an AST stack that is implemented as a stack of "AST Scopes".
* There is a special grammar rule <openscope-ast> that creates a new AST Scope.
* So, in order to consume all the block_items, all that has to be done is
* iterate over the topmost scope and then close it when done.
*
*
* @author Mike Kucera
*/
public class ScopedStack<T> {
private LinkedList<T> topScope;
// A stack of stacks, used to implement scoping
private final LinkedList<LinkedList<T>> scopeStack;
/**
* Creates a new ScopedStack with the first scope already open.
*/
public ScopedStack() {
topScope = new LinkedList<T>();
scopeStack = new LinkedList<LinkedList<T>>();
}
/**
* Opens a new scope.
*/
public void openScope() {
scopeStack.add(topScope);
topScope = new LinkedList<T>();
}
/**
* Marks the stack then pushes all the items in the given list.
*
* @throws NullPointerException if items is null
*/
public void openScope(List<T> items) {
openScope();
for(T item : items)
push(item);
}
/**
* Marks the stack then pushes all the items in the given array.
*
* @throws NullPointerException if items is null
*/
public void openScope(T[] items) {
// looks the same as above but compiles into different bytecode
openScope();
for(T item : items)
push(item);
}
/**
* Pops all the items in the topmost scope.
* The outermost scope cannot be closed.
*
* @throws NoSuchElementException If the outermost scope is closed.
*/
public List<T> closeScope() {
if(scopeStack.isEmpty())
throw new NoSuchElementException("cannot close outermost scope"); //$NON-NLS-1$
List<T> top = topScope;
topScope = scopeStack.removeLast();
return top;
}
/**
* Pushes an item onto the topmost scope.
*/
public void push(T o) {
topScope.add(o);
}
/**
* @throws NoSuchElementException if the topmost scope is empty
*/
public T pop() {
return topScope.removeLast();
}
/**
* @throws NoSuchElementException if the topmost scope is empty
*/
public T peek() {
return topScope.getLast();
}
/**
* Returns the entire top scope as a List.
*/
public List<T> topScope() {
return topScope;
}
/**
* Returns the next outermost scope.
* @throws NoSuchElementException if size() < 2
*/
public List<T> outerScope() {
return scopeStack.getLast();
}
public boolean isEmpty() {
return topScope.isEmpty() && scopeStack.isEmpty();
}
/**
* Why oh why does java not have reverse iterators?????
*/
public void print() {
final String separator = "----------"; //$NON-NLS-1$
System.out.println();
System.out.println('-');
printScope(topScope);
System.out.println(separator);
for(LinkedList<T> list : reverseIterable(scopeStack)) {
printScope(list);
}
System.out.println();
}
private void printScope(List<T> scope) {
for(T t : reverseIterable(scope)) {
System.out.println(t);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(List<T> scope : scopeStack)
appendScopeContents(sb, scope);
appendScopeContents(sb, topScope);
return sb.toString();
}
private void appendScopeContents(StringBuilder sb, List<T> scope) {
sb.append('[');
boolean first = true;
for(T t : scope) {
if(first)
first = false;
else
sb.append(',');
sb.append(t);
}
sb.append(']');
}
}

View file

@ -0,0 +1,71 @@
/*******************************************************************************
* 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
*********************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
import java.util.HashMap;
import java.util.Map;
/**
* Maps token kinds from a sub-parser back to the corresponding
* token kinds in a base parser.
*
* @author Mike Kucera
*/
public class TokenMap implements ITokenMap {
// LPG token kinds start at 0
// the kind is not part of the base language parser
public static int INVALID_KIND = -1;
private int[] kindMap = null;
/**
* @param toSymbols An array of symbols where the index is the token kind and the
* element data is a string representing the token kind. It is expected
* to pass the orderedTerminalSymbols field from an LPG generated symbol
* file, for example C99Parsersym.orderedTerminalSymbols.
*/
public TokenMap(String[] toSymbols, String[] fromSymbols) {
// If this map is not being used with an extension then it becomes an "identity map".
if(toSymbols == fromSymbols)
return;
kindMap = new int[fromSymbols.length];
Map<String,Integer> toMap = new HashMap<String,Integer>();
for(int i = 0; i < toSymbols.length; i++) {
toMap.put(toSymbols[i], new Integer(i));
}
for(int i = 0; i < fromSymbols.length; i++) {
Integer kind = toMap.get(fromSymbols[i]);
kindMap[i] = kind == null ? INVALID_KIND : kind.intValue();
}
}
/**
* Maps a token kind back to the corresponding kind define in the base C99 parser.
*/
public int mapKind(int kind) {
if(kindMap == null)
return kind;
if(kind < 0 || kind >= kindMap.length)
return INVALID_KIND;
return kindMap[kind];
}
}

View file

@ -0,0 +1,425 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
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;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer;
import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
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.action.ASTCompletionNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTASMDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayDesignator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayModifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBreakStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCaseStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCastExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCompoundStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTContinueStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDeclarationStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDefaultStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDesignatedInitializer;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDoStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTElaboratedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTEnumerationSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTEnumerator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFieldDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFieldDesignator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTForStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionDefinition;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTGotoStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTIfStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTInitializerList;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTKnRFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTLabelStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTModifiedArrayModifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTName;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTNullStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTParameterDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTPointer;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTProblem;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTProblemDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTProblemExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTProblemStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTReturnStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTSimpleDeclSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTSwitchStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeIdInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypedefNameSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTWhileStatement;
@SuppressWarnings("restriction") // all AST node constructors are internal
/**
* Abstract factory implementation that creates AST nodes for C99.
* These can be overridden in subclasses to change the
* implementations of the nodes.
*
* @author Mike Kucera
*/
public class C99ASTNodeFactory implements IC99ASTNodeFactory {
public static final C99ASTNodeFactory DEFAULT_INSTANCE = new C99ASTNodeFactory();
public IASTName newName(char[] name) {
return new CASTName(name);
}
public IASTName newName() {
return new CASTName();
}
/**
* TODO: this should return IASTCompletionNode
*/
public ASTCompletionNode newCompletionNode(String prefix, IASTTranslationUnit tu) {
return new ASTCompletionNode((prefix == null || prefix.length() == 0) ? null : prefix, tu);
}
public IASTLiteralExpression newLiteralExpression(int kind, String rep) {
return new CASTLiteralExpression(kind, rep);
}
public IASTIdExpression newIdExpression(IASTName name) {
return new CASTIdExpression(name);
}
public IASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2) {
return new CASTBinaryExpression(op, expr1, expr2);
}
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3) {
return new CASTConditionalExpression(expr1, expr2, expr3);
}
public IASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
return new CASTArraySubscriptExpression(arrayExpr, subscript);
}
public IASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
return new CASTFunctionCallExpression(idExpr, argList);
}
public IASTExpressionList newExpressionList() {
return new CASTExpressionList();
}
public IASTFieldReference newFieldReference(IASTName name, IASTExpression owner, boolean isPointerDereference) {
return new CASTFieldReference(name, owner, isPointerDereference);
}
public IASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand) {
return new CASTUnaryExpression(operator, operand);
}
public IASTTypeIdExpression newTypeIdExpression(int operator, IASTTypeId typeId) {
return new CASTTypeIdExpression(operator, typeId);
}
public ICASTTypeIdInitializerExpression newCTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializerList list) {
return new CASTTypeIdInitializerExpression(typeId, list);
}
public IASTCastExpression newCastExpression(int operator, IASTTypeId typeId, IASTExpression operand) {
return new CASTCastExpression(typeId, operand);
}
public IASTTypeId newTypeId(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) {
return new CASTTypeId(declSpecifier, declarator);
}
public IASTDeclarator newDeclarator(IASTName name) {
return new CASTDeclarator(name);
}
public IASTArrayDeclarator newArrayDeclarator(IASTName name) {
return new CASTArrayDeclarator(name);
}
public ICASTArrayModifier newModifiedArrayModifier() {
return new CASTModifiedArrayModifier();
}
public IASTArrayModifier newArrayModifier(IASTExpression expr) {
return new CASTArrayModifier(expr);
}
public IASTStandardFunctionDeclarator newFunctionDeclarator(IASTName name) {
return new CASTFunctionDeclarator(name);
}
public ICASTKnRFunctionDeclarator newCKnRFunctionDeclarator() {
return new CASTKnRFunctionDeclarator();
}
public ICASTPointer newCPointer() {
return new CASTPointer();
}
public IASTParameterDeclaration newParameterDeclaration(IASTDeclSpecifier declSpec, IASTDeclarator declarator) {
return new CASTParameterDeclaration(declSpec, declarator);
}
public IASTInitializerExpression newInitializerExpression(IASTExpression expression) {
return new CASTInitializerExpression(expression);
}
public IASTInitializerList newInitializerList() {
return new CASTInitializerList();
}
public ICASTDesignatedInitializer newCDesignatedInitializer(IASTInitializer rhs) {
return new CASTDesignatedInitializer(rhs);
}
public ICASTArrayDesignator newCArrayDesignator(IASTExpression exp) {
return new CASTArrayDesignator(exp);
}
public ICASTFieldDesignator newCFieldDesignator(IASTName name) {
return new CASTFieldDesignator(name);
}
public ICASTSimpleDeclSpecifier newCSimpleDeclSpecifier() {
return new CASTSimpleDeclSpecifier();
}
public ICASTTypedefNameSpecifier newCTypedefNameSpecifier() {
return new CASTTypedefNameSpecifier();
}
public IASTSimpleDeclaration newSimpleDeclaration(IASTDeclSpecifier declSpecifier) {
return new CASTSimpleDeclaration(declSpecifier);
}
public IASTFieldDeclarator newFieldDeclarator(IASTName name, IASTExpression bitFieldSize) {
return new CASTFieldDeclarator(name, bitFieldSize);
}
public ICASTCompositeTypeSpecifier newCCompositeTypeSpecifier(int key, IASTName name) {
return new CASTCompositeTypeSpecifier(key, name);
}
public IASTElaboratedTypeSpecifier newElaboratedTypeSpecifier(int kind, IASTName name) {
return new CASTElaboratedTypeSpecifier(kind, name);
}
public IASTEnumerator newEnumerator(IASTName name, IASTExpression value) {
return new CASTEnumerator(name, value);
}
public IASTCompoundStatement newCompoundStatement() {
return new CASTCompoundStatement();
}
public IASTForStatement newForStatement(IASTStatement init, IASTExpression condition,
IASTExpression iterationExpression, IASTStatement body) {
return new CASTForStatement(init, condition, iterationExpression, body);
}
public IASTExpressionStatement newExpressionStatement(IASTExpression expr) {
return new CASTExpressionStatement(expr);
}
public IASTDeclarationStatement newDeclarationStatement(IASTDeclaration declaration) {
return new CASTDeclarationStatement(declaration);
}
public IASTNullStatement newNullStatement() {
return new CASTNullStatement();
}
public IASTWhileStatement newWhileStatement(IASTExpression condition, IASTStatement body) {
return new CASTWhileStatement(condition, body);
}
public IASTDoStatement newDoStatement(IASTStatement body, IASTExpression condition) {
return new CASTDoStatement(body, condition);
}
public IASTGotoStatement newGotoStatement(IASTName name) {
return new CASTGotoStatement(name);
}
public IASTContinueStatement newContinueStatement() {
return new CASTContinueStatement();
}
public IASTBreakStatement newBreakStatement() {
return new CASTBreakStatement();
}
public IASTReturnStatement newReturnStatement(IASTExpression retValue) {
return new CASTReturnStatement(retValue);
}
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement) {
return new CASTLabelStatement(name, nestedStatement);
}
public IASTCaseStatement newCaseStatement(IASTExpression expression) {
return new CASTCaseStatement(expression);
}
public IASTDefaultStatement newDefaultStatement() {
return new CASTDefaultStatement();
}
public IASTSwitchStatement newSwitchStatment(IASTExpression controller, IASTStatement body) {
return new CASTSwitchStatement(controller, body);
}
public IASTIfStatement newIfStatement(IASTExpression expr, IASTStatement thenStat, IASTStatement elseClause) {
return new CASTIfStatement(expr, thenStat, elseClause);
}
public IASTFunctionDefinition newFunctionDefinition(IASTDeclSpecifier declSpecifier,
IASTFunctionDeclarator declarator, IASTStatement bodyStatement) {
return new CASTFunctionDefinition(declSpecifier, declarator, bodyStatement);
}
public IASTProblemDeclaration newProblemDeclaration() {
return new CASTProblemDeclaration();
}
public IASTProblemStatement newProblemStatement() {
return new CASTProblemStatement();
}
public IASTProblemExpression newProblemExpression() {
return new CASTProblemExpression();
}
public IASTProblem newProblem(int id, char[] arg, boolean warn, boolean error) {
return new CASTProblem(id, arg, warn, error);
}
public IASTAmbiguousExpression newAmbiguousExpression() {
return new CASTAmbiguousExpression();
}
public IASTAmbiguousStatement newAmbiguousStatement() {
return new CASTAmbiguousStatement();
}
public IASTTranslationUnit newTranslationUnit() {
return new CASTTranslationUnit();
}
public IASTASMDeclaration newASMDeclaration(String assembly) {
return new CASTASMDeclaration(assembly);
}
public ICASTEnumerationSpecifier newEnumerationSpecifier(IASTName name) {
return new CASTEnumerationSpecifier(name);
}
}

View file

@ -0,0 +1,974 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Completion;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK__Bool;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK__Complex;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_auto;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_char;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_const;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_double;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_extern;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_float;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_identifier;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_inline;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_int;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_long;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_register;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_restrict;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_short;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_signed;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_static;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_typedef;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_unsigned;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_void;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_volatile;
import java.util.List;
import lpg.lpgjavaruntime.IToken;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
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.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
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.IParserActionTokenProvider;
import org.eclipse.cdt.core.dom.lrparser.action.BuildASTParserAction;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.dom.lrparser.action.TokenMap;
import org.eclipse.cdt.core.dom.lrparser.util.CollectionUtils;
import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
* Semantic actions called by the C99 parser to build an AST.
*
* @author Mike Kucera
*/
@SuppressWarnings("restriction")
public class C99BuildASTParserAction extends BuildASTParserAction {
private ITokenMap tokenMap = null;
/** Used to create the AST node objects */
protected final IC99ASTNodeFactory nodeFactory;
/**
* @param parser
* @param orderedTerminalSymbols When an instance of this class is created for a parser
* that parsers token kinds will be mapped back to the base C99 parser's token kinds.
*/
public C99BuildASTParserAction(IC99ASTNodeFactory nodeFactory, IParserActionTokenProvider parser, IASTTranslationUnit tu) {
super(nodeFactory, parser, tu);
this.nodeFactory = nodeFactory;
}
@Override protected boolean isCompletionToken(IToken token) {
return asC99Kind(token) == TK_Completion;
}
public void setTokenMap(String[] orderedTerminalSymbols) {
this.tokenMap = new TokenMap(C99Parsersym.orderedTerminalSymbols, orderedTerminalSymbols);
}
int asC99Kind(IToken token) {
return asC99Kind(token.getKind());
}
private int asC99Kind(int tokenKind) {
return tokenMap == null ? tokenKind : tokenMap.mapKind(tokenKind);
}
/********************************************************************
* Start of semantic actions.
********************************************************************/
/**
* postfix_expression ::= postfix_expression '.' ident
* postfix_expression ::= postfix_expression '->' ident
*/
public void consumeExpressionFieldReference(/*IBinding field, */ boolean isPointerDereference) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = createName(parser.getRightIToken());
//name.setBinding(field);
IASTExpression owner = (IASTExpression) astStack.pop();
IASTFieldReference expr = nodeFactory.newFieldReference(name, owner, isPointerDereference);
setOffsetAndLength(expr);
astStack.push(expr);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* postfix_expression ::= '(' type_name ')' '{' <openscope> initializer_list '}'
* postfix_expression ::= '(' type_name ')' '{' <openscope> initializer_list ',' '}'
*/
public void consumeExpressionTypeIdInitializer() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
consumeInitializerList(); // closes the scope
IASTInitializerList list = (IASTInitializerList) astStack.pop();
IASTTypeId typeId = (IASTTypeId) astStack.pop();
ICASTTypeIdInitializerExpression expr = nodeFactory.newCTypeIdInitializerExpression(typeId, list);
setOffsetAndLength(expr);
astStack.push(expr);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* Sets a token specifier.
* Needs to be overrideable for new decl spec keywords.
*
* @param token Allows subclasses to override this method and use any
* object to determine how to set a specifier.
*/
protected void setSpecifier(ICASTDeclSpecifier node, IToken token) {
int kind = asC99Kind(token);
switch(kind){
case TK_typedef: node.setStorageClass(IASTDeclSpecifier.sc_typedef); return;
case TK_extern: node.setStorageClass(IASTDeclSpecifier.sc_extern); return;
case TK_static: node.setStorageClass(IASTDeclSpecifier.sc_static); return;
case TK_auto: node.setStorageClass(IASTDeclSpecifier.sc_auto); return;
case TK_register: node.setStorageClass(IASTDeclSpecifier.sc_register); return;
case TK_inline: node.setInline(true); return;
case TK_const: node.setConst(true); return;
case TK_restrict: node.setRestrict(true); return;
case TK_volatile: node.setVolatile(true); return;
}
if(node instanceof ICASTSimpleDeclSpecifier) {
ICASTSimpleDeclSpecifier n = (ICASTSimpleDeclSpecifier) node;
switch(kind) {
case TK_void: n.setType(IASTSimpleDeclSpecifier.t_void); break;
case TK_char: n.setType(IASTSimpleDeclSpecifier.t_char); break;
case TK__Bool: n.setType(ICASTSimpleDeclSpecifier.t_Bool); break;
case TK_int: n.setType(IASTSimpleDeclSpecifier.t_int); break;
case TK_float: n.setType(IASTSimpleDeclSpecifier.t_float); break;
case TK_double: n.setType(IASTSimpleDeclSpecifier.t_double); break;
case TK_signed: n.setSigned(true); break;
case TK_unsigned: n.setUnsigned(true); break;
case TK_short: n.setShort(true); break;
case TK__Complex: n.setComplex(true); break;
case TK_long:
boolean isLong = n.isLong();
n.setLongLong(isLong);
n.setLong(!isLong);
break;
}
}
}
@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);
}
/**
* declarator ::= <openscope> pointer direct_declarator
*
* abstract_declarator -- a declarator that does not include an identifier
* ::= <openscope> pointer
* | <openscope> pointer direct_abstract_declarator
*/
public void consumeDeclaratorWithPointer(boolean hasDeclarator) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclarator decl;
if(hasDeclarator)
decl = (IASTDeclarator) astStack.pop();
else
decl = nodeFactory.newDeclarator(nodeFactory.newName());
// add all the pointers to the declarator
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
List<Object> scope = astStack.closeScope();
for(Object o : scope) {
decl.addPointerOperator((ICASTPointer)o);
}
setOffsetAndLength(decl);
astStack.push(decl);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* 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;
}
}
}
/**
* array_modifier
* ::= '[' <openscope> type_qualifier_list ']'
* | '[' <openscope> type_qualifier_list assignment_expression ']'
* | '[' 'static' assignment_expression ']'
* | '[' 'static' <openscope> type_qualifier_list assignment_expression ']'
* | '[' <openscope> type_qualifier_list 'static' assignment_expression ']'
* | '[' '*' ']'
* | '[' <openscope> type_qualifier_list '*' ']'
*
* The main reason to separate array_modifier into its own rule is to
* make calculating the offset and length much easier.
*/
public void consumeDirectDeclaratorModifiedArrayModifier(boolean isStatic,
boolean isVarSized, boolean hasTypeQualifierList, boolean hasAssignmentExpr) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
assert isStatic || isVarSized || hasTypeQualifierList;
ICASTArrayModifier arrayModifier = nodeFactory.newModifiedArrayModifier();
// consume all the stuff between the square brackets into an array modifier
arrayModifier.setStatic(isStatic);
arrayModifier.setVariableSized(isVarSized);
if(hasAssignmentExpr)
arrayModifier.setConstantExpression((IASTExpression)astStack.pop());
if(hasTypeQualifierList)
collectArrayModifierTypeQualifiers(arrayModifier);
setOffsetAndLength(arrayModifier);
astStack.push(arrayModifier);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* init_declarator ::= declarator '=' initializer
*/
public void consumeDeclaratorWithInitializer() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTInitializer initializer = (IASTInitializer) astStack.pop();
IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
declarator.setInitializer(initializer);
setOffsetAndLength(declarator); // adjust the length to include the initializer
}
@Deprecated public void consumeDeclaratorCompleteField(/*IBinding binding*/) {
//IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
//declarator.getName().setBinding(binding);
}
/**
* direct_declarator ::= direct_declarator '(' <openscope> parameter_type_list ')'
* direct_declarator ::= direct_declarator '(' ')'
*/
public void consumeDirectDeclaratorFunctionDeclarator(boolean hasParameters) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = nodeFactory.newName();
IASTStandardFunctionDeclarator declarator = nodeFactory.newFunctionDeclarator(name);
if(hasParameters) {
boolean isVarArgs = astStack.pop() == PLACE_HOLDER;
declarator.setVarArgs(isVarArgs);
for(Object o : astStack.closeScope()) {
declarator.addParameterDeclaration((IASTParameterDeclaration)o);
}
}
int endOffset = endOffset(parser.getRightIToken());
consumeDirectDeclaratorFunctionDeclarator(declarator, endOffset);
}
/**
* direct_declarator ::= direct_declarator '(' <openscope> identifier_list ')'
*/
public void consumeDirectDeclaratorFunctionDeclaratorKnR() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICASTKnRFunctionDeclarator declarator = nodeFactory.newCKnRFunctionDeclarator();
IASTName[] names = astStack.topScope().toArray(new IASTName[0]);
declarator.setParameterNames(names);
astStack.closeScope();
int endOffset = endOffset(parser.getRightIToken());
consumeDirectDeclaratorFunctionDeclarator(declarator, endOffset);
}
/**
* identifier_list
* ::= 'identifier'
* | identifier_list ',' 'identifier'
*/
public void consumeIdentifierKnR() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = createName(parser.getRightIToken());
astStack.push(name);
}
/**
* pointer ::= '*'
* | pointer '*'
*/
public void consumePointer() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTPointer pointer = nodeFactory.newCPointer();
IToken star = parser.getRightIToken();
setOffsetAndLength(pointer, star);
astStack.push(pointer);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* pointer ::= '*' <openscope> type_qualifier_list
* | pointer '*' <openscope> type_qualifier_list
*/
public void consumePointerTypeQualifierList() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICASTPointer pointer = nodeFactory.newCPointer();
for(Object o : astStack.closeScope()) {
IToken token = (IToken)o;
switch(asC99Kind(token)) {
default: assert false;
case TK_const: pointer.setConst(true); break;
case TK_volatile: pointer.setVolatile(true); break;
case TK_restrict: pointer.setRestrict(true); break;
}
}
setOffsetAndLength(pointer);
astStack.push(pointer);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* parameter_declaration ::= declaration_specifiers declarator
* | declaration_specifiers abstract_declarator
*/
public void consumeParameterDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclarator declarator = (IASTDeclarator) astStack.pop();
IASTDeclSpecifier declSpec = (IASTDeclSpecifier) astStack.pop();
IASTParameterDeclaration declaration = nodeFactory.newParameterDeclaration(declSpec, declarator);
setOffsetAndLength(declaration);
astStack.push(declaration);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* parameter_declaration ::= declaration_specifiers
*/
public void consumeParameterDeclarationWithoutDeclarator(/*IBinding binding*/) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
// offsets need to be calculated differently in this case
final int endOffset = parser.getRightIToken().getEndOffset() + 1;
IASTName name = nodeFactory.newName();
setOffsetAndLength(name, endOffset, 0);
//name.setBinding(binding);
// it appears that a declarator is always required in the AST here
IASTDeclarator declarator = nodeFactory.newDeclarator(name);
setOffsetAndLength(declarator, endOffset, 0);
IASTDeclSpecifier declSpec = (IASTDeclSpecifier) astStack.pop();
IASTParameterDeclaration declaration = nodeFactory.newParameterDeclaration(declSpec, declarator);
setOffsetAndLength(declaration);
astStack.push(declaration);
if(TRACE_AST_STACK) System.out.println(astStack);
}
@Deprecated public void consumeDeclaratorCompleteParameter(/*IBinding binding*/) {
//if(DEBUG) DebugUtil.printMethodTrace();
//IASTDeclarator declarator = (IASTDeclarator) astStack.peek();
//declarator.getName().setBinding(binding);
}
/**
* direct_abstract_declarator
* ::= array_modifier
* | direct_abstract_declarator array_modifier
*/
public void consumeAbstractDeclaratorArrayModifier(boolean hasDeclarator) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTArrayModifier arrayModifier = (IASTArrayModifier) astStack.pop();
if(hasDeclarator) {
consumeDeclaratorArray(arrayModifier);
}
else {
IASTArrayDeclarator decl = nodeFactory.newArrayDeclarator(nodeFactory.newName());
decl.addArrayModifier(arrayModifier);
setOffsetAndLength(decl);
astStack.push(decl);
if(TRACE_AST_STACK) System.out.println(astStack);
}
}
/**
* direct_abstract_declarator
* ::= '(' ')'
* | direct_abstract_declarator '(' ')'
* | '(' <openscope> parameter_type_list ')'
* | direct_abstract_declarator '(' <openscope> parameter_type_list ')'
*/
public void consumeAbstractDeclaratorFunctionDeclarator(boolean hasDeclarator, boolean hasParameters) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTStandardFunctionDeclarator declarator = nodeFactory.newFunctionDeclarator(nodeFactory.newName());
if(hasParameters) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
for(Object o : astStack.closeScope()) {
declarator.addParameterDeclaration((IASTParameterDeclaration)o);
}
}
if(hasDeclarator) {
consumeDirectDeclaratorFunctionDeclarator(declarator, endOffset(parser.getRightIToken()));
}
else {
setOffsetAndLength(declarator);
astStack.push(declarator);
if(TRACE_AST_STACK) System.out.println(astStack);
}
}
/**
* designated_initializer ::= <openscope> designation initializer
*/
public void consumeInitializerDesignated() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTInitializer initializer = (IASTInitializer)astStack.pop();
ICASTDesignatedInitializer result = nodeFactory.newCDesignatedInitializer(initializer);
for(Object o : astStack.closeScope())
result.addDesignator((ICASTDesignator)o);
setOffsetAndLength(result);
astStack.push(result);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* designator ::= '[' constant_expression ']'
*/
public void consumeDesignatorArray() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTExpression expr = (IASTExpression) astStack.pop();
ICASTArrayDesignator designator = nodeFactory.newCArrayDesignator(expr);
setOffsetAndLength(designator);
astStack.push(designator);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* designator ::= '.' 'identifier'
*/
public void consumeDesignatorField(/*IBinding binding*/) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = createName( parser.getRightIToken() );
//name.setBinding(binding);
ICASTFieldDesignator designator = nodeFactory.newCFieldDesignator(name);
setOffsetAndLength(designator);
astStack.push(designator);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* declaration_specifiers ::= <openscope> simple_declaration_specifiers
*/
public void consumeDeclarationSpecifiersSimple() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICASTSimpleDeclSpecifier declSpec = nodeFactory.newCSimpleDeclSpecifier();
for(Object token : astStack.closeScope())
setSpecifier(declSpec, (IToken)token);
setOffsetAndLength(declSpec);
astStack.push(declSpec);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* declaration_specifiers ::= <openscope> struct_or_union_declaration_specifiers
* declaration_specifiers ::= <openscope> enum_declaration_specifiers
*/
public void consumeDeclarationSpecifiersStructUnionEnum() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
List<Object> topScope = astStack.closeScope();
ICASTDeclSpecifier declSpec = CollectionUtils.findFirstAndRemove(topScope, ICASTDeclSpecifier.class);
// now apply the rest of the specifiers
for(Object token : topScope)
setSpecifier(declSpec, (IToken)token);
setOffsetAndLength(declSpec);
astStack.push(declSpec);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* declaration_specifiers ::= <openscope> typdef_name_declaration_specifiers
*/
public void consumeDeclarationSpecifiersTypedefName() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICASTTypedefNameSpecifier declSpec = nodeFactory.newCTypedefNameSpecifier();
for(Object o : astStack.topScope()) {
if(o instanceof IToken) {
IToken token = (IToken) o;
// There is one identifier token on the stack
int kind = asC99Kind(token);
if(kind == TK_identifier || kind == TK_Completion) {
IASTName name = createName(token);
//name.setBinding(binding);
declSpec.setName(name);
}
else {
setSpecifier(declSpec, token);
}
}
}
astStack.closeScope();
setOffsetAndLength(declSpec);
astStack.push(declSpec);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* external_declaration ::= ';'
*
* TODO: doesn't the declaration need a name?
*/
public void consumeDeclarationEmpty() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclSpecifier declSpecifier = nodeFactory.newCSimpleDeclSpecifier();
IASTSimpleDeclaration declaration = nodeFactory.newSimpleDeclaration(declSpecifier);
setOffsetAndLength(declSpecifier);
setOffsetAndLength(declaration);
astStack.push(declaration);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* a declaration inside of a struct
*
* struct_declaration ::= specifier_qualifier_list <openscope> struct_declarator_list ';'
*
* specifier_qualifier_list is a subset of declaration_specifiers,
* struct_declarators are declarators that are allowed inside a struct,
* a struct declarator is a regular declarator plus bit fields
*/
public void consumeStructDeclaration(boolean hasDeclaration) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
consumeDeclarationSimple(hasDeclaration); // TODO this is ok as long as bit fields implement IASTDeclarator (see consumeDeclaration())
}
/**
* struct_declarator
* ::= ':' constant_expression
* | declarator ':' constant_expression
*/
public void consumeStructBitField(boolean hasDeclarator) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTExpression expr = (IASTExpression)astStack.pop();
IASTName name;
if(hasDeclarator) // it should have been parsed into a regular declarator
name = ((IASTDeclarator) astStack.pop()).getName();
else
name = nodeFactory.newName();
IASTFieldDeclarator fieldDecl = nodeFactory.newFieldDeclarator(name, expr);
setOffsetAndLength(fieldDecl);
astStack.push(fieldDecl);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* struct_or_union_specifier
* ::= 'struct' '{' <openscope> struct_declaration_list_opt '}'
* | 'union' '{' <openscope> struct_declaration_list_opt '}'
* | 'struct' struct_or_union_identifier '{' <openscope> struct_declaration_list_opt '}'
* | 'union' struct_or_union_identifier '{' <openscope> struct_declaration_list_opt '}'
*
* @param key either k_struct or k_union from IASTCompositeTypeSpecifier
*/
public void consumeTypeSpecifierComposite(boolean hasName, int key) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = (hasName) ? createName(parser.getRuleTokens().get(1)) : nodeFactory.newName();
ICASTCompositeTypeSpecifier typeSpec = nodeFactory.newCCompositeTypeSpecifier(key, name);
for(Object o : astStack.closeScope())
typeSpec.addMemberDeclaration((IASTDeclaration)o);
setOffsetAndLength(typeSpec);
astStack.push(typeSpec);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* struct_or_union_specifier
* ::= 'struct' struct_or_union_identifier
* | 'union' struct_or_union_identifier
*
* enum_specifier ::= 'enum' enum_identifier
*/
public void consumeTypeSpecifierElaborated(int kind /*, IBinding binding*/) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTName name = createName(parser.getRuleTokens().get(1));
//name.setBinding(binding);
IASTElaboratedTypeSpecifier typeSpec = nodeFactory.newElaboratedTypeSpecifier(kind, name);
setOffsetAndLength(typeSpec);
astStack.push(typeSpec);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* iteration_statement ::= 'while' '(' expression ')' statement
*/
public void consumeStatementWhileLoop() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTStatement body = (IASTStatement) astStack.pop();
IASTExpression condition = (IASTExpression) astStack.pop();
IASTWhileStatement whileStatement = nodeFactory.newWhileStatement(condition, body);
setOffsetAndLength(whileStatement);
astStack.push(whileStatement);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* block_item ::= declaration | statement
*
* Wrap a declaration in a DeclarationStatement.
*/
public void consumeStatementDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTDeclaration decl = (IASTDeclaration) astStack.pop();
if(disambiguateHackIdentifierExpression(decl))
return;
IASTDeclarationStatement stat = nodeFactory.newDeclarationStatement(decl);
setOffsetAndLength(stat);
astStack.push(stat);
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
*/
public void consumeStatementSwitch() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTStatement body = (IASTStatement) astStack.pop();
IASTExpression expr = (IASTExpression) astStack.pop();
IASTSwitchStatement stat = nodeFactory.newSwitchStatment(expr, body);
setOffsetAndLength(stat);
astStack.push(stat);
if(TRACE_AST_STACK) System.out.println(astStack);
}
public void consumeStatementIf(boolean hasElse) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTStatement elseClause = null;
if(hasElse)
elseClause = (IASTStatement) astStack.pop();
IASTStatement thenClause = (IASTStatement) astStack.pop();
IASTExpression condition = (IASTExpression) astStack.pop();
IASTIfStatement ifStatement = nodeFactory.newIfStatement(condition, thenClause, elseClause);
setOffsetAndLength(ifStatement);
astStack.push(ifStatement);
if(TRACE_AST_STACK) System.out.println(astStack);
}
/**
* function_definition
* ::= declaration_specifiers <openscope> declarator compound_statement
* | function_declarator compound_statement
*
* The seemingly pointless <openscope> is just there to
* prevent a shift/reduce conflict in the grammar.
*/
public void consumeFunctionDefinition(boolean hasDeclSpecifiers) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(String.valueOf(hasDeclSpecifiers));
IASTCompoundStatement body = (IASTCompoundStatement) astStack.pop();
IASTFunctionDeclarator decl = (IASTFunctionDeclarator) astStack.pop();
astStack.closeScope();
IASTDeclSpecifier declSpecifier;
if(hasDeclSpecifiers) {
declSpecifier = (IASTDeclSpecifier) astStack.pop();
}
else { // there are no decl specifiers, implicit int
declSpecifier = nodeFactory.newCSimpleDeclSpecifier();
}
IASTFunctionDefinition def = nodeFactory.newFunctionDefinition(declSpecifier, decl, body);
setOffsetAndLength(def);
astStack.push(def);
if(TRACE_AST_STACK) System.out.println(astStack);
}
@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
* <openscope> declaration_list compound_statement
*/
public void consumeFunctionDefinitionKnR() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IASTCompoundStatement body = (IASTCompoundStatement) astStack.pop();
IASTDeclaration[] declarations = (IASTDeclaration[]) astStack.topScope().toArray(new IASTDeclaration[0]);
astStack.closeScope();
ICASTKnRFunctionDeclarator decl = (ICASTKnRFunctionDeclarator) astStack.pop();
astStack.closeScope();
ICASTSimpleDeclSpecifier declSpecifier = (ICASTSimpleDeclSpecifier) astStack.pop();
decl.setParameterDeclarations(declarations);
// re-compute the length of the declaration to take the parameter declarations into account
ASTNode lastDeclaration = (ASTNode) declarations[declarations.length-1];
int endOffset = lastDeclaration.getOffset() + lastDeclaration.getLength();
((ASTNode)decl).setLength(endOffset - offset(decl));
IASTFunctionDefinition def = nodeFactory.newFunctionDefinition(declSpecifier, decl, body);
setOffsetAndLength(def);
astStack.push(def);
if(TRACE_AST_STACK) System.out.println(astStack);
}
}

View file

@ -0,0 +1,111 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import org.eclipse.cdt.core.dom.lrparser.action.FunctionalMap;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Binding;
/**
* A facade for a FunctionalMap to make it behave like
* a symbol table for C99.
*
* In particular we need to be able to lookup identifiers based both
* on the String representation of the identifier and its "namespace".
*
* @author Mike Kucera
*/
@Deprecated public class C99SymbolTable {
/**
* Adapter objects are used as the keys. The trick here is to implement
* compareTo() in such a way that identifiers are separated by their namespace.
*/
private static class Key implements Comparable<Key> {
private final String ident;
private final CNamespace namespace;
public Key(CNamespace namespace, String ident) {
if(namespace == null || ident == null)
throw new NullPointerException();
this.ident = ident;
this.namespace = namespace;
}
public int compareTo(Key x) {
// this separates namespaces in the symbol table
int c = namespace.compareTo(x.namespace);
// only if the namespace is the same do we check the identifier
return (c == 0) ? ident.compareTo(x.ident) : c;
}
@Override public String toString() {
return ident + "::" + namespace;//$NON-NLS-1$
}
}
/**
* Start with EMPTY_TABLE and build up a symbol table using insert().
*/
public static final C99SymbolTable EMPTY_TABLE = new C99SymbolTable();
// the map we are providing a facade for
private final FunctionalMap<Key,IC99Binding> map;
/**
* Constructors are private, start with EMPTY_TABLE
* and build it up using insert().
*/
private C99SymbolTable() {
map = FunctionalMap.emptyMap();
}
private C99SymbolTable(FunctionalMap<Key,IC99Binding> newRoot) {
map = newRoot;
}
/**
* Returns a new symbol table that contains the given mapping.
* @throws NullPointerException if the namespace or key is null.
*/
public C99SymbolTable insert(CNamespace ns, String key, IC99Binding binding) {
return new C99SymbolTable(map.insert(new Key(ns, key), binding));
}
/**
* Looks up the binding given its namespace and identifier.
* @return null If there is no binding corresponding to the key.
* @throws NullPointerException if the namespace or key is null.
*/
public IC99Binding lookup(CNamespace ns, String key) {
return map.lookup(new Key(ns, key));
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.size() == 0;
}
@Override public String toString() {
return map.toString();
}
// void printStructure() {
// map.printStructure();
// }
}

View file

@ -0,0 +1,354 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import java.util.LinkedList;
import lpg.lpgjavaruntime.IToken;
import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider;
import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
/**
* A simple set of trial and undo actions that just keep track
* of typedef names. This information is then fed back to the parser
* in order to disambiguate certain parser grammar rules.
*
* The command design pattern is used to implement undo actions.
*
* @author Mike Kucera
*/
public class C99TypedefTrackerParserAction {
private static final boolean DEBUG = true;
// provides limited access to the token stream
private final IParserActionTokenProvider parser;
// The symbolTable currently in use
private TypedefSymbolTable symbolTable = TypedefSymbolTable.EMPTY_TABLE;
// A stack that keeps track of scopes in the symbol table, used to "close" scopes and to undo the opening of scopes
private final LinkedList<TypedefSymbolTable> symbolTableScopeStack = new LinkedList<TypedefSymbolTable>();
// keeps track of nested declarations
private final LinkedList<DeclaratorFrame> declarationStack = new LinkedList<DeclaratorFrame>();
// "For every action there is an equal and opposite reaction." - Newton's third law
private final LinkedList<IUndoAction> undoStack = new LinkedList<IUndoAction>();
/**
* A command object that provides undo functionality.
*/
private interface IUndoAction {
void undo();
}
/**
* Undoes the last fired action.
*/
public void undo() {
undoStack.removeLast().undo();
}
public C99TypedefTrackerParserAction(IParserActionTokenProvider parser) {
this.parser = parser;
}
/**
* Lexer feedback hack, used by the parser to identify typedefname tokens.
*/
public boolean isTypedef(String ident) {
return symbolTable.contains(ident);
}
/**
* Methods used by tests, package local access.
*/
TypedefSymbolTable getSymbolTable() {
return symbolTable;
}
int undoStackSize() {
return undoStack.size();
}
LinkedList<DeclaratorFrame> getDeclarationStack() {
return declarationStack;
}
/**
* Called from the grammar file in places where a scope is created.
*
* Scopes are created by compound statements, however special care
* must also be taken with for loops because they may contain
* declarations.
*
* TODO: scope object now need to be handled explicitly
*/
public void openSymbolScope() {
if(DEBUG) DebugUtil.printMethodTrace();
symbolTableScopeStack.add(symbolTable);
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
symbolTable = symbolTableScopeStack.removeLast();
}
});
}
public void closeSymbolScope() {
if(DEBUG) DebugUtil.printMethodTrace();
final TypedefSymbolTable undoTable = symbolTable;
symbolTable = symbolTableScopeStack.removeLast(); // close the scope
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
symbolTableScopeStack.add(symbolTable);
symbolTable = undoTable;
}
});
}
/**
* Called from the grammar before a declaration is about to be reduced.
*/
public void openDeclarationScope() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.add(new DeclaratorFrame());
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.removeLast();
}
});
}
public void closeDeclarationScope() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame undoFrame = declarationStack.removeLast();
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.add(undoFrame);
}
});
}
public void consumeFunctionDefinition() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.removeLast();
final TypedefSymbolTable undoTable = symbolTable;
symbolTable = symbolTableScopeStack.removeLast();
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
symbolTableScopeStack.add(symbolTable);
symbolTable = undoTable;
declarationStack.add(frame);
}
});
}
public void consumeDeclSpecToken() {
if(DEBUG) DebugUtil.printMethodTrace();
IToken token = parser.getRightIToken();
final int kind = token.getKind();
// creates a DeclSpec if there isn't one already
DeclaratorFrame frame = declarationStack.getLast();
final DeclSpec declSpec = frame.getDeclSpec();
declSpec.add(kind);
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declSpec.remove(kind);
}
});
}
public void consumeDirectDeclaratorIdentifier() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.getLast();
frame.setDeclaratorName(parser.getRightIToken());
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
frame.setDeclaratorName(null);
}
});
}
public void consumeDeclaratorComplete() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.getLast();
IToken token = frame.getDeclaratorName();
DeclSpec declSpec = frame.getDeclSpec();
String ident = (token == null) ? null : token.toString();
//System.out.println("declarator complete: " + ident);
final TypedefSymbolTable oldTable = symbolTable;
if(declSpec.isTypedef()) {
//System.out.println("adding typedef: " + ident);
symbolTable = symbolTable.add(ident);
}
declarationStack.removeLast();
declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.removeLast();
declarationStack.add(frame);
symbolTable = oldTable;
}
});
}
public void consumeDeclaratorCompleteParameter() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.removeLast();
//declarationStack.getLast().addNestedDeclaration(parameterBinding);
// parameter declarations can only have one declarator, so don't reset
//declarationStack.add(new DeclaratorFrame()); // reset
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
//declarationStack.removeLast();
//declarationStack.getLast().removeLastNestedDeclaration();
declarationStack.add(frame);
}
});
}
/**
* This is a special case for the rule:
* parameter_declaration ::= declaration_specifiers
*
* In this case there is no declarator at all
*
* TODO: creating bindings that have no identifier seems really dumb,
* why does it need to be done? Why not just have a null binding or
* for that matter don't even have a name node
*
*/
public void consumeParameterDeclarationWithoutDeclarator() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.removeLast();
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.add(frame);
}
});
}
public void consumeDeclaratorCompleteField() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.removeLast();
declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.removeLast();
declarationStack.add(frame);
}
});
}
/**
* An abstract declarator used as part of an expression, eg) a cast.
* Only need the type.
*
* TODO: this isn't enough, I need a binding for the abstract declarator
* what I really need is a consumeDeclaratorCompleteTypeId similar to above
*/
public void consumeTypeId() {
if(DEBUG) DebugUtil.printMethodTrace();
final DeclaratorFrame frame = declarationStack.removeLast();
undoStack.add(new IUndoAction() {
public void undo() {
if(DEBUG) DebugUtil.printMethodTrace();
declarationStack.add(frame);
}
});
}
}

View file

@ -0,0 +1,29 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
/**
* The C language has 4 namespaces for identifiers.
* This enum represents three of them, the "member" namespace
* is represented by IStructure.getFields().
*
* The symbol table uses these to mark identifiers and keep
* the namespaces separate.
*
* @author Mike Kucera
*/
@Deprecated public enum CNamespace {
GOTO_LABEL, // goto labels
STRUCT_TAG,// structs, unions, enums
IDENTIFIER; // all other identifiers
}

View file

@ -0,0 +1,168 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.*;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99BasicType;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Function;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99QualifierType;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable;
/**
* Keeps track of declaration specifiers during the parse.
* Used to compute types and determine if a declarator is a typedef.
*
* @author Mike Kucera
*/
class DeclSpec {
// maps token kinds to the number of occurrences of that kind
private Map<Integer,Integer> tokenKindMap = new HashMap<Integer,Integer>();
private IType type = null;
public void add(int kind) {
tokenKindMap.put(kind, count(kind) + 1);
}
public void remove(final int kind) {
Integer count = tokenKindMap.get(kind);
if(count == null)
return;
if(count <= 1)
tokenKindMap.remove(kind);
else
tokenKindMap.put(kind, count - 1);
}
public boolean contains(int kind) {
return tokenKindMap.containsKey(kind);
}
public boolean isTypedef() {
return contains(C99Parsersym.TK_typedef);
}
/**
* Need to keep track of how many times a particular
* declaration specifier appears in order to support
* long long.
*/
public int count(int kind) {
Integer count = tokenKindMap.get(kind);
return count == null ? 0 : count;
}
/**
* Set if the type should be a structure.
*/
public void setType(IType type) {
this.type = type;
}
public IType getType() {
if(type != null)
return type;
if(tokenKindMap.isEmpty()) // there are no type tokens, so it must be implicit int
return new C99BasicType(ICBasicType.t_int);
C99BasicType basicType = new C99BasicType();
for(int kind : tokenKindMap.keySet()) {
switch(kind) {
case TK_void:
basicType.setType(ICBasicType.t_void);
break;
case TK_char:
basicType.setType(ICBasicType.t_char);
break;
case TK_int:
basicType.setType(ICBasicType.t_int);
break;
case TK_float:
basicType.setType(ICBasicType.t_float);
break;
case TK_double:
basicType.setType(ICBasicType.t_double);
break;
case TK_long:
boolean isLongLong = count(TK_long) > 1;
basicType.setLongLong(isLongLong);
basicType.setLong(!isLongLong);
break;
case TK_signed:
basicType.setSigned(true);
break;
case TK_unsigned:
basicType.setUnsigned(true);
break;
case TK_short:
basicType.setShort(true);
break;
case TK__Bool:
basicType.setType(ICBasicType.t_Bool);
break;
case TK__Complex:
basicType.setComplex(true);
break;
case TK__Imaginary:
basicType.setImaginary(true);
break;
}
}
boolean isConst = contains(TK_const);
boolean isRestrict = contains(TK_restrict);
boolean isVolatile = contains(TK_volatile);
if(isConst || isRestrict || isVolatile)
return new C99QualifierType(basicType, isConst, isVolatile, isRestrict);
else
return basicType;
}
public void modifyBinding(C99Variable var) {
if(!var.isAuto())
var.setAuto(contains(TK_auto));
if(!var.isExtern())
var.setExtern(contains(TK_extern));
if(!var.isRegister())
var.setRegister(contains(TK_register));
if(!var.isStatic())
var.setStatic(contains(TK_static));
}
public void modifyBinding(C99Function function) {
if(!function.isAuto())
function.setAuto(contains(TK_auto));
if(!function.isExtern())
function.setExtern(contains(TK_extern));
if(!function.isInline())
function.setInline(contains(TK_inline));
if(!function.isRegister())
function.setRegister(contains(TK_register));
if(!function.isStatic())
function.setStatic(contains(TK_static));
}
}

View file

@ -0,0 +1,142 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import java.util.LinkedList;
import java.util.List;
import lpg.lpgjavaruntime.IToken;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99PointerType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
/**
* Represents a frame on the declaration stack used by the resolver actions.
*
* TODO: document this class better
*
* @author Mike Kucera
*/
@SuppressWarnings("restriction")
public class DeclaratorFrame {
private DeclSpec declSpec;
//IBinding declarator;
private IToken declaratorName;
private boolean isDeclaratorBracketed;
private boolean isFunctionDeclarator = false;
// temporary storage for pointer modifiers
private LinkedList<LinkedList<C99PointerType>> pointerModifiers = new LinkedList<LinkedList<C99PointerType>>();
// stores pointer and array modifiers that are applied to the declarator
private LinkedList<ITypeContainer> typeModifiers = new LinkedList<ITypeContainer>();
private LinkedList<IBinding> nestedDeclarations = new LinkedList<IBinding>();
public DeclaratorFrame() {
}
public DeclaratorFrame(DeclSpec declSpec) {
this.declSpec = declSpec;
}
public DeclSpec getDeclSpec() {
if(declSpec == null)
declSpec = new DeclSpec();
return declSpec;
}
public IType getDeclaratorType() {
// the declSpec may be null, so use getDeclSpec()
IType baseType = getDeclSpec().getType();
if(typeModifiers.isEmpty())
return baseType;
IType type = typeModifiers.get(0);
// link the types together
for(int i = 1; i < typeModifiers.size(); i++) {
ITypeContainer t1 = typeModifiers.get(i-1);
ITypeContainer t2 = typeModifiers.get(i);
t1.setType(t2);
}
ITypeContainer last = typeModifiers.get(typeModifiers.size()-1);
last.setType(baseType);
return type;
}
public IToken getDeclaratorName() {
return declaratorName;
}
public void setDeclaratorName(IToken declaratorName) {
this.declaratorName = declaratorName;
}
public boolean isDeclaratorBracketed() {
return isDeclaratorBracketed;
}
public void setDeclaratorBracketed(boolean isDeclaratorBracketed) {
this.isDeclaratorBracketed = isDeclaratorBracketed;
}
public boolean isFunctionDeclarator() {
return isFunctionDeclarator;
}
public void setFunctionDeclarator(boolean isFunctionDeclarator) {
this.isFunctionDeclarator = isFunctionDeclarator;
}
public List<IBinding> getNestedDeclarations() {
return nestedDeclarations;
}
public void addNestedDeclaration(IBinding binding) {
nestedDeclarations.add(binding);
}
public void removeLastNestedDeclaration() {
nestedDeclarations.removeLast();
}
public void addTypeModifier(ITypeContainer x) {
typeModifiers.add(x);
}
public void removeLastTypeModifier() {
typeModifiers.removeLast();
}
public void addPointerModifier(C99PointerType x) {
pointerModifiers.getLast().add(x);
}
public void removeLastPointerModifier() {
pointerModifiers.getLast().removeLast();
}
public void openPointerModifierScope() {
pointerModifiers.add(new LinkedList<C99PointerType>());
}
public void openPointerModifierScope(LinkedList<C99PointerType> scope) {
pointerModifiers.add(scope);
}
public LinkedList<C99PointerType> closePointerModifierScope() {
return pointerModifiers.removeLast();
}
}

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* 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
*******************************************************************************/
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;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
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.action.IASTNodeFactory;
/**
* Factory for AST nodes that are just used by C and not by C++.
*
* @author Mike Kucera
*/
public interface IC99ASTNodeFactory extends IASTNodeFactory {
public IASTFieldReference newFieldReference(IASTName name, IASTExpression owner, boolean isPointerDereference);
public ICASTTypeIdInitializerExpression newCTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializerList list);
public ICASTArrayModifier newModifiedArrayModifier();
public ICASTKnRFunctionDeclarator newCKnRFunctionDeclarator();
public ICASTPointer newCPointer();
public IASTParameterDeclaration newParameterDeclaration(IASTDeclSpecifier declSpec, IASTDeclarator declarator);
public ICASTDesignatedInitializer newCDesignatedInitializer(IASTInitializer rhs);
public ICASTArrayDesignator newCArrayDesignator(IASTExpression exp);
public ICASTFieldDesignator newCFieldDesignator(IASTName name);
public ICASTSimpleDeclSpecifier newCSimpleDeclSpecifier();
public ICASTTypedefNameSpecifier newCTypedefNameSpecifier();
public IASTFieldDeclarator newFieldDeclarator(IASTName name, IASTExpression bitFieldSize);
public ICASTCompositeTypeSpecifier newCCompositeTypeSpecifier(int key, IASTName name);
}

View file

@ -0,0 +1,208 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Binding;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Scope;
/**
* Used to compute binding resolution during the parse.
*
* Imperative style symbol table with destructive update.
*
* Consists of two data structures, a hash table for fast lookup
* of bindings given their names, and a stack used to keep track
* of scopes.
*
* @deprecated Use FunctionalSymbolTable now that undo actions are needed
*
* @author Mike Kucera
*/
@Deprecated public class ImperativeSymbolTable {
private static final int TABLE_SIZE = 256;
private Bucket[] table = new Bucket[TABLE_SIZE];
private LinkedList<SymbolScope> scopeStack = new LinkedList<SymbolScope>();
/**
* Represents a scope in the C language.
*/
private static class SymbolScope {
/**
* List of buckets that have been modified in the current scope.
* When the scope is closed these buckets are popped, returning the
* symbol table to the state it was in before the scope was opened.
*/
List<Integer> modifiedBuckets = new ArrayList<Integer>();
/**
* List of inner scopes that have been closed.
*/
List<IC99Scope> innerScopes = new ArrayList<IC99Scope>();
}
/**
* A bucket object used to hold elements in the hash table.
*/
private static class Bucket {
String key;
CNamespace namespace;
IC99Binding binding;
Bucket next;
Bucket(Bucket next, CNamespace namespace, String key, IC99Binding binding) {
this.key = key;
this.namespace = namespace;
this.binding = binding;
this.next = next;
}
}
public ImperativeSymbolTable() {
openScope(); // open the global scope
// TODO populate the global scope with built-ins
}
/**
* Hashes a key into an index in the hash table.
*/
private int index(String key) {
return Math.abs(key.hashCode() % TABLE_SIZE);
}
/**
* Adds a binding to the symbol table in the current scope.
*
* @param mask A bit mask used to identify the namespace of the identifier.
*/
public void put(CNamespace namespace, String ident, IC99Binding b) {
int index = index(ident);
table[index] = new Bucket(table[index], namespace, ident, b);
SymbolScope scope = scopeStack.getLast();
scope.modifiedBuckets.add(index);
}
/**
* Special version of put that adds the binding to the scope that contains
* the current scope.
*
* This is here because the scope for a function body is opened before
* the function binding is created.
*/
public void putInOuterScope(CNamespace namespace, String ident, IC99Binding b) {
LinkedList<Bucket> poppedBindings = new LinkedList<Bucket>();
SymbolScope scope = scopeStack.removeLast();
for(int index : scope.modifiedBuckets) {
Bucket bucket = table[index];
poppedBindings.add(bucket);
table[index] = bucket.next;
}
put(namespace, ident, b);
for(int index : scope.modifiedBuckets) {
Bucket bucket = poppedBindings.removeFirst();
bucket.next = table[index];
table[index] = bucket;
}
scopeStack.add(scope);
}
/**
* Returns the binding associated with the given identifier, or
* null if there is none.
*
* @param mask A bit mask used to identify the namespace of the identifier.
*/
public IC99Binding get(CNamespace namespace, String ident) {
Bucket b = table[index(ident)];
while(b != null) {
if(namespace == b.namespace && ident.equals(b.key))
return b.binding;
b = b.next;
}
return null;
}
List<IC99Scope> getInnerScopes() {
return scopeStack.getLast().innerScopes;
}
/**
* Opens a new inner scope for identifiers.
*
* If an identifier is added that already exists in an outer scope
* then it will be shadowed.
*/
public void openScope() {
scopeStack.add(new SymbolScope());
}
/**
* Remove all the symbols defined in the scope that is being closed.
*
* @param scope An IScope object that will be used to represent this scope.
* @throws SymbolTableException If the global scope has already been closed or if bindingScope is null.
*/
public void closeScope(IC99Scope bindingScope) {
SymbolScope poppedScope = scopeStack.removeLast(); // pop the scopeStack
for(IC99Scope innerScope : poppedScope.innerScopes) {
innerScope.setParent(bindingScope);
}
if(!scopeStack.isEmpty()) { // would be empty if the global scope was popped
SymbolScope outerScope = scopeStack.getLast();
outerScope.innerScopes.add(bindingScope);
}
// pop each bucket that was modified in the scope
for(int index : poppedScope.modifiedBuckets) {
Bucket bucket = table[index];
bucket.binding.setScope(bindingScope);
table[index] = bucket.next;
}
}
public String toString() {
StringBuilder buff = new StringBuilder("[");
for(Bucket b : table) {
while(b != null) {
buff.append("<").append(b.key).append(": ").append(b.binding).append(">, ");
b = b.next;
}
}
return buff.append("]").toString();
}
}

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.c99;
import org.eclipse.cdt.core.dom.lrparser.action.FunctionalMap;
/**
* A facade for a FunctionalMap that is used just to track typedef
* declarations.
*
* This class acts like a set. No information needs to be associated
* with a typedef declaration, all we need to know is if the identifier
* has been declared as a typedef.
*
* @author Mike Kucera
*/
public class TypedefSymbolTable {
/**
* Start with EMPTY_TABLE and build up a symbol table using add().
*/
public static final TypedefSymbolTable EMPTY_TABLE = new TypedefSymbolTable();
// the map we are providing a facade for
private final FunctionalMap<String,Object> map;
/**
* Constructors are private, start with EMPTY_TABLE
* and build it up using insert().
*/
private TypedefSymbolTable() {
map = FunctionalMap.emptyMap();
}
private TypedefSymbolTable(FunctionalMap<String,Object> newRoot) {
map = newRoot;
}
public TypedefSymbolTable add(String typedefIdent) {
return new TypedefSymbolTable(map.insert(typedefIdent, null));
}
public boolean contains(String typedef) {
return map.containsKey(typedef);
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.size() == 0;
}
@Override public String toString() {
return map.toString();
}
}

View file

@ -0,0 +1,498 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.cpp;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
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;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
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.action.ASTCompletionNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTASMDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayModifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArraySubscriptExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBaseSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBreakStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCaseStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCastExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCatchHandler;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTConditionalExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTConstructorInitializer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTContinueStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTConversionName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarationStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDefaultStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeleteExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDoStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTEnumerationSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTEnumerator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTForStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTGotoStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIfStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTInitializerList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLabelStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLinkageSpecification;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceAlias;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNewExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNullStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTOperatorName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTPointer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTPointerToMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTProblem;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTProblemDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTProblemExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTProblemStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReferenceOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSwitchStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTryBlockStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypenameExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUsingDirective;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTVisibilityLabel;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTWhileStatement;
@SuppressWarnings("restriction") // all AST node constructors are internal
/**
* Abstract factory implementation that creates C++ AST nodes.
*
* @author Mike Kucera
*/
public class CPPASTNodeFactory implements ICPPASTNodeFactory {
public static final CPPASTNodeFactory DEFAULT_INSTANCE = new CPPASTNodeFactory();
public ASTCompletionNode newCompletionNode(String prefix, IASTTranslationUnit tu) {
return new ASTCompletionNode((prefix == null || prefix.length() == 0) ? null : prefix, tu);
}
public IASTName newName(char[] name) {
return new CPPASTName(name);
}
public IASTName newName() {
return new CPPASTName();
}
public ICPPASTOperatorName newCPPOperatorName(char[] name) {
return new CPPASTOperatorName(name);
}
public IASTProblem newProblem(int id, char[] arg, boolean warn, boolean error) {
return new CPPASTProblem(id, arg, warn, error);
}
public IASTProblemDeclaration newProblemDeclaration() {
return new CPPASTProblemDeclaration();
}
public IASTProblemExpression newProblemExpression() {
return new CPPASTProblemExpression();
}
public IASTProblemStatement newProblemStatement() {
return new CPPASTProblemStatement();
}
public IASTLiteralExpression newLiteralExpression(int kind, String rep) {
return new CPPASTLiteralExpression(kind, rep);
}
public IASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand) {
return new CPPASTUnaryExpression(operator, operand);
}
public IASTIdExpression newIdExpression(IASTName name) {
return new CPPASTIdExpression(name);
}
public IASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
return new CPPASTArraySubscriptExpression(arrayExpr, subscript);
}
public IASTExpressionList newExpressionList() {
return new CPPASTExpressionList();
}
public IASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
return new CPPASTFunctionCallExpression(idExpr, argList);
}
public IASTCastExpression newCastExpression(int operator, IASTTypeId typeId, IASTExpression operand) {
return new CPPASTCastExpression(operator, typeId, operand);
}
public ICPPASTNewExpression newCPPNewExpression(IASTExpression placement, IASTExpression initializer, IASTTypeId typeId) {
return new CPPASTNewExpression(placement, initializer, typeId);
}
public IASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2) {
return new CPPASTBinaryExpression(op, expr1, expr2);
}
public IASTConditionalExpression newConditionalExpession(IASTExpression expr1, IASTExpression expr2, IASTExpression expr3) {
return new CPPASTConditionalExpression(expr1, expr2, expr3);
}
public IASTFieldReference newFieldReference(IASTName name, IASTExpression owner, boolean isPointerDereference, boolean isTemplate) {
return new CPPASTFieldReference(name, owner, isPointerDereference, isTemplate);
}
public ICPPASTTemplateId newCPPTemplateId(IASTName templateName) {
return new CPPASTTemplateId(templateName);
}
public ICPPASTConversionName newCPPConversionName(char[] name, IASTTypeId typeId) {
return new CPPASTConversionName(name, typeId);
}
public ICPPASTQualifiedName newCPPQualifiedName() {
return new CPPASTQualifiedName();
}
public IASTCaseStatement newCaseStatement(IASTExpression expr) {
return new CPPASTCaseStatement(expr);
}
public IASTDefaultStatement newDefaultStatement() {
return new CPPASTDefaultStatement();
}
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement) {
return new CPPASTLabelStatement(name, nestedStatement);
}
public IASTExpressionStatement newExpressionStatement(IASTExpression expression) {
return new CPPASTExpressionStatement(expression);
}
public IASTNullStatement newNullStatement() {
return new CPPASTNullStatement();
}
public IASTCompoundStatement newCompoundStatement() {
return new CPPASTCompoundStatement();
}
public IASTIfStatement newIfStatement(IASTExpression condition, IASTStatement then, IASTStatement elseClause) {
return new CPPASTIfStatement(condition, then, elseClause);
}
public IASTSwitchStatement newSwitchStatment(IASTExpression controller, IASTStatement body) {
return new CPPASTSwitchStatement(controller, body);
}
public IASTIfStatement newIfStatement(IASTDeclaration condition, IASTStatement then, IASTStatement elseClause) {
return new CPPASTIfStatement(condition, then, elseClause);
}
public IASTSwitchStatement newSwitchStatment(IASTDeclaration controller, IASTStatement body) {
return new CPPASTSwitchStatement(controller, body);
}
public IASTWhileStatement newWhileStatement(IASTDeclaration condition, IASTStatement body) {
return new CPPASTWhileStatement(condition, body);
}
public IASTDoStatement newDoStatement(IASTStatement body, IASTExpression condition) {
return new CPPASTDoStatement(body, condition);
}
public IASTWhileStatement newWhileStatement(IASTExpression condition, IASTStatement body) {
return new CPPASTWhileStatement(condition, body);
}
public IASTBreakStatement newBreakStatement() {
return new CPPASTBreakStatement();
}
public IASTContinueStatement newContinueStatement() {
return new CPPASTContinueStatement();
}
public IASTGotoStatement newGotoStatement(IASTName name) {
return new CPPASTGotoStatement(name);
}
public IASTReturnStatement newReturnStatement(IASTExpression retValue) {
return new CPPASTReturnStatement(retValue);
}
public IASTForStatement newForStatement(IASTStatement init, IASTExpression condition,
IASTExpression iterationExpr, IASTStatement body) {
return new CPPASTForStatement(init, condition, iterationExpr, body);
}
public IASTDeclarationStatement newDeclarationStatement(IASTDeclaration declaration) {
return new CPPASTDeclarationStatement(declaration);
}
public IASTTypeIdExpression newTypeIdExpression(int operator, IASTTypeId typeId) {
return new CPPASTTypeIdExpression(operator, typeId);
}
public IASTDeclarator newDeclarator(IASTName name) {
return new CPPASTDeclarator(name);
}
public IASTTypeId newTypeId(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) {
return new CPPASTTypeId(declSpecifier, declarator);
}
public ICPPASTDeleteExpression newDeleteExpression(IASTExpression operand) {
return new CPPASTDeleteExpression(operand);
}
public IASTSimpleDeclaration newSimpleDeclaration(IASTDeclSpecifier declSpecifier) {
return new CPPASTSimpleDeclaration(declSpecifier);
}
public IASTInitializerExpression newInitializerExpression(IASTExpression expression) {
return new CPPASTInitializerExpression(expression);
}
public IASTFunctionDefinition newFunctionDefinition(IASTDeclSpecifier declSpecifier, IASTFunctionDeclarator declarator,
IASTStatement bodyStatement) {
return new CPPASTFunctionDefinition(declSpecifier, declarator, bodyStatement);
}
public IASTTranslationUnit newTranslationUnit() {
return new CPPASTTranslationUnit();
}
public ICPPASTSimpleDeclSpecifier newCPPSimpleDeclSpecifier() {
return new CPPASTSimpleDeclSpecifier();
}
public IASTStandardFunctionDeclarator newFunctionDeclarator(IASTName name) {
return new CPPASTFunctionDeclarator(name);
}
public ICPPASTSimpleTypeConstructorExpression newCPPSimpleTypeConstructorExpression(
int type, IASTExpression expression) {
return new CPPASTSimpleTypeConstructorExpression(type, expression);
}
public ICPPASTTypenameExpression newCPPTypenameExpression(
ICPPASTQualifiedName qualifiedName, IASTExpression expr, boolean isTemplate) {
return new CPPASTTypenameExpression(qualifiedName, expr, isTemplate);
}
public IASTASMDeclaration newASMDeclaration(String assembly) {
return new CPPASTASMDeclaration(assembly);
}
public ICPPASTNamespaceAlias newNamespaceAlias(IASTName alias, IASTName qualifiedName) {
return new CPPASTNamespaceAlias(alias, qualifiedName);
}
public ICPPASTUsingDeclaration newUsingDeclaration(IASTName name) {
return new CPPASTUsingDeclaration(name);
}
public ICPPASTUsingDirective newUsingDirective(IASTName name) {
return new CPPASTUsingDirective(name);
}
public ICPPASTLinkageSpecification newLinkageSpecification(String name) {
return new CPPASTLinkageSpecification(name);
}
public ICPPASTNamespaceDefinition newNamespaceDefinition(IASTName name) {
return new CPPASTNamespaceDefinition(name);
}
public ICPPASTTemplateDeclaration newTemplateDeclaration(IASTDeclaration declaration) {
return new CPPASTTemplateDeclaration(declaration);
}
public ICPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiation(IASTDeclaration declaration) {
return new CPPASTExplicitTemplateInstantiation(declaration);
}
public ICPPASTTemplateSpecialization newTemplateSpecialization(IASTDeclaration declaration) {
return new CPPASTTemplateSpecialization(declaration);
}
public ICPPASTTryBlockStatement newTryBlockStatement(IASTStatement body) {
return new CPPASTTryBlockStatement(body);
}
public ICPPASTCatchHandler newCatchHandler(IASTDeclaration decl, IASTStatement body) {
return new CPPASTCatchHandler(decl, body);
}
public IASTEnumerationSpecifier newEnumerationSpecifier(IASTName name) {
return new CPPASTEnumerationSpecifier(name);
}
public IASTEnumerator newEnumerator(IASTName name, IASTExpression value) {
return new CPPASTEnumerator(name, value);
}
public ICPPASTVisiblityLabel newVisibilityLabel(int visibility) {
return new CPPASTVisibilityLabel(visibility);
}
public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual) {
return new CPPASTBaseSpecifier(name, visibility, isVirtual);
}
public ICPPASTCompositeTypeSpecifier newCPPCompositeTypeSpecifier(int key, IASTName name) {
return new CPPASTCompositeTypeSpecifier(key, name);
}
public ICPPASTNamedTypeSpecifier newCPPNamedTypeSpecifier(IASTName name, boolean typename) {
return new CPPASTNamedTypeSpecifier(name, typename);
}
public IASTElaboratedTypeSpecifier newElaboratedTypeSpecifier(int kind, IASTName name) {
return new CPPASTElaboratedTypeSpecifier(kind, name);
}
public IASTPointer newCPPPointer() {
return new CPPASTPointer();
}
public ICPPASTReferenceOperator newReferenceOperator() {
return new CPPASTReferenceOperator();
}
public ICPPASTPointerToMember newPointerToMember(IASTName name) {
return new CPPASTPointerToMember(name);
}
public IASTInitializerList newInitializerList() {
return new CPPASTInitializerList();
}
public ICPPASTConstructorInitializer newConstructorInitializer(IASTExpression exp) {
return new CPPASTConstructorInitializer(exp);
}
public IASTArrayModifier newArrayModifier(IASTExpression expr) {
return new CPPASTArrayModifier(expr);
}
public IASTArrayDeclarator newArrayDeclarator(IASTName name) {
return new CPPASTArrayDeclarator(name);
}
public ICPPASTFunctionDeclarator newCPPFunctionDeclarator(IASTName name) {
return new CPPASTFunctionDeclarator(name);
}
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action.cpp;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
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.action.IASTNodeFactory;
/**
* TODO remove CPP from method names.
*
* @author Mike Kucera
*/
public interface ICPPASTNodeFactory extends IASTNodeFactory {
public ICPPASTOperatorName newCPPOperatorName(char[] name);
public ICPPASTNewExpression newCPPNewExpression(IASTExpression placement, IASTExpression initializer, IASTTypeId typeId);
public IASTFieldReference newFieldReference(IASTName name, IASTExpression owner, boolean isPointerDereference, boolean isTemplate);
public ICPPASTTemplateId newCPPTemplateId(IASTName templateName);
public ICPPASTConversionName newCPPConversionName(char[] name, IASTTypeId typeId);
public ICPPASTQualifiedName newCPPQualifiedName();
public IASTSwitchStatement newSwitchStatment(IASTDeclaration controller, IASTStatement body);
public IASTIfStatement newIfStatement(IASTDeclaration condition, IASTStatement then, IASTStatement elseClause);
public IASTWhileStatement newWhileStatement(IASTDeclaration condition, IASTStatement body);
public ICPPASTDeleteExpression newDeleteExpression(IASTExpression operand);
public ICPPASTSimpleDeclSpecifier newCPPSimpleDeclSpecifier();
public ICPPASTSimpleTypeConstructorExpression newCPPSimpleTypeConstructorExpression(int type, IASTExpression expression);
public ICPPASTTypenameExpression newCPPTypenameExpression(ICPPASTQualifiedName qualifiedName, IASTExpression expr, boolean isTemplate);
public ICPPASTNamespaceAlias newNamespaceAlias(IASTName alias, IASTName qualifiedName);
public ICPPASTUsingDeclaration newUsingDeclaration(IASTName name);
public ICPPASTUsingDirective newUsingDirective(IASTName name);
public ICPPASTLinkageSpecification newLinkageSpecification(String name);
public ICPPASTNamespaceDefinition newNamespaceDefinition(IASTName name);
public ICPPASTTemplateDeclaration newTemplateDeclaration(IASTDeclaration declaration);
public ICPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiation(IASTDeclaration declaration);
public ICPPASTTemplateSpecialization newTemplateSpecialization(IASTDeclaration declaration);
public ICPPASTTryBlockStatement newTryBlockStatement(IASTStatement body);
public ICPPASTCatchHandler newCatchHandler(IASTDeclaration decl, IASTStatement body);
public ICPPASTVisiblityLabel newVisibilityLabel(int visibility);
public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual);
public ICPPASTCompositeTypeSpecifier newCPPCompositeTypeSpecifier(int key, IASTName name);
public ICPPASTNamedTypeSpecifier newCPPNamedTypeSpecifier(IASTName name, boolean typename);
public IASTPointer newCPPPointer();
public ICPPASTReferenceOperator newReferenceOperator();
public ICPPASTPointerToMember newPointerToMember(IASTName name);
public ICPPASTConstructorInitializer newConstructorInitializer(IASTExpression exp);
public ICPPASTFunctionDeclarator newCPPFunctionDeclarator(IASTName name);
}

View file

@ -0,0 +1,97 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.c99;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.IParser;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99ASTNodeFactory;
import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parser;
/**
* ILanguage implementation for the C99 parser.
*
* @author Mike Kucera
*/
public class C99Language extends BaseExtensibleLanguage {
public static final String PLUGIN_ID = "org.eclipse.cdt.core.lrparser"; //$NON-NLS-1$
public static final String ID = PLUGIN_ID + ".c99"; //$NON-NLS-1$
private static final ITokenMap TOKEN_MAP = DOMToC99TokenMap.DEFAULT_MAP;
private static GCCLanguage GCC_LANGUAGE = GCCLanguage.getDefault();
private static C99Language DEFAULT = new C99Language();
public static C99Language getDefault() {
return DEFAULT;
}
@Override
protected IParser getParser() {
return new C99Parser();
}
@Override
protected ITokenMap getTokenMap() {
return TOKEN_MAP;
}
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
return null;
}
public String getId() {
return ID;
}
public int getLinkageID() {
return ILinkage.C_LINKAGE_ID;
}
public IASTName[] getSelectedNames(IASTTranslationUnit ast, int start, int length) {
return GCC_LANGUAGE.getSelectedNames(ast, start, length);
}
public String[] getBuiltinTypes() {
return GCC_LANGUAGE.getBuiltinTypes();
}
public String[] getKeywords() {
return GCC_LANGUAGE.getKeywords();
}
public String[] getPreprocessorKeywords() {
return GCC_LANGUAGE.getPreprocessorKeywords();
}
@Override
protected IASTTranslationUnit createASTTranslationUnit() {
return C99ASTNodeFactory.DEFAULT_INSTANCE.newTranslationUnit();
}
@Override
protected ParserLanguage getParserLanguageForPreprocessor() {
return ParserLanguage.C;
}
}

View file

@ -0,0 +1,329 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.c99;
import static org.eclipse.cdt.core.parser.IToken.tAMPER;
import static org.eclipse.cdt.core.parser.IToken.tAMPERASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tAND;
import static org.eclipse.cdt.core.parser.IToken.tARROW;
import static org.eclipse.cdt.core.parser.IToken.tASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tBITCOMPLEMENT;
import static org.eclipse.cdt.core.parser.IToken.tBITOR;
import static org.eclipse.cdt.core.parser.IToken.tBITORASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tCHAR;
import static org.eclipse.cdt.core.parser.IToken.tCOLON;
import static org.eclipse.cdt.core.parser.IToken.tCOMMA;
import static org.eclipse.cdt.core.parser.IToken.tCOMPLETION;
import static org.eclipse.cdt.core.parser.IToken.tDECR;
import static org.eclipse.cdt.core.parser.IToken.tDIV;
import static org.eclipse.cdt.core.parser.IToken.tDIVASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tDOT;
import static org.eclipse.cdt.core.parser.IToken.tELLIPSIS;
import static org.eclipse.cdt.core.parser.IToken.tEND_OF_INPUT;
import static org.eclipse.cdt.core.parser.IToken.tEOC;
import static org.eclipse.cdt.core.parser.IToken.tEQUAL;
import static org.eclipse.cdt.core.parser.IToken.tFLOATINGPT;
import static org.eclipse.cdt.core.parser.IToken.tGT;
import static org.eclipse.cdt.core.parser.IToken.tGTEQUAL;
import static org.eclipse.cdt.core.parser.IToken.tIDENTIFIER;
import static org.eclipse.cdt.core.parser.IToken.tINCR;
import static org.eclipse.cdt.core.parser.IToken.tINTEGER;
import static org.eclipse.cdt.core.parser.IToken.tLBRACE;
import static org.eclipse.cdt.core.parser.IToken.tLBRACKET;
import static org.eclipse.cdt.core.parser.IToken.tLCHAR;
import static org.eclipse.cdt.core.parser.IToken.tLPAREN;
import static org.eclipse.cdt.core.parser.IToken.tLSTRING;
import static org.eclipse.cdt.core.parser.IToken.tLT;
import static org.eclipse.cdt.core.parser.IToken.tLTEQUAL;
import static org.eclipse.cdt.core.parser.IToken.tMINUS;
import static org.eclipse.cdt.core.parser.IToken.tMINUSASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tMOD;
import static org.eclipse.cdt.core.parser.IToken.tMODASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tNOT;
import static org.eclipse.cdt.core.parser.IToken.tNOTEQUAL;
import static org.eclipse.cdt.core.parser.IToken.tOR;
import static org.eclipse.cdt.core.parser.IToken.tPLUS;
import static org.eclipse.cdt.core.parser.IToken.tPLUSASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tQUESTION;
import static org.eclipse.cdt.core.parser.IToken.tRBRACE;
import static org.eclipse.cdt.core.parser.IToken.tRBRACKET;
import static org.eclipse.cdt.core.parser.IToken.tRPAREN;
import static org.eclipse.cdt.core.parser.IToken.tSEMI;
import static org.eclipse.cdt.core.parser.IToken.tSHIFTL;
import static org.eclipse.cdt.core.parser.IToken.tSHIFTLASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tSHIFTR;
import static org.eclipse.cdt.core.parser.IToken.tSHIFTRASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tSTAR;
import static org.eclipse.cdt.core.parser.IToken.tSTARASSIGN;
import static org.eclipse.cdt.core.parser.IToken.tSTRING;
import static org.eclipse.cdt.core.parser.IToken.tUNKNOWN_CHAR;
import static org.eclipse.cdt.core.parser.IToken.tXOR;
import static org.eclipse.cdt.core.parser.IToken.tXORASSIGN;
import static org.eclipse.cdt.core.parser.IToken.t__Bool;
import static org.eclipse.cdt.core.parser.IToken.t__Complex;
import static org.eclipse.cdt.core.parser.IToken.t__Imaginary;
import static org.eclipse.cdt.core.parser.IToken.t_auto;
import static org.eclipse.cdt.core.parser.IToken.t_break;
import static org.eclipse.cdt.core.parser.IToken.t_case;
import static org.eclipse.cdt.core.parser.IToken.t_char;
import static org.eclipse.cdt.core.parser.IToken.t_const;
import static org.eclipse.cdt.core.parser.IToken.t_continue;
import static org.eclipse.cdt.core.parser.IToken.t_default;
import static org.eclipse.cdt.core.parser.IToken.t_do;
import static org.eclipse.cdt.core.parser.IToken.t_double;
import static org.eclipse.cdt.core.parser.IToken.t_else;
import static org.eclipse.cdt.core.parser.IToken.t_enum;
import static org.eclipse.cdt.core.parser.IToken.t_extern;
import static org.eclipse.cdt.core.parser.IToken.t_float;
import static org.eclipse.cdt.core.parser.IToken.t_for;
import static org.eclipse.cdt.core.parser.IToken.t_goto;
import static org.eclipse.cdt.core.parser.IToken.t_if;
import static org.eclipse.cdt.core.parser.IToken.t_inline;
import static org.eclipse.cdt.core.parser.IToken.t_int;
import static org.eclipse.cdt.core.parser.IToken.t_long;
import static org.eclipse.cdt.core.parser.IToken.t_register;
import static org.eclipse.cdt.core.parser.IToken.t_restrict;
import static org.eclipse.cdt.core.parser.IToken.t_return;
import static org.eclipse.cdt.core.parser.IToken.t_short;
import static org.eclipse.cdt.core.parser.IToken.t_signed;
import static org.eclipse.cdt.core.parser.IToken.t_sizeof;
import static org.eclipse.cdt.core.parser.IToken.t_static;
import static org.eclipse.cdt.core.parser.IToken.t_struct;
import static org.eclipse.cdt.core.parser.IToken.t_switch;
import static org.eclipse.cdt.core.parser.IToken.t_typedef;
import static org.eclipse.cdt.core.parser.IToken.t_union;
import static org.eclipse.cdt.core.parser.IToken.t_unsigned;
import static org.eclipse.cdt.core.parser.IToken.t_void;
import static org.eclipse.cdt.core.parser.IToken.t_volatile;
import static org.eclipse.cdt.core.parser.IToken.t_while;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_And;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_AndAnd;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_AndAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Arrow;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Assign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Bang;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Caret;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_CaretAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Colon;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Comma;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Completion;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Dot;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_DotDotDot;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_EOF_TOKEN;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_EQ;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_EndOfCompletion;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_GE;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_GT;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Invalid;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LE;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LT;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LeftBrace;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LeftBracket;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LeftParen;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LeftShift;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_LeftShiftAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Minus;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_MinusAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_MinusMinus;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_NE;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Or;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_OrAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_OrOr;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Percent;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_PercentAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Plus;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_PlusAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_PlusPlus;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Question;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_RightBrace;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_RightBracket;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_RightParen;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_RightShift;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_RightShiftAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_SemiColon;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Slash;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_SlashAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Star;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_StarAssign;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_Tilde;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK__Bool;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK__Complex;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK__Imaginary;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_auto;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_break;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_case;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_char;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_charconst;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_const;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_continue;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_default;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_do;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_double;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_else;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_enum;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_extern;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_float;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_floating;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_for;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_goto;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_identifier;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_if;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_inline;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_int;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_integer;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_long;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_register;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_restrict;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_return;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_short;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_signed;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_sizeof;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_static;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_stringlit;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_struct;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_switch;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_typedef;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_union;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_unsigned;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_void;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_volatile;
import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.TK_while;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
/**
* Maps tokens types returned by CPreprocessor to token types
* expected by the C99 parser.
*
*
* TODO: Make token maps composable.
*
* The idea would be to combine a DOM->C99 map with a C99->UPC map
* to get a DOM->UPC map.
*
* @author Mike Kucera
*
*/
public final class DOMToC99TokenMap implements ITokenMap {
public static final DOMToC99TokenMap DEFAULT_MAP = new DOMToC99TokenMap();
private DOMToC99TokenMap() {
// just a private constructor
}
public int mapKind(int kind) {
switch(kind) {
case tIDENTIFIER : return TK_identifier;
case tINTEGER : return TK_integer;
case tCOLON : return TK_Colon;
case tSEMI : return TK_SemiColon;
case tCOMMA : return TK_Comma;
case tQUESTION : return TK_Question;
case tLPAREN : return TK_LeftParen;
case tRPAREN : return TK_RightParen;
case tLBRACKET : return TK_LeftBracket;
case tRBRACKET : return TK_RightBracket;
case tLBRACE : return TK_LeftBrace;
case tRBRACE : return TK_RightBrace;
case tPLUSASSIGN : return TK_PlusAssign;
case tINCR : return TK_PlusPlus;
case tPLUS : return TK_Plus;
case tMINUSASSIGN : return TK_MinusAssign;
case tDECR : return TK_MinusMinus;
case tARROW : return TK_Arrow;
case tMINUS : return TK_Minus;
case tSTARASSIGN : return TK_StarAssign;
case tSTAR : return TK_Star;
case tMODASSIGN : return TK_PercentAssign;
case tMOD : return TK_Percent;
case tXORASSIGN : return TK_CaretAssign;
case tXOR : return TK_Caret;
case tAMPERASSIGN : return TK_AndAssign;
case tAND : return TK_AndAnd;
case tAMPER : return TK_And;
case tBITORASSIGN : return TK_OrAssign;
case tOR : return TK_OrOr;
case tBITOR : return TK_Or;
case tBITCOMPLEMENT: return TK_Tilde;
case tNOTEQUAL : return TK_NE;
case tNOT : return TK_Bang;
case tEQUAL : return TK_EQ;
case tASSIGN : return TK_Assign;
case tUNKNOWN_CHAR : return TK_Invalid;
case tSHIFTL : return TK_LeftShift;
case tLTEQUAL : return TK_LE;
case tLT : return TK_LT;
case tSHIFTRASSIGN : return TK_RightShiftAssign;
case tSHIFTR : return TK_RightShift;
case tGTEQUAL : return TK_GE;
case tGT : return TK_GT;
case tSHIFTLASSIGN : return TK_LeftShiftAssign;
case tELLIPSIS : return TK_DotDotDot;
case tDOT : return TK_Dot;
case tDIVASSIGN : return TK_SlashAssign;
case tDIV : return TK_Slash;
case t_auto : return TK_auto;
case t_break : return TK_break;
case t_case : return TK_case;
case t_char : return TK_char;
case t_const : return TK_const;
case t_continue : return TK_continue;
case t_default : return TK_default;
case t_do : return TK_do;
case t_double : return TK_double;
case t_else : return TK_else;
case t_enum : return TK_enum;
case t_extern : return TK_extern;
case t_float : return TK_float;
case t_for : return TK_for;
case t_goto : return TK_goto;
case t_if : return TK_if;
case t_inline : return TK_inline;
case t_int : return TK_int;
case t_long : return TK_long;
case t_register : return TK_register;
case t_return : return TK_return;
case t_short : return TK_short;
case t_sizeof : return TK_sizeof;
case t_static : return TK_static;
case t_signed : return TK_signed;
case t_struct : return TK_struct;
case t_switch : return TK_switch;
case t_typedef : return TK_typedef;
case t_union : return TK_union;
case t_unsigned : return TK_unsigned;
case t_void : return TK_void;
case t_volatile : return TK_volatile;
case t_while : return TK_while;
case tFLOATINGPT : return TK_floating;
case tSTRING : return TK_stringlit;
case tLSTRING : return TK_stringlit;
case tCHAR : return TK_charconst;
case tLCHAR : return TK_charconst;
case t__Bool : return TK__Bool;
case t__Complex : return TK__Complex;
case t__Imaginary : return TK__Imaginary;
case t_restrict : return TK_restrict;
case tCOMPLETION : return TK_Completion;
case tEOC : return TK_EndOfCompletion;
case tEND_OF_INPUT : return TK_EOF_TOKEN;
default:
assert false : "token not recognized by the C99 parser: " + kind; //$NON-NLS-1$
return TK_Invalid;
}
}
}

View file

@ -0,0 +1,173 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.cpp;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import static org.eclipse.cdt.core.parser.IToken.*;
import static org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPParsersym.*;
/**
* Maps tokens types returned by CPreprocessor to token types
* expected by the C++ parser.
*
* TODO: Make token maps composable.
*
* The idea would be to combine a DOM->C99 map with a C99->UPC map
* to get a DOM->UPC map.
*
* @author Mike Kucera
*
*/
public class DOMToISOCPPTokenMap implements ITokenMap {
public static final DOMToISOCPPTokenMap DEFAULT_MAP = new DOMToISOCPPTokenMap();
private DOMToISOCPPTokenMap() {
// just a private constructor
}
public int mapKind(int kind) {
switch(kind) {
case tIDENTIFIER : return TK_identifier;
case tINTEGER : return TK_integer;
case tCOLONCOLON : return TK_ColonColon;
case tCOLON : return TK_Colon;
case tSEMI : return TK_SemiColon;
case tCOMMA : return TK_Comma;
case tQUESTION : return TK_Question;
case tLPAREN : return TK_LeftParen;
case tRPAREN : return TK_RightParen;
case tLBRACKET : return TK_LeftBracket;
case tRBRACKET : return TK_RightBracket;
case tLBRACE : return TK_LeftBrace;
case tRBRACE : return TK_RightBrace;
case tPLUSASSIGN : return TK_PlusAssign;
case tINCR : return TK_PlusPlus;
case tPLUS : return TK_Plus;
case tMINUSASSIGN : return TK_MinusAssign;
case tDECR : return TK_MinusMinus;
case tARROWSTAR : return TK_ArrowStar;
case tARROW : return TK_Arrow;
case tMINUS : return TK_Minus;
case tSTARASSIGN : return TK_StarAssign;
case tSTAR : return TK_Star;
case tMODASSIGN : return TK_PercentAssign;
case tMOD : return TK_Percent;
case tXORASSIGN : return TK_CaretAssign;
case tXOR : return TK_Caret;
case tAMPERASSIGN : return TK_AndAssign;
case tAND : return TK_AndAnd;
case tAMPER : return TK_And;
case tBITORASSIGN : return TK_OrAssign;
case tOR : return TK_OrOr;
case tBITOR : return TK_Or;
case tBITCOMPLEMENT: return TK_Tilde;
case tNOTEQUAL : return TK_NE;
case tNOT : return TK_Bang;
case tEQUAL : return TK_EQ;
case tASSIGN : return TK_Assign;
case tUNKNOWN_CHAR : return TK_Invalid;
case tSHIFTL : return TK_LeftShift;
case tLTEQUAL : return TK_LE;
case tLT : return TK_LT;
case tSHIFTRASSIGN : return TK_RightShiftAssign;
case tSHIFTR : return TK_RightShift;
case tGTEQUAL : return TK_GE;
case tGT : return TK_GT;
case tSHIFTLASSIGN : return TK_LeftShiftAssign;
case tELLIPSIS : return TK_DotDotDot;
case tDOTSTAR : return TK_DotStar;
case tDOT : return TK_Dot;
case tDIVASSIGN : return TK_SlashAssign;
case tDIV : return TK_Slash;
case t_asm : return TK_asm;
case t_auto : return TK_auto;
case t_bool : return TK_bool;
case t_break : return TK_break;
case t_case : return TK_case;
case t_catch : return TK_catch;
case t_char : return TK_char;
case t_class : return TK_class;
case t_const : return TK_const;
case t_const_cast : return TK_const_cast;
case t_continue : return TK_continue;
case t_default : return TK_default;
case t_delete : return TK_delete;
case t_do : return TK_do;
case t_double : return TK_double;
case t_dynamic_cast: return TK_dynamic_cast;
case t_else : return TK_else;
case t_enum : return TK_enum;
case t_explicit : return TK_explicit;
case t_export : return TK_export;
case t_extern : return TK_extern;
case t_false : return TK_false;
case t_float : return TK_float;
case t_for : return TK_for;
case t_friend : return TK_friend;
case t_goto : return TK_goto;
case t_if : return TK_if;
case t_inline : return TK_inline;
case t_int : return TK_int;
case t_long : return TK_long;
case t_mutable : return TK_mutable;
case t_namespace : return TK_namespace;
case t_new : return TK_new;
case t_operator : return TK_operator;
case t_private : return TK_private;
case t_protected : return TK_protected;
case t_public : return TK_public;
case t_register : return TK_register;
case t_return : return TK_return;
case t_short : return TK_short;
case t_sizeof : return TK_sizeof;
case t_static : return TK_static;
case t_static_cast : return TK_static_cast;
case t_signed : return TK_signed;
case t_struct : return TK_struct;
case t_switch : return TK_switch;
case t_template : return TK_template;
case t_this : return TK_this;
case t_throw : return TK_throw;
case t_true : return TK_true;
case t_try : return TK_try;
case t_typedef : return TK_typedef;
case t_typeid : return TK_typeid;
case t_typename : return TK_typename;
case t_union : return TK_union;
case t_unsigned : return TK_unsigned;
case t_using : return TK_using;
case t_virtual : return TK_virtual;
case t_void : return TK_void;
case t_volatile : return TK_volatile;
case t_wchar_t : return TK_wchar_t;
case t_while : return TK_while;
case tFLOATINGPT : return TK_floating;
case tSTRING : return TK_stringlit;
case tLSTRING : return TK_stringlit;
case tCHAR : return TK_charconst;
case tLCHAR : return TK_charconst;
case tCOMPLETION : return TK_Completion;
case tEOC : return TK_EndOfCompletion;
case tEND_OF_INPUT : return TK_EOF_TOKEN;
default:
assert false : "token not recognized by the ISO CPP parser: " + kind; //$NON-NLS-1$
return TK_Invalid;
}
}
}

View file

@ -0,0 +1,97 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.IParser;
import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99ASTNodeFactory;
import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.lrparser.cpp.CPPParser;
/**
* ILanguage implementation for the C++ parser.
*
* @author Mike Kucera
*/
public class ISOCPPLanguage extends BaseExtensibleLanguage {
public static final String PLUGIN_ID = "org.eclipse.cdt.core.lrparser"; //$NON-NLS-1$
public static final String ID = PLUGIN_ID + ".isocpp"; //$NON-NLS-1$
private static final ITokenMap TOKEN_MAP = DOMToISOCPPTokenMap.DEFAULT_MAP;
private static GPPLanguage GPP_LANGUAGE = GPPLanguage.getDefault();
private static ISOCPPLanguage DEFAULT = new ISOCPPLanguage();
public static ISOCPPLanguage getDefault() {
return DEFAULT;
}
@Override
protected IParser getParser() {
return new CPPParser();
}
@Override
protected ITokenMap getTokenMap() {
return TOKEN_MAP;
}
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
return null;
}
public String getId() {
return ID;
}
public int getLinkageID() {
return ILinkage.CPP_LINKAGE_ID;
}
public IASTName[] getSelectedNames(IASTTranslationUnit ast, int start, int length) {
return GPP_LANGUAGE.getSelectedNames(ast, start, length);
}
public String[] getBuiltinTypes() {
return GPP_LANGUAGE.getBuiltinTypes();
}
public String[] getKeywords() {
return GPP_LANGUAGE.getKeywords();
}
public String[] getPreprocessorKeywords() {
return GPP_LANGUAGE.getPreprocessorKeywords();
}
@Override
protected IASTTranslationUnit createASTTranslationUnit() {
return C99ASTNodeFactory.DEFAULT_INSTANCE.newTranslationUnit();
}
@Override
protected ParserLanguage getParserLanguageForPreprocessor() {
return ParserLanguage.CPP;
}
}

View file

@ -0,0 +1,202 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.lpgextensions;
import java.util.Collections;
import java.util.List;
import lpg.lpgjavaruntime.IToken;
import lpg.lpgjavaruntime.LexStream;
import lpg.lpgjavaruntime.PrsStream;
/**
* Base class for parser action classes which support trial, undo and
* final actions.
*/
public abstract class AbstractTrialUndoActionProvider<ACT, RULE_DATA> extends PrsStream implements ITrialUndoActionProvider<RULE_DATA> {
/**
* An action that does nothing.
*/
public static final Action<Object, Object> EMPTY_ACTION = new Action<Object, Object>();
/**
* The parser table interpreter.
*/
protected TrialUndoParser btParser;
public AbstractTrialUndoActionProvider() {
super();
}
public AbstractTrialUndoActionProvider(LexStream lexStream) {
super(lexStream);
}
/**
* Actions for reduction rules.
*/
protected Action<ACT, RULE_DATA>[] ruleAction;
protected ACT parserAction;
public void setParserAction(ACT parserAction) {
this.parserAction = parserAction;
}
/**
* The reduction rule which is currently being processed.
*/
protected Rule<RULE_DATA> activeRule;
/**
* Returns the number of tokens in the rule being reduced.
*/
public int getRuleTokenCount() {
return activeRule.getEndTokenOffset() - activeRule.getStartTokenOffset() + 1;
}
/**
* Returns the tokens in the rule being reduced.
*/
@SuppressWarnings("unchecked")
public List<IToken> getRuleTokens() {
return Collections.unmodifiableList(getTokens().subList(getFirstRealToken(activeRule.getStartTokenOffset()), activeRule.getEndTokenOffset() + 1));
}
public void backtrack() {
btParser.backtrack();
}
public void setActiveRule(Rule<RULE_DATA> rule) {
activeRule = rule;
}
public Rule<RULE_DATA> getActiveRule() {
return activeRule;
}
public final boolean trialAction(int rule_number) {
return ruleAction[rule_number].doTrial(this, parserAction);
}
public final void undoAction(int rule_number) {
ruleAction[rule_number].doUndo(this, parserAction);
}
public final void finalAction(int rule_number) {
System.out.println("finalAction: " + rule_number);
ruleAction[rule_number].doFinal(this, parserAction);
}
public TrialUndoParser getParser() {
return btParser;
}
/**
* Returns the offset of the leftmost token of the
* rule being reduced.
*/
private int getLeftSpan() {
return getFirstRealToken(activeRule.getStartTokenOffset());
}
/**
* Returns the leftmost token of the rule being reduced.
*/
public IToken getLeftIToken() {
return super.getIToken(getLeftSpan());
}
/**
* Returns the offset of the rightmost token of the
* rule being reduced.
*/
private int getRightSpan() {
return activeRule.getEndTokenOffset();
}
/**
* Returns the rightmost token of the rule being reduced.
*/
public IToken getRightIToken() {
return super.getIToken(getRightSpan());
}
public static <ACT, RULE_DATA> Action<ACT, RULE_DATA> emptyAction() {
return new Action<ACT, RULE_DATA>();
}
@SuppressWarnings("unused")
public static class Action<ACT, RULE_DATA> {
public void doFinal(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
// convenience method, can be overridden
}
public boolean doTrial(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
//System.out.println(provider.getActiveRule());
//System.out.println(Rules.lookup(provider.getActiveRule().getRuleNumber()));
return false;
}
public void doUndo(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
//System.out.println(provider.getActiveRule() + " - undo");
// convenience method, can be overridden
}
}
public static class DeclaredAction<ACT, RULE_DATA> extends Action<ACT, RULE_DATA> {
protected boolean hasUndo = false;
@Override
public boolean doTrial(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
return true;
}
}
/**
* Action for a null rule
*/
static final class NullAction<ACT, RULE_DATA> extends Action<ACT, RULE_DATA> {
@Override
public void doFinal(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
// do nothing
}
}
static final class BadAction<ACT, RULE_DATA> extends Action<ACT, RULE_DATA> {
@Override
public void doFinal(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
throw new Error(new BadActionException());
}
@Override
public boolean doTrial(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
throw new Error(new BadActionException());
}
@Override
public void doUndo(ITrialUndoActionProvider<RULE_DATA> provider, ACT action) {
throw new Error(new BadActionException());
}
}
static public class BadActionException extends Exception {
private static final long serialVersionUID = 1L;
}
}

View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 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
*********************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.lpgextensions;
/**
* Provides trial, undo, and final actions for the
* TrialUndoBacktrackingParser.
*/
public interface ITrialUndoActionProvider<RULE_DATA> {
/**
* Invokes the trial action that corresponds to the given rule number.
*/
boolean trialAction(int ruleNumber);
/**
* Invokes the undo action that corresponds to the given rule number.
*/
void undoAction(int ruleNumber);
/**
* Invokes the final action that corresponds to the given rule number.
*/
void finalAction(int ruleNumber);
/**
* Sets the given Rule as the active rule for this provider.
*/
void setActiveRule(Rule<RULE_DATA> rule);
/**
* Returns the active rule for this provider.
*/
Rule<RULE_DATA> getActiveRule();
}

View file

@ -0,0 +1,141 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.lpgextensions;
import java.util.LinkedList;
import lpg.lpgjavaruntime.ConfigurationStack;
import lpg.lpgjavaruntime.IntTuple;
import lpg.lpgjavaruntime.TokenStream;
class ParserState {
private static final int STACK_INCREMENT = 1024;
public int lastToken;
public int currentAction;
public IntTuple tokens;
public int actionStack[];
public int stateStackTop;
public int[] stateStack;
public int actionCount;
public int totalCommits;
public int[] parserLocationStack;
public int[] undoStack;
// Error recovery
public int[] locationStack;
public int repair_token;
/**
* The number of trial actions that have been executed since the last backtrackable point was encountered.
*/
public int trialActionCount;
/**
* A stack that contains the number of trial actions that were executed at different backtrackable points.
*/
public LinkedList<Integer> trialActionStack;
/**
* Trial actions that have been executed but not yet committed.
*/
public LinkedList pendingCommits;
public ConfigurationStack configurationStack;
public int act;
public int curtok;
public ParserState(int startState, TokenStream tokStream) {
reallocateStateStack();
stateStackTop = 0;
stateStack[0] = startState;
//
// The tuple tokens will eventually contain the sequence
// of tokens that resulted in a successful parse. We leave
// it up to the "Stream" implementer to define the predecessor
// of the first token as he sees fit.
//
tokStream.reset(); // Position at first token.
tokens = new IntTuple(tokStream.getStreamLength());
tokens.add(tokStream.getPrevious(tokStream.peek()));
}
public void allocateOtherStacks() {
locationStack = new int[stateStack.length];
}
public void reallocateStateStack() {
int old_stack_length = (stateStack == null ? 0 : stateStack.length), stack_length = old_stack_length + STACK_INCREMENT;
if (stateStack == null)
stateStack = new int[stack_length];
else
System.arraycopy(stateStack, 0, stateStack = new int[stack_length], 0, old_stack_length);
return;
}
//
// Allocate or reallocate all the stacks. Their sizes should always be the
// same.
//
public void reallocateOtherStacks(int start_token_index) {
// assert(stateStack != null);
if (this.actionStack == null) {
this.actionStack = new int[stateStack.length];
locationStack = new int[stateStack.length];
actionStack[0] = 0;
undoStack = new int[stateStack.length];
locationStack[0] = start_token_index;
parserLocationStack = new int[stateStack.length];
parserLocationStack[0] = start_token_index;
} else if (this.actionStack.length < stateStack.length) {
int old_length = this.actionStack.length;
System.arraycopy(this.actionStack, 0, this.actionStack = new int[stateStack.length], 0, old_length);
System.arraycopy(this.undoStack, 0, this.undoStack = new int[stateStack.length], 0, old_length);
System.arraycopy(locationStack, 0, locationStack = new int[stateStack.length], 0, old_length);
}
return;
}
@SuppressWarnings("nls")
public void dumpState() {
System.out.print(curtok);
System.out.print("\t");
System.out.print(act);
System.out.print("\t");
dump(stateStack, stateStackTop);
System.out.print("\t");
dump(parserLocationStack, stateStackTop);
System.out.println();
}
@SuppressWarnings("nls")
private void dump(int[] array, int limit) {
System.out.print("[");
for (int i = 0; i < limit; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(array[i]);
}
System.out.print("]");
}
}

View file

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 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
*********************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.lpgextensions;
/**
* Provides information about a reduction rule that a parser has
* encountered.
*/
class Rule<RULE_DATA> {
private int ruleNumber;
private int startTokenOffset;
private int endTokenOffset;
private RULE_DATA data;
public Rule(int ruleNumber, int startTokenOffset, int endTokenOffset) {
this.ruleNumber = ruleNumber;
this.startTokenOffset = startTokenOffset;
this.endTokenOffset = endTokenOffset;
}
public int getRuleNumber() {
return ruleNumber;
}
public int getStartTokenOffset() {
return startTokenOffset;
}
public int getEndTokenOffset() {
return endTokenOffset;
}
@Override
public String toString() {
return String.valueOf(ruleNumber);
}
public RULE_DATA getData() {
return data;
}
public void setData(RULE_DATA data) {
this.data = data;
}
}

View file

@ -0,0 +1,652 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.lpgextensions;
import java.util.LinkedList;
import lpg.lpgjavaruntime.BadParseException;
import lpg.lpgjavaruntime.BadParseSymFileException;
import lpg.lpgjavaruntime.ConfigurationElement;
import lpg.lpgjavaruntime.ConfigurationStack;
import lpg.lpgjavaruntime.Monitor;
import lpg.lpgjavaruntime.NotBacktrackParseTableException;
import lpg.lpgjavaruntime.ParseTable;
import lpg.lpgjavaruntime.TokenStream;
public class TrialUndoParser {
private Monitor monitor = null;
private int START_STATE, NUM_RULES, LA_STATE_OFFSET, EOFT_SYMBOL, ERROR_SYMBOL, ACCEPT_ACTION, ERROR_ACTION;
private TokenStream tokStream;
private ParseTable prs;
private ITrialUndoActionProvider actionProvider;
private boolean skipTokens = false; // true if error productions are used to
// skip tokens
private ParserState state;
/**
* Signals that a backtrack was requested by a trial action.
*/
private boolean backtrackRequested;
//
// Override the getToken function in Stacks.
//
public final int getToken(int i) {
return state.tokens.get(state.parserLocationStack[state.stateStackTop + (i - 1)]);
}
public int getTokenOffset() {
return state.parserLocationStack[state.stateStackTop];
}
public final int getCurrentRule() {
return state.currentAction;
}
public final int getFirstToken() {
return tokStream.getFirstErrorToken(getToken(1));
}
public final int getFirstToken(int i) {
return tokStream.getFirstErrorToken(getToken(i));
}
public final int getLastToken() {
return tokStream.getLastErrorToken(state.lastToken);
}
public final int getLastToken(int i) {
int l = (i >= prs.rhs(state.currentAction) ? state.lastToken : state.tokens.get(state.locationStack[state.stateStackTop + i] - 1));
return tokStream.getLastErrorToken(l);
}
public TrialUndoParser(TokenStream tokStream, ParseTable prs, ITrialUndoActionProvider ra) throws BadParseSymFileException, NotBacktrackParseTableException {
this.tokStream = tokStream;
this.prs = prs;
this.actionProvider = ra;
START_STATE = prs.getStartState();
NUM_RULES = prs.getNumRules();
LA_STATE_OFFSET = prs.getLaStateOffset();
EOFT_SYMBOL = prs.getEoftSymbol();
ERROR_SYMBOL = prs.getErrorSymbol();
ACCEPT_ACTION = prs.getAcceptAction();
ERROR_ACTION = prs.getErrorAction();
if (!prs.isValidForParser())
throw new BadParseSymFileException();
if (!prs.getBacktrack())
throw new NotBacktrackParseTableException();
}
public TrialUndoParser(Monitor monitor, TokenStream tokStream, ParseTable prs, ITrialUndoActionProvider ra) throws BadParseSymFileException, NotBacktrackParseTableException {
this(tokStream, prs, ra);
this.monitor = monitor;
}
//
// Parse without attempting any Error token recovery
//
public Object parse() throws BadParseException {
// without an argument parse() will ignore error productions
return parse(0);
}
//
// Parse input allowing up to max_error_count Error token recoveries.
// When max_error_count is 0, no Error token recoveries occur.
// When max_error is > 0, it limits the number of Error token recoveries.
// When max_error is < 0, the number of error token recoveries is unlimited.
// Also, such recoveries only require one token to be parsed beyond the
// recovery point.
// (normally two tokens beyond the recovery point must be parsed)
// Thus, a negative max_error_count should be used when error productions
// are used to
// skip tokens.
//
public Object parse(int max_error_count) throws BadParseException {
state = new ParserState(START_STATE, tokStream);
skipTokens = max_error_count < 0;
state.pendingCommits = new LinkedList();
backtrackRequested = false;
state.trialActionCount = 0;
// Next "start" token
state.repair_token = 0;
int start_token_index = tokStream.peek();
int start_action_index = 0;
// Last commit point
int[] temp_stack = new int[1];
temp_stack[0] = START_STATE;
state.reallocateOtherStacks(start_token_index);
int initial_error_token = backtrackParse(state.repair_token);
for (int error_token = initial_error_token, count = 0; error_token != 0; error_token = backtrackParse(state.repair_token), count++) {
if (count == max_error_count)
throw new BadParseException(initial_error_token);
state.actionCount = start_action_index;
tokStream.reset(start_token_index);
state.stateStackTop = temp_stack.length - 1;
System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
state.reallocateOtherStacks(start_token_index);
backtrackParseUpToError(state.repair_token, error_token);
for (state.stateStackTop = findRecoveryStateIndex(state.stateStackTop); state.stateStackTop >= 0; state.stateStackTop = findRecoveryStateIndex(state.stateStackTop - 1)) {
int recovery_token = state.tokens.get(state.locationStack[state.stateStackTop] - 1);
state.repair_token = errorRepair((recovery_token >= start_token_index ? recovery_token : error_token), error_token);
if (state.repair_token != 0)
break;
}
if (state.stateStackTop < 0)
throw new BadParseException(initial_error_token);
temp_stack = new int[state.stateStackTop + 1];
System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);
start_action_index = state.actionCount;
start_token_index = tokStream.peek();
}
if (state.repair_token != 0)
state.tokens.add(state.repair_token);
int t;
for (t = start_token_index; tokStream.getKind(t) != EOFT_SYMBOL; t = tokStream.getNext(t))
state.tokens.add(t);
state.tokens.add(t);
return null;
}
//
// Process reductions and continue...
//
private int process_backtrack_reductions(int act) {
do {
state.stateStackTop -= (prs.rhs(act) - 1);
trialAction(act);
if (backtrackRequested) {
backtrackRequested = false;
return ERROR_ACTION;
}
act = prs.ntAction(state.stateStack[state.stateStackTop], prs.lhs(act));
} while (act <= NUM_RULES);
return act;
}
//
// Process reductions and continue...
//
private int process_repair_reductions(int act) {
do {
System.out.println("process_repair_reductions: " + act);
state.stateStackTop -= (prs.rhs(act) - 1);
act = prs.ntAction(state.stateStack[state.stateStackTop], prs.lhs(act));
} while (act <= NUM_RULES);
return act;
}
//
// Parse the input until either the parse completes successfully or
// an error is encountered. This function returns an integer that
// represents the last action that was executed by the parser. If
// the parse was succesful, then the tuple "action" contains the
// successful sequence of actions that was executed.
//
private int backtrackParse(int initial_token) {
//
// Allocate configuration stack.
//
state.configurationStack = new ConfigurationStack(prs);
state.trialActionStack = new LinkedList<Integer>();
state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
//
// Keep parsing until we successfully reach the end of file or
// an error is encountered. The list of actions executed will
// be stored in the "action" tuple.
//
int error_token = 0;
int maxStackTop = state.stateStackTop;
int start_token = tokStream.peek();
state.curtok = (initial_token > 0 ? initial_token : tokStream.getToken());
int current_kind = tokStream.getKind(state.curtok);
state.act = tAction(state.stateStack[state.stateStackTop], current_kind);
//
// The main driver loop
//
for (;;) {
//
// if the parser needs to stop processing,
// it may do so here.
//
if (monitor != null && monitor.isCancelled())
return 0;
state.parserLocationStack[state.stateStackTop] = state.curtok;
if (state.act <= NUM_RULES) {
state.actionCount++;
state.stateStackTop--;
state.act = process_backtrack_reductions(state.act);
} else if (state.act > ERROR_ACTION) {
state.actionCount++;
state.lastToken = state.curtok;
state.curtok = tokStream.getToken();
current_kind = tokStream.getKind(state.curtok);
state.act = process_backtrack_reductions(state.act - ERROR_ACTION);
} else if (state.act < ACCEPT_ACTION) {
state.actionCount++;
state.lastToken = state.curtok;
state.curtok = tokStream.getToken();
current_kind = tokStream.getKind(state.curtok);
}
if (state.act == ERROR_ACTION) {
error_token = (error_token > state.curtok ? error_token : state.curtok);
undoActions();
ConfigurationElement configuration = state.configurationStack.pop();
if (configuration == null)
state.act = ERROR_ACTION;
else {
state.actionCount = configuration.action_length;
state.act = configuration.act;
state.curtok = configuration.curtok;
current_kind = tokStream.getKind(state.curtok);
tokStream.reset(state.curtok == initial_token ? start_token : tokStream.getNext(state.curtok));
state.stateStackTop = configuration.stack_top;
configuration.retrieveStack(state.stateStack);
continue;
}
break;
}
if (state.act > ACCEPT_ACTION && state.act != ERROR_ACTION) {
if (state.configurationStack.findConfiguration(state.stateStack, state.stateStackTop, state.curtok))
state.act = ERROR_ACTION;
else {
state.configurationStack.push(state.stateStack, state.stateStackTop, state.act + 1, state.curtok, state.actionCount);
state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
state.act = prs.baseAction(state.act);
maxStackTop = state.stateStackTop > maxStackTop ? state.stateStackTop : maxStackTop;
}
continue;
} else if (state.act == ACCEPT_ACTION) {
break;
}
try {
state.stateStack[++state.stateStackTop] = state.act;
} catch (IndexOutOfBoundsException e) {
state.reallocateStateStack();
state.stateStack[state.stateStackTop] = state.act;
}
state.act = tAction(state.act, current_kind);
}
// System.out.println("****Number of configurations: " +
// configuration_stack.configurationSize());
// System.out.println("****Number of elements in stack tree: " +
// configuration_stack.numStateElements());
// System.out.println("****Number of elements in stacks: " +
// configuration_stack.stacksSize());
// System.out.println("****Number of actions: " + action.size());
// System.out.println("****Max Stack Size = " + maxStackTop);
// System.out.flush();
return (state.act == ERROR_ACTION ? error_token : 0);
}
private void backtrackParseUpToError(int initial_token, int error_token) {
//
// Allocate configuration stack.
//
state.configurationStack = new ConfigurationStack(prs);
state.trialActionStack = new LinkedList<Integer>();
state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
//
// Keep parsing until we successfully reach the end of file or
// an error is encountered. The list of actions executed will
// be stored in the "action" tuple.
//
// tokStream.reset(initial_token);
int start_token = tokStream.peek();
state.curtok = (initial_token > 0 ? initial_token : tokStream.getToken());
int current_kind = tokStream.getKind(state.curtok);
state.act = tAction(state.stateStack[state.stateStackTop], current_kind);
state.tokens.add(state.curtok);
state.locationStack[state.stateStackTop] = state.tokens.size();
state.actionStack[state.stateStackTop] = state.actionCount;
state.undoStack[state.stateStackTop] = state.trialActionCount;
for (;;) {
//
// if the parser needs to stop processing,
// it may do so here.
//
if (monitor != null && monitor.isCancelled())
return;
state.parserLocationStack[state.stateStackTop] = state.curtok;
if (state.act <= NUM_RULES) {
state.actionCount++;
state.stateStackTop--;
state.act = process_backtrack_reductions(state.act);
} else if (state.act > ERROR_ACTION) {
state.actionCount++;
state.lastToken = state.curtok;
state.curtok = tokStream.getToken();
current_kind = tokStream.getKind(state.curtok);
state.tokens.add(state.curtok);
state.act = process_backtrack_reductions(state.act - ERROR_ACTION);
} else if (state.act < ACCEPT_ACTION) {
state.actionCount++;
state.lastToken = state.curtok;
state.curtok = tokStream.getToken();
current_kind = tokStream.getKind(state.curtok);
state.tokens.add(state.curtok);
} else if (state.act == ERROR_ACTION) {
if (state.curtok != error_token) {
undoActions();
ConfigurationElement configuration = state.configurationStack.pop();
if (configuration == null)
state.act = ERROR_ACTION;
else {
state.actionCount = configuration.action_length;
state.act = configuration.act;
int next_token_index = configuration.curtok;
state.tokens.reset(next_token_index);
state.curtok = state.tokens.get(next_token_index - 1);
current_kind = tokStream.getKind(state.curtok);
tokStream.reset(state.curtok == initial_token ? start_token : tokStream.getNext(state.curtok));
state.stateStackTop = configuration.stack_top;
configuration.retrieveStack(state.stateStack);
state.locationStack[state.stateStackTop] = state.tokens.size();
state.actionStack[state.stateStackTop] = state.actionCount;
state.undoStack[state.stateStackTop] = state.trialActionCount;
continue;
}
}
break;
} else if (state.act > ACCEPT_ACTION) {
if (state.configurationStack.findConfiguration(state.stateStack, state.stateStackTop, state.tokens.size()))
state.act = ERROR_ACTION;
else {
state.configurationStack.push(state.stateStack, state.stateStackTop, state.act + 1, state.tokens.size(), state.actionCount);
state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
state.act = prs.baseAction(state.act);
}
continue;
} else
break; // assert(act == ACCEPT_ACTION);
state.stateStack[++state.stateStackTop] = state.act; // no need
// to check
// if out of
// bounds
state.locationStack[state.stateStackTop] = state.tokens.size();
state.actionStack[state.stateStackTop] = state.actionCount;
state.undoStack[state.stateStackTop] = state.trialActionCount;
state.act = tAction(state.act, current_kind);
}
// assert(curtok == error_token);
return;
}
private boolean repairable(int error_token) {
//
// Allocate configuration stack.
//
ConfigurationStack configuration_stack = new ConfigurationStack(prs);
//
// Keep parsing until we successfully reach the end of file or
// an error is encountered. The list of actions executed will
// be stored in the "action" tuple.
//
int start_token = tokStream.peek();
int final_token = tokStream.getStreamLength(); // unreachable
int curtok = 0;
int current_kind = ERROR_SYMBOL;
int act = tAction(state.stateStack[state.stateStackTop], current_kind);
for (;;) {
if (act <= NUM_RULES) {
state.stateStackTop--;
act = process_repair_reductions(act);
} else if (act > ERROR_ACTION) {
curtok = tokStream.getToken();
if (curtok > final_token)
return true;
current_kind = tokStream.getKind(curtok);
act = process_repair_reductions(act - ERROR_ACTION);
} else if (act < ACCEPT_ACTION) {
curtok = tokStream.getToken();
if (curtok > final_token)
return true;
current_kind = tokStream.getKind(curtok);
} else if (act == ERROR_ACTION) {
ConfigurationElement configuration = configuration_stack.pop();
if (configuration == null)
act = ERROR_ACTION;
else {
state.stateStackTop = configuration.stack_top;
configuration.retrieveStack(state.stateStack);
act = configuration.act;
curtok = configuration.curtok;
if (curtok == 0) {
current_kind = ERROR_SYMBOL;
tokStream.reset(start_token);
} else {
current_kind = tokStream.getKind(curtok);
tokStream.reset(tokStream.getNext(curtok));
}
continue;
}
break;
} else if (act > ACCEPT_ACTION) {
if (configuration_stack.findConfiguration(state.stateStack, state.stateStackTop, curtok))
act = ERROR_ACTION;
else {
configuration_stack.push(state.stateStack, state.stateStackTop, act + 1, curtok, 0);
act = prs.baseAction(act);
}
continue;
} else
break; // assert(act == ACCEPT_ACTION);
try {
//
// We consider a configuration to be acceptable for recovery
// if we are able to consume enough symbols in the remaining
// tokens to reach another potential recovery point past the
// original error token.
//
if ((curtok > error_token) && (final_token == tokStream.getStreamLength())) {
//
// If the ERROR_SYMBOL is a valid Action Adjunct in the
// state
// "act" then we set the terminating token as the successor
// of
// the current token. I.e., we have to be able to parse at
// least
// two tokens past the re-synch point before we claim
// victory.
//
if (recoverableState(act))
final_token = skipTokens ? curtok : tokStream.getNext(curtok);
}
state.stateStack[++state.stateStackTop] = act;
} catch (IndexOutOfBoundsException e) {
state.reallocateStateStack();
state.stateStack[state.stateStackTop] = act;
}
act = tAction(act, current_kind);
}
//
// If we can reach the end of the input successfully, we claim victory.
//
return (act == ACCEPT_ACTION);
}
private boolean recoverableState(int state) {
for (int k = prs.asi(state); prs.asr(k) != 0; k++) {
if (prs.asr(k) == ERROR_SYMBOL)
return true;
}
return false;
}
private int findRecoveryStateIndex(int start_index) {
int i;
for (i = start_index; i >= 0; i--) {
//
// If the ERROR_SYMBOL is an Action Adjunct in state stateStack[i]
// then chose i as the index of the state to recover on.
//
if (recoverableState(state.stateStack[i]))
break;
}
if (i >= 0) // if a recoverable state, remove null reductions, if any.
{
int k;
for (k = i - 1; k >= 0; k--) {
if (state.locationStack[k] != state.locationStack[i])
break;
}
i = k + 1;
}
return i;
}
private int errorRepair(int recovery_token, int error_token) {
int temp_stack[] = new int[state.stateStackTop + 1];
System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);
for (; tokStream.getKind(recovery_token) != EOFT_SYMBOL; recovery_token = tokStream.getNext(recovery_token)) {
System.out.println("recovery token: " + tokStream.getKind(recovery_token)); //$NON-NLS-1$
tokStream.reset(recovery_token);
if (repairable(error_token))
break;
state.stateStackTop = temp_stack.length - 1;
System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
}
if (tokStream.getKind(recovery_token) == EOFT_SYMBOL) {
tokStream.reset(recovery_token);
if (!repairable(error_token)) {
state.stateStackTop = temp_stack.length - 1;
System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
return 0;
}
}
state.stateStackTop = temp_stack.length - 1;
System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
undoActions(state.undoStack[state.stateStackTop]);
tokStream.reset(recovery_token);
state.tokens.reset(state.locationStack[state.stateStackTop] - 1);
state.actionCount = state.actionStack[state.stateStackTop];
state.trialActionCount = state.undoStack[state.stateStackTop];
return tokStream.makeErrorToken(state.tokens.get(state.locationStack[state.stateStackTop] - 1), tokStream.getPrevious(recovery_token), error_token, ERROR_SYMBOL);
}
private int tAction(int act, int sym) {
act = prs.tAction(act, sym);
if (act > LA_STATE_OFFSET) {
int next_token = tokStream.peek();
act = prs.lookAhead(act - LA_STATE_OFFSET, tokStream.getKind(next_token));
while (act > LA_STATE_OFFSET) {
next_token = tokStream.getNext(next_token);
act = prs.lookAhead(act - LA_STATE_OFFSET, tokStream.getKind(next_token));
}
}
return act;
}
private void trialAction(int action) {
int start = getTokenOffset();
int end = getLastToken();
Rule rule = new Rule(action, start, end);
actionProvider.setActiveRule(rule);
boolean saveAction = actionProvider.trialAction(action);
if (backtrackRequested) {
return;
}
if (saveAction) {
state.trialActionCount++;
state.pendingCommits.add(rule);
}
}
/**
* Performs the undo actions (in reverse order) for the corresponding trial
* actions that have been executed since the last backtrackable point.
*/
private void undoActions() {
int oldTrialActionCount;
if (state.trialActionStack.size() == 0) {
oldTrialActionCount = 0;
} else {
oldTrialActionCount = state.trialActionStack.removeLast();
}
safeUndoActions(oldTrialActionCount);
// needs to be a real checked exception if we ever decide to implement commits
//assert (state.trialActionCount == 0 && oldTrialActionCount == 0) || oldTrialActionCount != state.trialActionCount : "Went back in time too far";
}
private void safeUndoActions(int total) {
assert total >= 0 : "Tried to go back in time but the door was already shut."; //$NON-NLS-1$
undoActions(total);
}
private void undoActions(int total) {
while (state.trialActionCount > total) {
Rule action = ((Rule) state.pendingCommits.removeLast());
actionProvider.setActiveRule(action);
actionProvider.undoAction(action.getRuleNumber());
state.trialActionCount--;
}
}
public void backtrack() {
backtrackRequested = true;
}
public void commit() {
while (state.pendingCommits.size() > 0) {
Rule activeRule = (Rule) state.pendingCommits.removeFirst();
actionProvider.setActiveRule(activeRule);
actionProvider.finalAction(activeRule.getRuleNumber());
state.totalCommits++;
}
}
}

View file

@ -0,0 +1,303 @@
--------------------------------------------------------------------------------
-- Copyright (c) 2006, 2007 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
--------------------------------------------------------------------------------
--
-- In a parser using this template, the following macro may be redefined:
--
-- $additional_interfaces
-- $ast_class
--
-- B E G I N N I N G O F T E M P L A T E TrialUndoParserTemplate
--
%Options programming_language=java,margin=8,backtrack
%Options table,error_maps,scopes
%options prefix=TK_,
%options action=("*.java", "/.", "./")
%options headers=("*.java", "/:", ":/")
%options ParseTable=lpg.lpgjavaruntime.ParseTable
--
-- This template requires that the name of the EOF token be set
-- to EOF_TOKEN to be consistent with LexerTemplateD and LexerTemplateE
--
$EOF
EOF_TOKEN
$End
$ERROR
ERROR_TOKEN
$End
$Define
$DefaultAllocation
/:
RULE_ACTIONS[$rule_number] = new Action$rule_number$();:/
$NoAllocation
/:
RULE_ACTIONS[$rule_number] = EMPTY_ACTION:/
$NullAllocation
/:
RULE_ACTIONS[$rule_number] = new NullAction();:/
$BadAllocation
/:
RULE_ACTIONS[$rule_number] = new BadAction();:/
$Header
/.
//
// Rule $rule_number: $rule_text
//./
$DefaultAction
/.$DefaultAllocation $Header
static final class Action$rule_number extends Action./
--
-- This macro is used to initialize the ruleAction array
-- to the null_action function.
--
$NullAction
/. $NullAllocation $Header
//
// final class NullAction extends Action
//
./
--
-- This macro is used to initialize the ruleAction array
-- to the no_action function.
--
$NoAction
/. $NoAllocation $Header
//
// final class NullAction extends Action
//
./
--
-- This macro is used to initialize the ruleAction array
-- to the bad_action function.
--
$BadAction
/. $BadAllocation $Header
//
// final class NullAction extends Action
//
./
--
-- This is the header for a ruleAction class
--
$BeginAction
/.$DefaultAllocation $Header
static final class Action$rule_number extends DeclaredAction<$action_class, $data_class> {
./
$EndAction
/.
}./
$BeginTrial
/.
public boolean doTrial(ITrialUndoActionProvider<$data_class> provider, $action_class action) {./
$EndTrial
/.
return hasUndo;
}./
$BeginUndo
/.
public Action$rule_number() { hasUndo = true; };
public void doUndo(ITrialUndoActionProvider<$data_class> provider, $action_class action) {./
$EndUndo
/.
}./
$BeginFinal
/.
public void doFinal(ITrialUndoActionProvider<$data_class> provider, $action_class action) {./
$EndFinal
/.
}./
$BeginJava
/.$BeginAction
$symbol_declarations./
$EndJava /.$EndAction./
$SplitActions /../
--
-- Macros that may be needed in a parser using this template
--
$additional_interfaces /../
$ast_class /.$ast_type./
$action_class /.Object./
$Trial /.$BeginTrial./
$Undo /.$BeginUndo./
$Final /.$BeginFinal./
$Action /.$BeginAction./
$End
$Globals
/.
import lpg.lpgjavaruntime.*;
import org.eclipse.cdt.core.dom.lrparser.lpgextensions.ITrialUndoActionProvider;
import org.eclipse.cdt.core.dom.lrparser.lpgextensions.AbstractTrialUndoActionProvider;
import org.eclipse.cdt.core.dom.lrparser.lpgextensions.TrialUndoParser;
./
$End
$Headers
/.
public class $action_type extends AbstractTrialUndoActionProvider<$action_class, $data_class> implements IParserActionTokenProvider, IParser $additional_interfaces {
private static ParseTable prs = new $prs_type();
protected static final Action<$action_class, $data_class>[] RULE_ACTIONS;
{
ruleAction = RULE_ACTIONS;
}
public $action_type(LexStream lexStream) {
super(lexStream);
try {
super.remapTerminalSymbols(orderedTerminalSymbols(), $prs_type.EOFT_SYMBOL);
} catch (NullExportedSymbolsException e) {
} catch (NullTerminalSymbolsException e) {
} catch (UnimplementedTerminalsException e) {
java.util.ArrayList unimplemented_symbols = e.getSymbols();
System.out.println("The Lexer will not scan the following token(s):");
for (int i = 0; i < unimplemented_symbols.size(); i++) {
Integer id = (Integer) unimplemented_symbols.get(i);
System.out.println(" " + $sym_type.orderedTerminalSymbols[id.intValue()]);
}
System.out.println();
} catch (UndefinedEofSymbolException e) {
throw new Error(new UndefinedEofSymbolException("The Lexer does not implement the Eof symbol " + $sym_type.orderedTerminalSymbols[$prs_type.EOFT_SYMBOL]));
}
}
public $action_type() { // constructor
// this(new $lexer_class());
}
public String[] orderedTerminalSymbols() {
return $sym_type.orderedTerminalSymbols;
}
public String getTokenKindName(int kind) {
return $sym_type.orderedTerminalSymbols[kind];
}
public int getEOFTokenKind() {
return $prs_type.EOFT_SYMBOL;
}
public PrsStream getParseStream() {
return (PrsStream) this;
}
//
// Report error message for given error_token.
//
public final void reportErrorTokenMessage(int error_token, String msg) {
int firsttok = super.getFirstRealToken(error_token), lasttok = super.getLastRealToken(error_token);
String location = super.getFileName() + ':' +
(firsttok > lasttok
? (super.getEndLine(lasttok) + ":" + super.getEndColumn(lasttok))
: (super.getLine(error_token) + ":" +
super.getColumn(error_token) + ":" +
super.getEndLine(error_token) + ":" +
super.getEndColumn(error_token))) + ": ";
super.reportError((firsttok > lasttok ? ParseErrorCodes.INSERTION_CODE : ParseErrorCodes.SUBSTITUTION_CODE), location, msg);
}
public $ast_class parser() {
return parser(null, 0);
}
public $ast_class parser(Monitor monitor) {
return parser(monitor, 0);
}
public $ast_class parser(int error_repair_count) {
return parser(null, error_repair_count);
}
public $ast_class parser(Monitor monitor, int error_repair_count) {
try {
btParser = new TrialUndoParser((TokenStream) this, prs, (ITrialUndoActionProvider<$data_class>) this);
} catch (NotBacktrackParseTableException e) {
throw new Error(new NotBacktrackParseTableException("Regenerate $prs_type.java with -BACKTRACK option"));
} catch (BadParseSymFileException e) {
throw new Error(new BadParseSymFileException("Bad Parser Symbol File -- $sym_type.java"));
}
try {
Object result = (Object) btParser.parse(error_repair_count);
btParser.commit();
return result;
} catch (BadParseException e) {
reset(e.error_token); // point to error token
//DiagnoseParser diagnoseParser = new DiagnoseParser((TokenStream) this, prs);
//diagnoseParser.diagnose(e.error_token);
}
return null;
}
./
/:
//
// Initialize ruleAction array.
//
static {
RULE_ACTIONS = new Action[$NUM_RULES + 1];
RULE_ACTIONS[0] = null;
:/
$End
$Trailers
/.
}
./
/:
//
// Make sure that all elements of ruleAction are properly initialized
//
for (int i = 0; i < RULE_ACTIONS.length; i++) {
if (RULE_ACTIONS[i] == null) {
RULE_ACTIONS[i] = emptyAction();
}
}
}
:/
$End
--
-- E N D O F T E M P L A T E
--

View file

@ -0,0 +1,472 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.util;
import java.io.PrintStream;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
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.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICPointerType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
/**
* A utility that prints an AST to the console, useful for debugging purposes.
*
* @author Mike Kucera
*/
@SuppressWarnings("restriction")
class ASTPrinter {
/**
* Prints the AST to the given PrintStream.
*/
public static void printAST(IASTTranslationUnit root, PrintStream stream) {
PrintStream out = stream == null ? System.out : stream;
if(root == null) {
out.println("null"); //$NON-NLS-1$
return;
}
PrintVisitor visitor = new PrintVisitor(out);
IASTPreprocessorStatement[] preStats = root.getAllPreprocessorStatements();
if(preStats != null) {
for(int i = 0; i < preStats.length; i++) {
print(out, 0, preStats[i]);
}
}
root.accept(visitor);
IASTProblem[] problems = root.getPreprocessorProblems();
if(problems != null) {
for(int i = 0; i < problems.length; i++) {
print(out, 0, problems[i]);
}
}
IASTComment[] comments = root.getComments();
if(comments != null) {
for(int i = 0; i < comments.length; i++) {
print(out, 0, comments[i]);
}
}
}
/**
* Prints the AST to stdout.
*/
public static void printAST(IASTTranslationUnit root) {
printAST(root, null);
}
public static void printProblems(IASTTranslationUnit root, PrintStream stream) {
PrintStream out = stream == null ? System.out : stream;
if(root == null) {
out.println("null");//$NON-NLS-1$
return;
}
ProblemVisitor visitor = new ProblemVisitor(out);
root.accept(visitor);
IASTProblem[] problems = root.getPreprocessorProblems();
if(problems != null) {
for(int i = 0; i < problems.length; i++) {
print(out, 0, problems[i]);
}
}
}
public static void printProblems(IASTTranslationUnit root) {
printProblems(root, System.out);
}
private static void print(PrintStream out, int indentLevel, Object n) {
for(int i = 0; i < indentLevel; i++)
out.print(" "); //$NON-NLS-1$
if(n == null) {
out.println("NULL"); //$NON-NLS-1$
return;
}
String classname = n.getClass().getName();
out.print(classname);
if(n instanceof ASTNode) {
ASTNode node = (ASTNode) n;
out.print(" (" + node.getOffset() + "," + node.getLength() + ") "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if(node.getParent() == null && !(node instanceof IASTTranslationUnit)) {
out.print("PARENT IS NULL ");//$NON-NLS-1$
}
//out.print(node.getPropertyInParent());
}
if(n instanceof ICArrayType) {
ICArrayType at = (ICArrayType)n;
try {
if(at.isRestrict()) {
out.print(" restrict"); //$NON-NLS-1$
}
} catch (DOMException e) {
e.printStackTrace();
}
}
if(n instanceof IASTName) {
out.print(" " + ((IASTName)n).toString()); //$NON-NLS-1$
}
else if(n instanceof ICASTPointer) {
ICASTPointer pointer = (ICASTPointer) n;
if(pointer.isConst())
out.print(" const"); //$NON-NLS-1$
if(pointer.isVolatile())
out.print(" volatile"); //$NON-NLS-1$
if(pointer.isRestrict())
out.print(" restrict");//$NON-NLS-1$
}
else if(n instanceof ICPointerType) {
ICPointerType pointer = (ICPointerType)n;
try {
if(pointer.isConst())
out.print(" const"); //$NON-NLS-1$
if(pointer.isVolatile())
out.print(" volatile"); //$NON-NLS-1$
if(pointer.isRestrict())
out.print(" restrict");//$NON-NLS-1$
} catch (DOMException e) {
e.printStackTrace();
}
out.println();
try {
print(out, indentLevel, ((ITypeContainer)n).getType());
} catch(Exception e) {}
}
else if(n instanceof ICASTArrayModifier) {
if(((ICASTArrayModifier)n).isRestrict()) {
out.print(" restrict"); //$NON-NLS-1$
}
}
else if(n instanceof IASTComment) {
out.print("'" + new String(((IASTComment)n).getComment()) + "'");
}
// else if(n instanceof ICompositeType) {
// try {
// IField[] fields = ((ICompositeType)n).getFields();
// if(fields == null || fields.length == 0) {
// out.print(" no fields");
// }
// for(IField field : fields) {
// out.println();
// print(out, indentLevel + 1, field);
// }
// } catch (DOMException e) {
// e.printStackTrace();
// }
// }
else if(n instanceof ITypeContainer) {
out.println();
try {
print(out, indentLevel, ((ITypeContainer)n).getType());
} catch(Exception e) {}
}
else if(n instanceof IVariable) {
IVariable var = (IVariable) n;
IType t;
try {
t = var.getType();
out.println();
print(out, indentLevel, t);
} catch (DOMException e) {
//e.printStackTrace();
}
}
out.println();
}
private static class ProblemVisitor extends CASTVisitor {
private PrintStream out;
ProblemVisitor(PrintStream out) {
this.out = out;
shouldVisitProblems = true;
shouldVisitDeclarations = true;
shouldVisitStatements = true;
shouldVisitExpressions = true;
}
public int visit(IASTProblem problem) {
print(out, 1, problem);
return PROCESS_CONTINUE;
}
public int visit(IASTDeclaration declaration) {
if(declaration instanceof IASTProblemDeclaration)
print(out, 0, declaration);
return PROCESS_CONTINUE;
}
public int visit(IASTExpression expression) {
if(expression instanceof IASTProblemExpression)
print(out, 0, expression);
return PROCESS_CONTINUE;
}
public int visit(IASTStatement statement) {
if(statement instanceof IASTProblemStatement)
print(out, 0, statement);
return PROCESS_CONTINUE;
}
}
private static class PrintVisitor extends CASTVisitor {
private PrintStream out;
private int indentLevel = 0;
PrintVisitor(PrintStream out) {
this.out = out;
shouldVisitDesignators = true;
shouldVisitNames = true;
shouldVisitDeclarations = true;
shouldVisitInitializers = true;
shouldVisitParameterDeclarations = true;
shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true;
shouldVisitExpressions = true;
shouldVisitStatements = true;
shouldVisitTypeIds = true;
shouldVisitEnumerators = true;
shouldVisitTranslationUnit = true;
shouldVisitProblems = true;
}
private void print(IASTNode node) {
ASTPrinter.print(out, indentLevel, node);
}
private void print(IBinding binding) {
ASTPrinter.print(out, indentLevel, binding);
}
public int visit(IASTComment comment) {
print(comment);
indentLevel++;
return super.visit(comment);
}
public int visit(ICASTDesignator designator) {
print(designator);
indentLevel++;
return super.visit(designator);
}
public int visit(IASTDeclaration declaration) {
print(declaration);
indentLevel++;
return super.visit(declaration);
}
public int visit(IASTDeclarator declarator) {
print(declarator);
indentLevel++;
IASTPointerOperator[] pointers = declarator.getPointerOperators();
for(int i = 0; i < pointers.length; i++) {
print(pointers[i]);
}
if(declarator instanceof IASTArrayDeclarator) {
IASTArrayDeclarator decl = (IASTArrayDeclarator)declarator;
org.eclipse.cdt.core.dom.ast.IASTArrayModifier[] modifiers = decl.getArrayModifiers();
for(int i = 0; i < modifiers.length; i++) {
print((IASTNode)modifiers[i]);
}
}
return super.visit(declarator);
}
public int visit(IASTDeclSpecifier declSpec) {
print(declSpec);
indentLevel++;
return super.visit(declSpec);
}
public int visit(IASTEnumerator enumerator) {
print(enumerator);
indentLevel++;
return super.visit(enumerator);
}
public int visit(IASTExpression expression) {
print(expression);
indentLevel++;
return super.visit(expression);
}
public int visit(IASTInitializer initializer) {
print(initializer);
indentLevel++;
return super.visit(initializer);
}
public int visit(IASTName name) {
print(name);
IBinding binding = name.resolveBinding();
print(binding);
indentLevel++;
return super.visit(name);
}
public int visit(IASTParameterDeclaration parameterDeclaration) {
print(parameterDeclaration);
indentLevel++;
return super.visit(parameterDeclaration);
}
public int visit(IASTProblem problem) {
print(problem);
indentLevel++;
return super.visit(problem);
}
public int visit(IASTStatement statement) {
print(statement);
indentLevel++;
return super.visit(statement);
}
public int visit(IASTTranslationUnit tu) {
print(tu);
indentLevel++;
return super.visit(tu);
}
public int visit(IASTTypeId typeId) {
print(typeId);
indentLevel++;
return super.visit(typeId);
}
public int leave(IASTComment comment) {
indentLevel--;
return super.leave(comment);
}
public int leave(ICASTDesignator designator) {
indentLevel--;
return super.leave(designator);
}
public int leave(IASTDeclaration declaration) {
indentLevel--;
return super.leave(declaration);
}
public int leave(IASTDeclarator declarator) {
indentLevel--;
return super.leave(declarator);
}
public int leave(IASTDeclSpecifier declSpec) {
indentLevel--;
return super.leave(declSpec);
}
public int leave(IASTEnumerator enumerator) {
indentLevel--;
return super.leave(enumerator);
}
public int leave(IASTExpression expression) {
indentLevel--;
return super.leave(expression);
}
public int leave(IASTInitializer initializer) {
indentLevel--;
return super.leave(initializer);
}
public int leave(IASTName name) {
indentLevel--;
return super.leave(name);
}
public int leave(IASTParameterDeclaration parameterDeclaration) {
indentLevel--;
return super.leave(parameterDeclaration);
}
public int leave(IASTProblem problem) {
indentLevel--;
return super.leave(problem);
}
public int leave(IASTStatement statement) {
indentLevel--;
return super.leave(statement);
}
public int leave(IASTTranslationUnit tu) {
indentLevel--;
return super.leave(tu);
}
public int leave(IASTTypeId typeId) {
indentLevel--;
return super.leave(typeId);
}
};
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.util;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
/**
* An AST visitor that asserts that all bindings have been resolved.
*
* @author Mike Kucera
*/
class BindingCheckVisitor extends CASTVisitor {
public static ASTVisitor VISITOR = new BindingCheckVisitor();
private BindingCheckVisitor() {
shouldVisitNames = true;
shouldVisitDeclarations = true;
shouldVisitInitializers = true;
shouldVisitParameterDeclarations = true;
shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true;
shouldVisitExpressions = true;
shouldVisitStatements = true;
shouldVisitTypeIds = true;
shouldVisitEnumerators = true;
shouldVisitTranslationUnit = true;
shouldVisitProblems = false;
shouldVisitComments = false;
shouldVisitDesignators = true;
}
public int visit(IASTName name) {
if(name.getBinding() == null)
throw new AssertionError("Binding did not get pre-resolved: '" + name + "'");
return PROCESS_CONTINUE;
}
}

View file

@ -0,0 +1,126 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.util;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import lpg.lpgjavaruntime.IToken;
/**
* Useful utility methods for dealing with Collections.
*
* @author Mike Kucera
*/
public final class CollectionUtils {
private CollectionUtils() {
// this class has just static utility methods
}
/**
* Returns an iterator that iterates backwards over the given list.
* The remove() method is not implemented and will throw UnsupportedOperationException.
* @throws NullPointerException if list is null
*/
public static <T> Iterator<T> reverseIterator(final List<T> list) {
return new Iterator<T>() {
ListIterator<T> iterator = list.listIterator(list.size());
public boolean hasNext() {
return iterator.hasPrevious();
}
public T next() {
return iterator.previous();
}
public void remove() {
throw new UnsupportedOperationException("remove() not supported"); //$NON-NLS-1$
}
};
}
/**
* Allows a foreach loop to iterate backwards over a list
* from the end to the start.
* @throws NullPointerException if list is null
*/
public static <T> Iterable<T> reverseIterable(final List<T> list) {
return iterable(reverseIterator(list));
}
/**
* Creates an Iterable instance that just returns
* the given Iterator from its iterator() method.
*
* This is useful for using an iterator in a foreach loop directly.
*
* ex)
*
* foreach(Object o : iterable(list.listIterator())) {
* // do something
* }
*
* @throws NullPointerException if list is null
*/
public static <T> Iterable<T> iterable(final Iterator<T> iter) {
if(iter == null)
throw new NullPointerException("iter parameter is null"); //$NON-NLS-1$
return new Iterable<T>() {
public Iterator<T> iterator() {
return iter;
}
};
}
/**
* Allows simple pattern match testing of lists of tokens.
*
* @throws NullPointerException if source or pattern is null
*/
public static boolean matchTokens(List<IToken> source, Integer ... pattern) {
if(source.size() != pattern.length) // throws NPE if either param is null
return false;
for(int i = 0, n = pattern.length; i < n; i++) {
if(source.get(i).getKind() != pattern[i].intValue())
return false;
}
return true;
}
/**
* Finds the first object in the heterogeneous list that is an instance of
* the given class, removes it from the list, and returns it.
*
* @throws NullPointerException if list or clazz is null
* @throws UnsupportedOperationException if the list's Iterator does not support the remove() method
*/
@SuppressWarnings("unchecked")
public static <T> T findFirstAndRemove(List<Object> list, Class<T> clazz) {
// There's a name somewhere on the stack, find it
for(Iterator<Object> iter = list.iterator(); iter.hasNext();) {
Object o = iter.next();
if(clazz.isInstance(o)) {
iter.remove();
return (T) o;
}
}
return null;
}
}

View file

@ -0,0 +1,76 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.util;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
/**
* This class contains several convenience methods
* mainly for debugging purposes.
*
* @author Mike Kucera
*
*/
public class DebugUtil {
private DebugUtil() { // class just contains static methods
}
/**
* Prints a trace message to stdout that gives info
* about the method that calls this method.
*/
public static void printMethodTrace() {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
printMethodTrace(trace, null);
}
/**
* Prints a trace message to stdout that gives info
* about the method that calls this method.
*/
public static void printMethodTrace(String extraMessage) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
printMethodTrace(trace, extraMessage);
}
private static void printMethodTrace(StackTraceElement[] trace, String extraMessage) {
StackTraceElement caller = trace[3];
String className = caller.getClassName();
className = className.substring(className.lastIndexOf(".") + 1);//$NON-NLS-1$
String message = String.format("%s.%s(%s:%d)", //$NON-NLS-1$
className, caller.getMethodName(), caller.getFileName(), caller.getLineNumber());
if(extraMessage != null)
message += ": " + extraMessage;//$NON-NLS-1$
System.out.println(message);
}
/**
* Prints a textual representation of the AST to stdout.
*/
public static void printAST(IASTTranslationUnit tu) {
ASTPrinter.printAST(tu);
}
/**
* Throws an AssertionError if any of the bindings in
* the given AST cannot be resolved.
*/
public static void assertBindings(IASTTranslationUnit tu) throws AssertionError {
tu.accept(BindingCheckVisitor.VISITOR);
}
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99BuildASTParserAction;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99TypedefTrackerParserAction;
class C99ParserAction {
public C99BuildASTParserAction builder;
public C99TypedefTrackerParserAction resolver;
}

View file

@ -0,0 +1,212 @@
/*******************************************************************************
* 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.c99;
public interface C99Parsersym {
public final static int
TK_auto = 26,
TK_break = 33,
TK_case = 34,
TK_char = 43,
TK_const = 21,
TK_continue = 35,
TK_default = 36,
TK_do = 37,
TK_double = 44,
TK_else = 80,
TK_enum = 56,
TK_extern = 27,
TK_float = 45,
TK_for = 28,
TK_goto = 38,
TK_if = 39,
TK_inline = 29,
TK_int = 46,
TK_long = 47,
TK_register = 30,
TK_restrict = 22,
TK_return = 40,
TK_short = 48,
TK_signed = 49,
TK_sizeof = 12,
TK_static = 24,
TK_struct = 57,
TK_switch = 41,
TK_typedef = 31,
TK_union = 58,
TK_unsigned = 50,
TK_void = 51,
TK_volatile = 23,
TK_while = 32,
TK__Bool = 52,
TK__Complex = 53,
TK__Imaginary = 54,
TK_integer = 13,
TK_floating = 14,
TK_charconst = 15,
TK_stringlit = 16,
TK_identifier = 2,
TK_TypedefName = 19,
TK_Completion = 5,
TK_EndOfCompletion = 3,
TK_Invalid = 94,
TK_LeftBracket = 42,
TK_LeftParen = 1,
TK_LeftBrace = 6,
TK_Dot = 67,
TK_Arrow = 81,
TK_PlusPlus = 10,
TK_MinusMinus = 11,
TK_And = 9,
TK_Star = 4,
TK_Plus = 7,
TK_Minus = 8,
TK_Tilde = 17,
TK_Bang = 18,
TK_Slash = 68,
TK_Percent = 69,
TK_RightShift = 63,
TK_LeftShift = 64,
TK_LT = 70,
TK_GT = 71,
TK_LE = 72,
TK_GE = 73,
TK_EQ = 75,
TK_NE = 76,
TK_Caret = 77,
TK_Or = 78,
TK_AndAnd = 79,
TK_OrOr = 82,
TK_Question = 83,
TK_Colon = 59,
TK_DotDotDot = 65,
TK_Assign = 62,
TK_StarAssign = 84,
TK_SlashAssign = 85,
TK_PercentAssign = 86,
TK_PlusAssign = 87,
TK_MinusAssign = 88,
TK_RightShiftAssign = 89,
TK_LeftShiftAssign = 90,
TK_AndAssign = 91,
TK_CaretAssign = 92,
TK_OrAssign = 93,
TK_Comma = 55,
TK_RightBracket = 66,
TK_RightParen = 61,
TK_RightBrace = 60,
TK_SemiColon = 20,
TK_ERROR_TOKEN = 25,
TK_EOF_TOKEN = 74;
public final static String orderedTerminalSymbols[] = {
"",
"LeftParen",
"identifier",
"EndOfCompletion",
"Star",
"Completion",
"LeftBrace",
"Plus",
"Minus",
"And",
"PlusPlus",
"MinusMinus",
"sizeof",
"integer",
"floating",
"charconst",
"stringlit",
"Tilde",
"Bang",
"TypedefName",
"SemiColon",
"const",
"restrict",
"volatile",
"static",
"ERROR_TOKEN",
"auto",
"extern",
"for",
"inline",
"register",
"typedef",
"while",
"break",
"case",
"continue",
"default",
"do",
"goto",
"if",
"return",
"switch",
"LeftBracket",
"char",
"double",
"float",
"int",
"long",
"short",
"signed",
"unsigned",
"void",
"_Bool",
"_Complex",
"_Imaginary",
"Comma",
"enum",
"struct",
"union",
"Colon",
"RightBrace",
"RightParen",
"Assign",
"RightShift",
"LeftShift",
"DotDotDot",
"RightBracket",
"Dot",
"Slash",
"Percent",
"LT",
"GT",
"LE",
"GE",
"EOF_TOKEN",
"EQ",
"NE",
"Caret",
"Or",
"AndAnd",
"else",
"Arrow",
"OrOr",
"Question",
"StarAssign",
"SlashAssign",
"PercentAssign",
"PlusAssign",
"MinusAssign",
"RightShiftAssign",
"LeftShiftAssign",
"AndAssign",
"CaretAssign",
"OrAssign",
"Invalid"
};
public final static boolean isValidForParser = true;
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
public class C99ArrayType implements ICArrayType, ITypeContainer {
private boolean isConst;
private boolean isRestrict;
private boolean isStatic;
private boolean isVolatile;
private boolean isVariableLength;
private IType type;
public C99ArrayType() {
}
public C99ArrayType(IType type) {
this.type = type;
}
public boolean isConst() {
return isConst;
}
public void setConst(boolean isConst) {
this.isConst = isConst;
}
public boolean isRestrict() {
return isRestrict;
}
public void setRestrict(boolean isRestrict) {
this.isRestrict = isRestrict;
}
public boolean isStatic() {
return isStatic;
}
public void setStatic(boolean isStatic) {
this.isStatic = isStatic;
}
public boolean isVolatile() {
return isVolatile;
}
public void setVolatile(boolean isVolatile) {
this.isVolatile = isVolatile;
}
public boolean isVariableLength() {
return isVariableLength;
}
public void setVariableLength(boolean isVariableLength) {
this.isVariableLength = isVariableLength;
}
public IASTExpression getArraySizeExpression() throws DOMException {
return null;
}
public IType getType() {
return type;
}
public void setType(IType type) {
this.type = type;
}
public boolean isSameType(IType t) {
if(t == this)
return true;
if(t instanceof ITypedef)
return t.isSameType(this);
if(t instanceof ICArrayType) {
ICArrayType at = (ICArrayType)t;
try {
if(at.isConst() == isConst &&
at.isRestrict() == isRestrict &&
at.isStatic() == isStatic &&
at.isVolatile() == isVolatile &&
at.isVariableLength() == isVariableLength) {
return at.isSameType(type);
}
} catch(DOMException _) { }
}
return false;
}
public C99ArrayType clone() {
C99ArrayType clone = null;
try {
clone = (C99ArrayType) super.clone();
clone.type = (IType) type.clone();
} catch (CloneNotSupportedException e) {
assert false; // not going to happen
}
return clone;
}
}

View file

@ -0,0 +1,132 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
public class C99BasicType implements ICBasicType {
/* Type flags given in IBasicType */
private int type;
private boolean isLong;
private boolean isShort;
private boolean isSigned;
private boolean isUnsigned;
private boolean isComplex;
private boolean isImaginary;
private boolean isLongLong;
public C99BasicType() {
}
public C99BasicType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean isLong() {
return isLong;
}
public void setLong(boolean isLong) {
this.isLong = isLong;
}
public boolean isShort() {
return isShort;
}
public void setShort(boolean isShort) {
this.isShort = isShort;
}
public boolean isSigned() {
return isSigned;
}
public void setSigned(boolean isSigned) {
this.isSigned = isSigned;
}
public boolean isUnsigned() {
return isUnsigned;
}
public void setUnsigned(boolean isUnsigned) {
this.isUnsigned = isUnsigned;
}
public boolean isComplex() {
return isComplex;
}
public void setComplex(boolean isComplex) {
this.isComplex = isComplex;
}
public boolean isImaginary() {
return isImaginary;
}
public void setImaginary(boolean isImaginary) {
this.isImaginary = isImaginary;
}
public boolean isLongLong() {
return isLongLong;
}
public void setLongLong(boolean isLongLong) {
this.isLongLong = isLongLong;
}
public IASTExpression getValue() {
return null;
}
public boolean isSameType(IType t) {
if(t == this)
return true;
if(!(t instanceof C99BasicType))
return false;
C99BasicType bt = (C99BasicType) t;
return bt.type == this.type &&
bt.isLong == this.isLong &&
bt.isShort == this.isShort &&
bt.isSigned == this.isSigned &&
bt.isUnsigned == this.isUnsigned &&
bt.isComplex == this.isComplex &&
bt.isImaginary == this.isImaginary &&
bt.isLongLong == this.isLongLong;
}
public C99BasicType clone() {
try {
return (C99BasicType) super.clone();
} catch (CloneNotSupportedException e) {
assert false;
return null;
}
}
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
public class C99CompositeTypeScope extends C99Scope implements ICCompositeTypeScope {
private ICompositeType struct;
public C99CompositeTypeScope(ICompositeType struct) {
this.struct = struct;
}
public ICompositeType getCompositeType() {
return struct;
}
public IBinding getBinding(char[] name) throws DOMException {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,105 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class C99Enumeration extends PlatformObject implements IC99Binding, IEnumeration, ITypeable {
private List<IEnumerator> enumerators = new ArrayList<IEnumerator>();
private String name;
private IScope scope;
public C99Enumeration() {
}
public C99Enumeration(String name) {
this.name = name;
}
public void addEnumerator(IEnumerator e) {
enumerators.add(e);
}
public IEnumerator[] getEnumerators() {
return enumerators.toArray(new IEnumerator[enumerators.size()]);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public char[] getNameCharArray() {
return name.toCharArray();
}
public IType getType() {
return this;
}
public boolean isSameType(IType type) {
if( type == this )
return true;
if( type instanceof ITypedef)
return type.isSameType( this );
return false;
}
public C99Enumeration clone() {
try {
C99Enumeration clone = (C99Enumeration) super.clone();
clone.enumerators = new ArrayList<IEnumerator>();
for(IEnumerator e : enumerators) {
// TODO this is wrong,
// IEnumerator is not Cloneable so we are not returning a deep copy here
clone.addEnumerator(e);
}
return clone;
} catch (CloneNotSupportedException e1) {
assert false;
return null;
}
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public IScope getScope() {
return scope;
}
public void setScope(IScope scope) {
this.scope = scope;
}
}

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class C99Enumerator extends PlatformObject implements IC99Binding, IEnumerator, ITypeable {
private String name;
private IType type;
private IScope scope;
public C99Enumerator() {
}
public C99Enumerator(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IType getType() {
return type;
}
public void setType(IType type) {
this.type = type;
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public char[] getNameCharArray() {
return name.toCharArray();
}
public IScope getScope() {
return scope;
}
public void setScope(IScope scope) {
this.scope = scope;
}
}

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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
public class C99Field extends C99Variable implements IC99Binding, IField, ITypeable {
private ICompositeType compositeTypeOwner;
public C99Field() {
}
public C99Field(String name) {
super(name);
}
public ICompositeType getCompositeTypeOwner() {
return compositeTypeOwner;
}
public void setCompositeTypeOwner(ICompositeType compositeTypeOwner) {
this.compositeTypeOwner = compositeTypeOwner;
}
public IScope getScope() {
try {
return compositeTypeOwner.getCompositeScope();
} catch (DOMException e) {
return null; // should never happen
}
}
}

View file

@ -0,0 +1,152 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class C99Function extends PlatformObject implements IC99Binding, IFunction, ITypeable {
private String name;
private IFunctionType type;
private List<IParameter> parameters = new ArrayList<IParameter>();
private boolean isAuto;
private boolean isExtern;
private boolean isInline;
private boolean isRegister;
private boolean isStatic;
private boolean isVarArgs;
// the scope that the function is in (must be the global scope, no?)
private IScope scope;
// the scope that represents the body of the function
private IScope bodyScope;
public C99Function() {
}
public C99Function(String name) {
this.name = name;
}
public C99Function(String name, IFunctionType type) {
this(name);
this.type = type;
}
public IParameter[] getParameters() {
return parameters.toArray(new IParameter[parameters.size()]);
}
public void addParameter(IParameter parameter) {
parameters.add(parameter);
}
public IFunctionType getType() {
return type;
}
public void setType(IFunctionType type) {
this.type = type;
}
public boolean isAuto() {
return isAuto;
}
public void setAuto(boolean isAuto) {
this.isAuto = isAuto;
}
public boolean isExtern() {
return isExtern;
}
public void setExtern(boolean isExtern) {
this.isExtern = isExtern;
}
public boolean isInline() {
return isInline;
}
public void setInline(boolean isInline) {
this.isInline = isInline;
}
public boolean isRegister() {
return isRegister;
}
public void setRegister(boolean isRegister) {
this.isRegister = isRegister;
}
public boolean isStatic() {
return isStatic;
}
public void setStatic(boolean isStatic) {
this.isStatic = isStatic;
}
public boolean takesVarArgs() {
return isVarArgs;
}
public void setTakesVarArgs(boolean isVarArgs) {
this.isVarArgs = isVarArgs;
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public char[] getNameCharArray() {
return name.toCharArray();
}
public IScope getScope() {
return scope;
}
public IScope getFunctionScope() {
return bodyScope;
}
public void setFunctionScope(IScope bodyScope) {
this.bodyScope = bodyScope;
}
public void setScope(IScope scope) {
this.scope = scope;
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
public class C99FunctionScope extends C99Scope implements ICFunctionScope {
/**
* Scope that represents the compound statement of the body of this scope.
* Does not include the parameters which are part of this function scope.
*/
private IScope bodyScope;
public IBinding getBinding(char[] name) throws DOMException {
// TODO Auto-generated method stub
return null;
}
public void setBodyScope(IScope bodyScope) {
this.bodyScope = bodyScope;
}
public IScope getBodyScope() throws DOMException {
return bodyScope;
}
}

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
public class C99FunctionType implements IFunctionType {
private IType returnType;
private List<IType> parameterTypes = new ArrayList<IType>();
public IType[] getParameterTypes() {
return parameterTypes.toArray(new IType[parameterTypes.size()]);
}
public void addParameterType(IType parameterType) {
parameterTypes.add(parameterType);
}
public IType getReturnType() {
return returnType;
}
public void setReturnType(IType returnType) {
this.returnType = returnType;
}
public boolean isSameType(IType type) {
// TODO Auto-generated method stub
return false;
}
public C99FunctionType clone() {
try {
C99FunctionType clone = (C99FunctionType) super.clone();
clone.setReturnType((IType)returnType.clone());
clone.parameterTypes = new ArrayList<IType>();
for(IType parameterType : parameterTypes) {
clone.addParameterType((IType)parameterType.clone());
}
return clone;
} catch (CloneNotSupportedException e) {
assert false;
return null;
}
}
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.ILabel;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class C99Label extends PlatformObject implements IC99Binding, ILabel {
private String name;
private IScope scope;
public C99Label() {
}
public C99Label(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public char[] getNameCharArray() {
return name.toCharArray();
}
public IASTLabelStatement getLabelStatement() {
return null;
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public IScope getScope() {
return scope;
}
public void setScope(IScope scope) {
this.scope = scope;
}
}

Some files were not shown because too many files have changed in this diff Show more