00001 #include "sdag/constructs/Constructs.h"
00002 #include "xi-symbol.h"
00003 #include "xi-util.h"
00004 #include <cstdio>
00005 #include <cstdlib>
00006 #include <fstream>
00007 #include <iostream>
00008 #include <list>
00009 #include <string>
00010 #include <vector>
00011
00012 using std::cout;
00013 using std::endl;
00014
00015 extern FILE* yyin;
00016 extern void yyrestart(FILE* input_file);
00017 extern int yyparse(void);
00018 extern void yyerror(const char*);
00019 extern int yylex(void);
00020 extern void scan_string(const char*);
00021
00022 extern xi::AstChildren<xi::Module>* modlist;
00023 extern xi::rwentry rwtable[];
00024
00025 using namespace xi;
00026 #include "xi-grammar.tab.h"
00027
00028 namespace xi {
00029
00030 std::vector<std::string> inputBuffer;
00031
00032 int fortranMode, internalMode;
00033 const char* cur_file;
00034
00035 char *fname, *origFile;
00036
00037 void ReservedWord(int token, int fCol, int lCol) {
00038 char text[300];
00039 const char* word = 0;
00040 for (int i = 0; rwtable[i].tok != 0; ++i) {
00041 if (rwtable[i].tok == token) {
00042 word = rwtable[i].res;
00043 break;
00044 }
00045 }
00046 sprintf(text, "Reserved word '%s' used as an identifier", word);
00047 xi::pretty_msg("error", text, fCol, lCol);
00048 yyerror(text);
00049 }
00050
00051
00052 class MacroDefinition {
00053 private:
00054 char* key;
00055 char* val;
00056
00057 public:
00058 MacroDefinition() : key(NULL), val(NULL) {}
00059 MacroDefinition(char* k, char* v) : key(k), val(v) {}
00060 explicit MacroDefinition(char* str) {
00061
00062 char* equal = strchr(str, '=');
00063 if (equal) {
00064 *equal = 0;
00065 key = str;
00066 val = equal + 1;
00067 } else {
00068 key = str;
00069 val = const_cast<char*>("");
00070 }
00071 }
00072 char* match(const char* k) {
00073 if (!strcmp(k, key)) {
00074 return val;
00075 } else {
00076 return NULL;
00077 }
00078 }
00079 };
00080
00081 static std::list<MacroDefinition*> macros;
00082
00083 int macroDefined(const char* str, int istrue) {
00084 std::list<MacroDefinition*>::iterator def;
00085 for (def = macros.begin(); def != macros.end(); ++def) {
00086 char* val = (*def)->match(str);
00087 if (val) {
00088 if (!istrue) {
00089 return 1;
00090 } else {
00091 return atoi(val);
00092 }
00093 }
00094 }
00095 return 0;
00096 }
00097
00098
00099
00100
00101 void splitScopedName(const char* name, const char** scope, const char** basename) {
00102 const char* scopeEnd = strrchr(name, ':');
00103 if (!scopeEnd) {
00104 *scope = NULL;
00105 *basename = name;
00106 return;
00107 }
00108 *basename = scopeEnd + 1;
00109 int len = scopeEnd - name + 1;
00110 char* tmp = new char[len + 1];
00111 strncpy(tmp, name, len);
00112 tmp[len] = 0;
00113 *scope = tmp;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 std::string readFile(const char* interfaceFile) {
00150
00151
00152 std::istream* in;
00153 std::string buffer;
00154 if (interfaceFile) {
00155 cur_file = interfaceFile;
00156 in = new std::ifstream(interfaceFile);
00157 if(in->fail()) {
00158 cout << "Error: failed to open input file '" << interfaceFile << "'." << endl;
00159 exit(1);
00160 }
00161 } else {
00162 cur_file = (origFile != NULL) ? origFile : "STDIN";
00163 in = &std::cin;
00164 }
00165
00166 std::string line;
00167 while (std::getline(*in, line)) {
00168 buffer += line + "\n";
00169 inputBuffer.push_back(line);
00170 }
00171
00172 if (interfaceFile) delete in;
00173
00174 return buffer;
00175 }
00176
00177 AstChildren<Module>* Parse(std::string& str) {
00178 modlist = NULL;
00179 scan_string(str.c_str());
00180 if (yyparse()) exit(1);
00181 if (num_errors > 0) exit(1);
00182 return modlist;
00183 }
00184
00185 int count_tokens(std::string& str) {
00186 scan_string(str.c_str());
00187 int count = 0;
00188 while (yylex()) count++;
00189 return count;
00190 }
00191
00192 void abortxi(char* name) {
00193 cout << "Usage : " << name
00194 << " [-ansi|-f90|-intrinsic|-D|-M|-count-tokens|-chare-names|-module-names|-orig-file]"
00195 << " module.ci" << endl;
00196 exit(1);
00197 }
00198
00199 }
00200
00201 using namespace xi;
00202
00203 int processAst(xi::AstChildren<xi::Module> *m, const bool chareNames,
00204 const bool dependsMode, const int fortranMode_,
00205 const int internalMode_, char* fname_, char* origFile_) {
00206
00207 fortranMode = fortranMode_;
00208 internalMode = internalMode_;
00209 cur_file = origFile = origFile_;
00210 fname = fname_;
00211
00212 if (!m) return 0;
00213 m->preprocess();
00214 m->check();
00215 if (num_errors != 0) exit(1);
00216
00217 if (chareNames) {
00218 m->printChareNames();
00219 return 0;
00220 }
00221
00222 if (dependsMode) {
00223 std::string ciFileBaseName;
00224 if (fname != NULL) {
00225 ciFileBaseName = fname;
00226 } else if (origFile != NULL) {
00227 ciFileBaseName = origFile;
00228 } else {
00229 abortxi(fname);
00230 }
00231 size_t loc = ciFileBaseName.rfind('/');
00232 if (loc != std::string::npos) ciFileBaseName = ciFileBaseName.substr(loc + 1);
00233 m->recurse(ciFileBaseName.c_str(), &Module::genDepend);
00234 } else {
00235 m->recursev(&Module::generate);
00236 }
00237
00238 return 0;
00239 }
00240
00241 #ifndef XI_LIBRARY
00242 int main(int argc, char* argv[]) {
00243 origFile = NULL;
00244 fname = NULL;
00245 int fortranMode = 0;
00246 int internalMode = 0;
00247 bool dependsMode = false;
00248 bool countTokens = false;
00249 bool chareNames = false;
00250 bool moduleNames = false;
00251
00252 for (int i = 1; i < argc; i++) {
00253 if (*argv[i] == '-') {
00254 if (strcmp(argv[i], "-ansi") == 0) {
00255 } else if (strcmp(argv[i], "-f90") == 0)
00256 fortranMode = 1;
00257 else if (strcmp(argv[i], "-intrinsic") == 0)
00258 internalMode = 1;
00259 else if (strncmp(argv[i], "-D", 2) == 0)
00260 macros.push_back(new MacroDefinition(argv[i] + 2));
00261 else if (strncmp(argv[i], "-M", 2) == 0)
00262 dependsMode = true;
00263 else if (strcmp(argv[i], "-count-tokens") == 0)
00264 countTokens = true;
00265 else if (strcmp(argv[i], "-chare-names") == 0)
00266 chareNames = true;
00267 else if (strcmp(argv[i], "-module-names") == 0)
00268 moduleNames = true;
00269 else if (strcmp(argv[i], "-orig-file") == 0)
00270 origFile = argv[++i];
00271 else
00272 abortxi(argv[0]);
00273 } else {
00274 fname = argv[i];
00275 }
00276 }
00277
00278 std::string buffer = readFile(fname);
00279 sanitizeComments(buffer);
00280 sanitizeStrings(buffer);
00281
00282 if (countTokens) {
00283 cout << count_tokens(buffer) << endl;
00284 return 0;
00285 }
00286
00287 AstChildren<Module>* m = Parse(buffer);
00288
00289 if (moduleNames) {
00290 extern xi::AstChildren<xi::Module>* modlist;
00291 modlist->recursev(&Module::printName);
00292 return 0;
00293 }
00294
00295 return processAst(m, chareNames, dependsMode, fortranMode, internalMode, fname,
00296 origFile);
00297 }
00298 #endif