Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

GrammarManager.cpp

Go to the documentation of this file.
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 //  Standard Member Functions
00014 //
00016 
00017 GrammarManager::GrammarManager()
00018 {
00019     // blank default    
00020 }
00021 
00022 #if 0  /* omit definitions until they are implemented */
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 /* omit definitions until they are implemented */
00055     
00056 GrammarManager::~GrammarManager()
00057 {
00058     // blank default    
00059 }
00060 
00062 //
00063 //  Additional Public Member Functions
00064 //
00066 
00067 Parser* GrammarManager::obtainParser(std::string name)
00068 {
00069     //
00070     // prepare input stream & parse it
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     // write grammar to the file
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     // call compiler
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     // dynamicly load generated code
00125     //
00126     // (alternatively, we could run it on a pipe, or
00127     // have generated the tables in our own memory.)
00128     //
00129     putenv("LD_LIBRARY=.");    /* or LD_LIBRARY_PATH? */
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     // should we look for both C and C++ versions?  nah, we compiled it.
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     // ISO C++ doesn't seem to allow this, even with reinterpret_cast ?!
00149     // so I do it this way:
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 //  Additional Private Member Functions
00164 //
00166 
00167 #undef TRACE_NAME

Home to blindfold. This page generated via doxygen 1.2.11.1 Wed Oct 10 16:40:33 2001.