mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
initial commit of new C99 and C++ parsers (work in progress)
This commit is contained in:
parent
6c58a96029
commit
17f8a38f4e
116 changed files with 31235 additions and 0 deletions
7
lrparser/org.eclipse.cdt.core.lrparser.tests/.classpath
Normal file
7
lrparser/org.eclipse.cdt.core.lrparser.tests/.classpath
Normal 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>
|
28
lrparser/org.eclipse.cdt.core.lrparser.tests/.project
Normal file
28
lrparser/org.eclipse.cdt.core.lrparser.tests/.project
Normal 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>
|
|
@ -0,0 +1,3 @@
|
||||||
|
#Fri Oct 05 11:17:36 EDT 2007
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
internal.default.compliance=default
|
|
@ -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
|
24
lrparser/org.eclipse.cdt.core.lrparser.tests/about.html
Normal file
24
lrparser/org.eclipse.cdt.core.lrparser.tests/about.html
Normal 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>
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 _) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 _) { }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -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$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 _) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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$
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -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 _) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 _) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 _) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
7
lrparser/org.eclipse.cdt.core.lrparser/.classpath
Normal file
7
lrparser/org.eclipse.cdt.core.lrparser/.classpath
Normal 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>
|
34
lrparser/org.eclipse.cdt.core.lrparser/.project
Normal file
34
lrparser/org.eclipse.cdt.core.lrparser/.project
Normal 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>
|
|
@ -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
|
17
lrparser/org.eclipse.cdt.core.lrparser/META-INF/MANIFEST.MF
Normal file
17
lrparser/org.eclipse.cdt.core.lrparser/META-INF/MANIFEST.MF
Normal 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
|
24
lrparser/org.eclipse.cdt.core.lrparser/about.html
Normal file
24
lrparser/org.eclipse.cdt.core.lrparser/about.html
Normal 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>
|
24
lrparser/org.eclipse.cdt.core.lrparser/about.ini
Normal file
24
lrparser/org.eclipse.cdt.core.lrparser/about.ini
Normal 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
|
9
lrparser/org.eclipse.cdt.core.lrparser/about.mappings
Normal file
9
lrparser/org.eclipse.cdt.core.lrparser/about.mappings
Normal 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@
|
25
lrparser/org.eclipse.cdt.core.lrparser/about.properties
Normal file
25
lrparser/org.eclipse.cdt.core.lrparser/about.properties
Normal 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
|
21
lrparser/org.eclipse.cdt.core.lrparser/build.properties
Normal file
21
lrparser/org.eclipse.cdt.core.lrparser/build.properties
Normal 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
|
BIN
lrparser/org.eclipse.cdt.core.lrparser/eclipse32.gif
Normal file
BIN
lrparser/org.eclipse.cdt.core.lrparser/eclipse32.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
18
lrparser/org.eclipse.cdt.core.lrparser/plugin.properties
Normal file
18
lrparser/org.eclipse.cdt.core.lrparser/plugin.properties
Normal 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++
|
28
lrparser/org.eclipse.cdt.core.lrparser/plugin.xml
Normal file
28
lrparser/org.eclipse.cdt.core.lrparser/plugin.xml
Normal 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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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();
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -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("]");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
--
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
Loading…
Add table
Reference in a new issue