blob: 66f5cbeb364122bae719e5264dc283411cd97cc2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.lrparser.symboltable;
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
*/
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;
}
@Override
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();
// }
}