00001 #define TRACE_NAME "GrammarManager"
00002 extern "C" {
00003 #include <stdio.h>
00004 #include <dlfcn.h>
00005 #include "ebnf.h"
00006 #include "abstract_grammar.h"
00007 }
00008 #include "GrammarManager.h"
00009 #include "YaccGeneratedParser.h"
00010
00012
00013
00014
00016
00017 GrammarManager::GrammarManager()
00018 {
00019
00020 }
00021
00022 #if 0
00023
00024 GrammarManager::GrammarManager(const GrammarManager& other)
00025 {
00026 NOT_IMPLEMENTED
00027 }
00028
00029 const GrammarManager& GrammarManager::operator=(const GrammarManager& other)
00030 {
00031 NOT_IMPLEMENTED
00032 }
00033
00034 bool GrammarManager::operator==(const GrammarManager& other) const
00035 {
00036 NOT_IMPLEMENTED
00037 }
00038
00039 bool GrammarManager::operator<(const GrammarManager& other) const
00040 {
00041 NOT_IMPLEMENTED
00042 }
00043
00044 size_t GrammarManager::hash() const
00045 {
00046 NOT_IMPLEMENTED
00047 }
00048
00049 std::ostream& GrammarManager::print_to(std::ostream& stream) const
00050 {
00051 NOT_IMPLEMENTED
00052 }
00053
00054 #endif
00055
00056 GrammarManager::~GrammarManager()
00057 {
00058
00059 }
00060
00062
00063
00064
00066
00067 Parser* GrammarManager::obtainParser(std::string name)
00068 {
00069
00070
00071
00072 std::string::size_type pos = name.find(':');
00073 std::string scheme;
00074 std::string rest;
00075 if (pos == std::string::npos) {
00076 scheme = "file";
00077 rest = name;
00078 } else {
00079 scheme = name.substr((unsigned) 0,pos-1);
00080 rest = name.substr(pos+1);
00081 }
00082
00083 Grammar* grammar = 0;
00084 if (scheme == "file") {
00085 NOT_IMPLEMENTED;
00086 grammar = parse_file(rest.c_str());
00087 } else {
00088 die("Only 'file:' URIs are currently implemented.");
00089 }
00090
00091 #if 0
00092
00093
00094
00095 char *grammar_file = tempnam(0, "bnf.");
00096 if (!grammar_file) die("can't generate unique filename");
00097 FILE *f = fopen(grammar_file, "w");
00098 if (!f) { perror(grammar_file); die("can't open temp file"); }
00099 print_grammar(f, grammar);
00100 fclose(f);
00101
00102
00103
00104
00105 std::string command;
00106 std::string library_file = grammar_file;
00107 library_file.append(".so");
00108
00109 char *prog = getenv("BLINDFOLD_GRAMMAR_COMPILER");
00110 if (prog) {
00111 command.append(prog);
00112 } else {
00113 command.append("blindfold_grammar_compiler");
00114 }
00115 command.append(" ");
00116 command.append(grammar_file);
00117 command.append(" ");
00118 command.append(library_file);
00119
00120 int rc = system(command.c_str());
00121 if (rc != 0) die("grammar compiler failed.");
00122
00123
00124
00125
00126
00127
00128
00129 putenv("LD_LIBRARY=.");
00130 void* lib = dlopen(library_file.c_str(), RTLD_NOW);
00131 if (!lib) {
00132 fprintf(stderr, "Error loading newly-compiled parser:\n ");
00133 fputs (dlerror(), stderr);
00134 fputs("\n", stderr);
00135 exit(1);
00136 }
00137
00138
00139 void* entry_point = dlsym(lib, "generated_parser__FP17TripleSinkReifierPc");
00140 char *error;
00141 if ((error = dlerror()) != NULL) {
00142 fprintf(stderr, "Error linking with newly-compiled parser:\n ");
00143 fputs(error, stderr);
00144 fputs("\n", stderr);
00145 exit(1);
00146 }
00147
00148
00149
00150 parse_function ep = (parse_function) entry_point;
00151
00152 std::cerr << "New parser generated, compiled, and loaded.\n";
00153 std::cerr.flush();
00154
00155 return new YaccGeneratedParser(ep);
00156 #else
00157 return 0;
00158 #endif
00159 }
00160
00162
00163
00164
00166
00167 #undef TRACE_NAME