diff options
Diffstat (limited to 'bnf/main.cpp')
-rw-r--r-- | bnf/main.cpp | 155 |
1 files changed, 94 insertions, 61 deletions
diff --git a/bnf/main.cpp b/bnf/main.cpp index f88eb21f..020ff0f6 100644 --- a/bnf/main.cpp +++ b/bnf/main.cpp @@ -1,52 +1,56 @@ #include <stdio.h> #include <string.h> +#include <iostream> #include "lex.hpp" +#include "common.hpp" extern FILE* yyin; ::std::string get_dir_path(const ::std::string& input) { auto pos = input.rfind("/"); if( pos == ::std::string::npos) { - return ""; + return "./"; } else { return ::std::string( input, 0, input.rfind("/") + 1 ); } } -int main(int argc, char *argv[]) { - const char *base_filename; - if(argc < 2 || strcmp(argv[1], "-") == 0) { - yyin = stdin; - base_filename = "-"; - } - else { - base_filename = argv[1]; - yyin = fopen(argv[1], "r"); +::std::unique_ptr<Module> parse_module_file(::std::string filename, ::std::string base_path) +{ + ::std::cout << "filename = " << filename << ", base_path = " << base_path << ";" << ::std::endl; + + if( filename != "-" ) { + yyin = fopen(filename.c_str(), "r"); if( !yyin ) { - fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", argv[1], strerror(errno)); - return 1; + fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", filename.c_str(), strerror(errno)); + exit(1); } } - yylineno = 1; - yydebug = (getenv("BNFDEBUG") != NULL); - - ParserContext context(base_filename); - if( context.filename != "-" ) { - context.base_path = get_dir_path(context.filename); - } + ParserContext context( ::std::move(filename) ); + context.base_path = ::std::move(base_path); + + yylineno = 1; int rv = yyparse(context); - fclose(yyin); + if( yyin != stdin ) { + fclose(yyin); + } if( rv != 0 ) { - return rv; + exit(1); } - + assert( context.output_module.get() ); - auto& mod = *context.output_module; - printf("output module = %p\n", &mod); + //context.output_module->set_paths( ::std::move(context.filename), ::std::move(context.base_path) ); + return ::std::move(context.output_module); +} + +void post_process_module(Module& mod, const ::std::string& mod_filename, const ::std::string& mod_dir_path) +{ + ::std::cout << "mod = ["<<mod.mod_path()<<"], mod_filename = " << mod_filename << ", mod_dir_path = " << mod_dir_path << ";" << ::std::endl; - for(auto& item : mod.items()) { + for(auto& item : mod.items()) + { Module* opt_submod = dynamic_cast<Module*>(item.get()); if( !opt_submod ) continue; Module& submod = *opt_submod; @@ -54,49 +58,78 @@ int main(int argc, char *argv[]) { if( ! submod.is_external() ) { // - inline modules can be ignored.. for now - continue ; - } - ::std::string filename; - ::std::string base_path; - if( context.filename == "-" ) { - return 1; - } - else if( submod.attrs().has("path") ) { - filename = get_dir_path(context.filename) + submod.attrs().get_first("path").string(); - base_path = get_dir_path(filename); - } - else if( context.base_path == "" ) { - return 1; + if( mod_dir_path != "" ) { + submod.set_paths( mod_filename, mod_dir_path + submod.name() + "/" ); + } } - else { - filename = context.base_path + submod.name() + ".rs"; - base_path = ""; - yyin = fopen( filename.c_str(), "r" ); - if( !yyin ) { - printf("> '%s' not found\n", filename.c_str()); - base_path = context.base_path + submod.name() + "/"; - filename = base_path + "mod.rs"; + else + { + ::std::string filename; + ::std::string base_path; + if( mod_filename == "-" ) { + fprintf(stderr, "ERROR: Referencing 'mod %s;' from stdin\n", submod.name().c_str()); + exit(1); + } + else if( submod.attrs().has("path") ) { + filename = get_dir_path(mod_filename) + submod.attrs().get_first("path").string(); + base_path = get_dir_path(filename); + } + else if( mod_dir_path == "" ) { + fprintf(stderr, "ERROR: Referencing 'mod %s;' from non-controlling file\n", submod.name().c_str()); + exit(1); } else { - fclose(yyin); + filename = mod_dir_path + submod.name() + ".rs"; + base_path = ""; + yyin = fopen( filename.c_str(), "r" ); + if( !yyin ) { + printf("> '%s' not found\n", filename.c_str()); + base_path = mod_dir_path + submod.name() + "/"; + filename = base_path + "mod.rs"; + } + else { + fclose(yyin); + } } - } - assert(filename.size() > 0); - yyin = fopen( filename.c_str(), "r" ); - if( !yyin ) { - printf("> '%s' not found\n", filename.c_str()); - return 1; + + assert(filename.size() > 0); + submod = ::std::move( *parse_module_file(filename, base_path) ); + submod.set_paths( filename, base_path ); } - ParserContext new_context(filename); - yylineno = 1; - int rv = yyparse(new_context); - fclose(yyin); - if( rv != 0 ) { - return rv; - } - submod = ::std::move( *new_context.output_module ); + auto mp = mod.mod_path(); + mp.push_back(submod.name()); + submod.set_mod_path(::std::move(mp)); + } + + for(auto& item : mod.items()) + { + Module* opt_submod = dynamic_cast<Module*>(item.get()); + if( !opt_submod ) continue; + Module& submod = *opt_submod; + + const ::std::string& submod_fname = submod.filename(); + const ::std::string& submod_dir = submod.base_dir(); + post_process_module(submod, submod_fname, submod_dir); + } +} + +int main(int argc, char *argv[]) { + ::std::string base_filename; + if(argc < 2 || strcmp(argv[1], "-") == 0) { + yyin = stdin; + base_filename = "-"; } + else { + base_filename = argv[1]; + } + yydebug = (getenv("BNFDEBUG") != NULL); + + ::std::string base_path = (base_filename == "-" ? ::std::string("") : get_dir_path(base_filename)); + auto mod = parse_module_file(base_filename, base_path); + printf("output module = %p\n", &*mod); + + post_process_module(*mod, base_filename, base_path); return 0; } |