All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.formcalc.SymbolTable Maven / Gradle / Ivy

The newest version!
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2007 Adobe Systems Incorporated All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Adobe Systems Incorporated and its suppliers, if any. The intellectual and
 * technical concepts contained herein are proprietary to Adobe Systems
 * Incorporated and its suppliers and may be covered by U.S. and Foreign
 * Patents, patents in process, and are protected by trade secret or copyright
 * law. Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained from
 * Adobe Systems Incorporated.
 */
package com.adobe.xfa.formcalc;


import java.util.List;


/**
 * Class SymbolTable defines the symbol table used by the
 * FormCalc scripting engine.
 * The FormCalc parser in fact, maintains two symbols tables: one
 * for all built-in functions and a separate one for variables,
 * parameters and functions.
 * 
 * 

The symbol table for built-ins is quite static in size, but its * contents can span several invocations of yyparse(). Conversely, the * symbol table for variables, parameters and functions needs to grow * to as many variables, parameters and functions as are defined in the * FormCalc script, and needs to contract its contents before each * invocation of yyparse(). * * @author Paul Imerson, Mike P. Tardif * * @exclude from published api. */ public final class SymbolTable { static final int SIZE = 509; // size must be prime! /** * Instantiates a SymbolTable object. */ SymbolTable() { // empty } /** * Creates storage for this object. * * @param nTableSize a size for this object' s hash table. * This defines the number of buckets in the hash table. For optimal * results this number should be prime, and sufficiently large to avoid * collisions. * @return integer 1 upon success, and 0 otherwise. */ int create(int nTableSize /* = SIZE */) { mnTableSize = nTableSize; moTableBase = new CalcSymbol[nTableSize]; return 1; } /** * Gets this object's current table size. * * @return the current table size. */ int getTableSize() { return mnTableSize; } /** * (Re-)Initializes this object. Depending upon type * and other attributes, unneeded symbols in the table are deleted. * * @param bSaveMode the save state. */ void init(CalcParser oParser) { for (int i = 0; i < mnTableSize; i++) { CalcSymbol prev = null; CalcSymbol next = null; for (CalcSymbol p = moTableBase[i]; p != null; p = next) { next = p.getNext(); int store = p.getStore(); if ((store & CalcSymbol.StorePrelim) == CalcSymbol.StorePrelim) { if (! oParser.mbSyntaxErrorSeen) { store &= ~CalcSymbol.StorePrelim; p.setStore(store); } else { if (p == moTableBase[i]) prev = moTableBase[i] = next; else prev.setNext(next); continue; } } int type = p.getType(); if (p.getStore() == CalcSymbol.StoreFroz || type == CalcSymbol.TypeFunction) { if (! oParser.mbWasInSaveMode) { if (p == moTableBase[i]) prev = moTableBase[i] = next; else prev.setNext(next); continue; } } else if (type == CalcSymbol.TypeVariable || type == CalcSymbol.TypeReference) { if (p.getScope() > 1) { if (p == moTableBase[i]) prev = moTableBase[i] = next; else prev.setNext(next); continue; } else if (! oParser.mbWasInSaveMode) { if (p == moTableBase[i]) prev = moTableBase[i] = next; else prev.setNext(next); continue; } } prev = p; } } } /** * Looks for the given symbol in this object. If found, the * symbol is returned. The search is confined to Function, Parameter * and Builtin-type symbols. * * @param sName the name of the symbol being searched for. * @return the located symbol or null if not found. */ CalcSymbol lookup(String sName) { assert(sName != null); CalcSymbol q = null; int h = hash(sName); for (CalcSymbol p = moTableBase[h]; p != null; p = p.getNext()) { if (sName.equals(p.getName())) { int type = p.getType(); if (type == CalcSymbol.TypeFunction) return p; else if (type == CalcSymbol.TypeBuiltin) return p; else if (type == CalcSymbol.TypeParameter) return p; } } return q; } /** * Looks up the given symbol in this object. If found, the * symbol is returned. Variable-type symbols returned will have the * largest scope of all currently active scopes. * * @param sName the name of the symbol being searched for. * @param oScope the scope of the symbol being searched for. * @return the located symbol or null if not found. */ CalcSymbol lookup(String sName, ScopeTable oScope) { assert(sName != null); CalcSymbol q = null; int h = hash(sName); for (CalcSymbol p = moTableBase[h]; p != null; p = p.getNext()) { if (sName.equals(p.getName())) { int type = p.getType(); if ((type == CalcSymbol.TypeVariable || type == CalcSymbol.TypeReference) && oScope.isActive(p.getScope())) { if (q == null) q = p; else if (p.getScope() > q.getScope()) q = p; } else if (p.getType() == CalcSymbol.TypeParameter) q = p; } } return q; } /** * Looks up an existing the symbol in this object. * The symbol must have the same name, be a variable, and must * have the same scope as the given. Effectively this is * searching for an alias. * * @param oSym the symbol alias being searched for. * @return the located symbol or null if not found. */ CalcSymbol lookup(CalcSymbol oSym) { assert(oSym != null); CalcSymbol q = null; int h = hash(oSym.getName()); for (CalcSymbol p = moTableBase[h]; p != null; p = p.getNext()) { String sName = p.getName(); if (sName != null && sName.equals(oSym.getName())) { int type = p.getType(); if ((type == CalcSymbol.TypeVariable || type == CalcSymbol.TypeReference) && p.getScope() == oSym.getScope()) q = p; } } return q; } /** * Installs the given symbol. A new symbol is created, and added to the * SymbolTable object. * * @param sName the name of the symbol being inserted. * @return the inserted symbol. */ CalcSymbol install(String sName) { assert(sName != null); int h = hash(sName); CalcSymbol p = new CalcSymbol(); p.setName(sName); p.setNext(moTableBase[h]); moTableBase[h] = p; return p; } /** * Enumerates entries in this object. It populates * a list of CalcSymbol pointers to variables, references * and parameters. Symbols are not copied, so they must not * be stored for later use. * * @param oScope the scope of the symbol being searched for. * @param oSymbols the returned list of symbols. */ public void enumerate(ScopeTable oScope, List oSymbols) { for (int h = 0; h < mnTableSize; h++) { for (CalcSymbol p = moTableBase[h]; p != null; p = p.getNext()) { boolean bAdd = false; int type = p.getType(); if ((type == CalcSymbol.TypeVariable || type == CalcSymbol.TypeReference) && oScope.isActive(p.getScope())) { bAdd = true; } else if (p.getType() == CalcSymbol.TypeParameter) bAdd = true; if (bAdd) oSymbols.add(p); } } } /** * Hashes a name. * * @param sName the name being hashed. * @return the hash value. */ private int hash(String sName) { assert(sName != null); int h = 0; for (int i = 0, n = sName.length(); i < n; i++) h = h << 1 ^ sName.charAt(i); h %= mnTableSize; if (h < 0) h = -h; return h; } private CalcSymbol[] moTableBase; // a dynamic array of CalcSymbols private int mnTableSize; // the table size }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy