00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2008 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: SymbolTable.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.58 $ $Date: 2008/03/27 19:36:46 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Stores the functions available to get info from a molecule 00019 * Calls the atom selection parser to create a parse tree 00020 * 00021 ***************************************************************************/ 00022 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include "SymbolTable.h" 00028 #include "AtomSel.h" 00029 #include "Inform.h" 00030 #include "ParseTree.h" 00031 00032 SymbolTable::~SymbolTable(void) { 00033 int num, i; 00034 00035 num = fctns.num(); 00036 for (i=0; i<num; i++) 00037 delete fctns.data(i); 00038 00039 num = custom_singlewords.num(); 00040 for (i=0; i<num; i++) 00041 delete [] custom_singlewords.data(i); 00042 } 00043 00044 00045 // is the given element changable? Returns TRUE on yes, FALSE on no 00046 int SymbolTable::is_changeable( int fctnidx) { 00047 if (!(fctnidx >= 0 && fctnidx < fctns.num())) 00048 return FALSE; 00049 00050 SymbolTableElement *fctn=fctns.data(fctnidx); 00051 if (fctn->set_fctn) 00052 return TRUE; 00053 00054 return FALSE; 00055 } 00056 00057 int SymbolTable::num_custom_singleword() { 00058 return custom_singlewords.num(); 00059 } 00060 00061 const char *SymbolTable::custom_singleword_name(int i) { 00062 return custom_singlewords.name(i); 00063 } 00064 00065 int SymbolTable::add_custom_singleword(const char *name, const char *macro) { 00066 // Check if the macro already exists as a "hardwired" singleword. If so, 00067 // return failure. 00068 if (find_attribute(name) >= 0 && custom_singlewords.typecode(name) < 0) { 00069 msgErr << "Macro '" << name << "' cannot be redefined." << sendmsg; 00070 return 0; 00071 } 00072 // Check for recursion 00073 ParseTree *tree = parse(macro); 00074 if (!tree) { 00075 msgErr << "Macro '" << macro << "' cannot be parsed." << sendmsg; 00076 return 0; 00077 } 00078 if (tree->find_recursion(name)) { 00079 msgErr << "Macro definition'" << name << "' => '" << macro << "' contains itself." << sendmsg; 00080 delete tree; 00081 return 0; 00082 } 00083 delete tree; 00084 00085 // add the name with the given macro. 00086 // if the macro already exists, overwrite it with the new one 00087 int ind = custom_singlewords.typecode(name); 00088 if (ind < 0) { 00089 ind = custom_singlewords.add_name(name, stringdup(macro)); 00090 } else { 00091 delete [] custom_singlewords.data(ind); 00092 custom_singlewords.set_data(ind, stringdup(macro)); 00093 } 00094 00095 // get cached copy of the name 00096 const char *my_name = custom_singlewords.name(ind); 00097 add_singleword(my_name, atomsel_custom_singleword, NULL); 00098 00099 return 1; 00100 } 00101 00102 const char *SymbolTable::get_custom_singleword(const char *name) { 00103 int ind = custom_singlewords.typecode(name); 00104 if (ind < 0) return NULL; 00105 return custom_singlewords.data(ind); 00106 } 00107 00108 int SymbolTable::remove_custom_singleword(const char *name) { 00109 // remove from list of custom singlewords by changing the name to "" 00110 int ind = custom_singlewords.typecode(name); 00111 if (ind < 0) return 0; 00112 custom_singlewords.set_name(ind, ""); 00113 00114 // get the index in the tables of names and functions 00115 ind = find_attribute(name); 00116 if (ind < 0) return 0; // XXX this had better not happen 00117 fctns.set_name(ind, ""); 00118 return 1; 00119 } 00120 00121 #if defined(_MSC_VER) 00122 extern int yyparse(void); 00123 #else 00124 extern "C" int yyparse(); 00125 #endif 00126 00127 ParseTree *SymbolTable::parse(const char *s) { 00128 char *temps = strdup(s); 00129 atomparser_yystring = temps; 00130 atomparser_symbols = this; 00131 yyparse(); 00132 free(temps); 00133 if (atomparser_result) 00134 return new ParseTree(this, atomparser_result); 00135 return NULL; 00136 } 00137
1.2.14 written by Dimitri van Heesch,
© 1997-2002