static gpgme_error_t import_status_handler (void *priv, gpgme_status_code_t code, char *args) { gpgme_ctx_t ctx = (gpgme_ctx_t) priv; gpgme_error_t err; void *hook; op_data_t opd; err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL); opd = hook; if (err) return err; switch (code) { case GPGME_STATUS_IMPORT_OK: case GPGME_STATUS_IMPORT_PROBLEM: err = parse_import (args, opd->lastp, code == GPGME_STATUS_IMPORT_OK ? 0 : 1); if (err) return err; opd->lastp = &(*opd->lastp)->next; break; case GPGME_STATUS_IMPORT_RES: err = parse_import_res (args, &opd->result); break; default: break; } return 0; }
file_contents parse(parse_source source) { file_contents contents; contents.imports = ll_new(); contents.enums = ll_new(); contents.unions = ll_new(); contents.structs = ll_new(); contents.functions = ll_new(); optional op = get_token(&source); while(op_has(op)) { parse_token current = *((parse_token*)op_get(op)); if(equals(current.data, new_slice("struct"))) { struct_declaration *dec = analyze_struct(&source); ll_add_last(contents.structs, dec); } else if(equals(current.data, new_slice("union"))) { struct_declaration *dec = analyze_struct(&source); ll_add_last(contents.unions, dec); } else if(equals(current.data, new_slice("func"))) { func_declaration *func = analyze_func(&source); ll_add_last(contents.functions, func); } else if(equals(current.data, new_slice("import"))) { import_declaration *imp = parse_import(&source); ll_add_last(contents.imports, imp); } else if(equals(current.data, new_slice("enum"))) { enum_declaration *enm = parse_enum(&source); ll_add_last(contents.enums, enm); }//TODO: Throw an error for an unexpected token op = get_token(&source); } return contents; }
// Parses a list of import statements at the top of a file. void parse_imports(Parser *parser) { Lexer *lexer = parser->lexer; // Continually parse import statements while (lexer->token == TOKEN_IMPORT) { // Consume the `import` lexer_next(lexer); // Parse the rest of the import parse_import(parser); } }
void FidlParser::add_root_object(ast::ASTNode* object) { if (ast::Package* package = dynamic_cast<ast::Package*>(object)) { root_node_->add_child(object); set_current_package(package); } else if (ast::ImportDecl* import = dynamic_cast<ast::ImportDecl*>(object)) { current_package()->add_child(object); ast::StringConstant const* filename = dynamic_cast<ast::StringConstant const*>(&(import->filename())); assert(filename); parse_import(filename->value()); } else { current_package()->add_child(object); } }
module * module_parser::parse(const module_source & source, istream & text_stream) { if (verbose<module_parser>::enabled()) cout << "Parsing " << source.path << endl; ast::node_ptr ast; { stream::parsing::driver parser(text_stream, cout, source); int error = parser.parse(); if (error) throw parser_error(); ast = parser.ast(); if (verbose<ast::output>::enabled()) { cout << endl << "## AST for file " << source.path << " ##" << endl; ast::printer p; p.print(ast.get()); cout << endl; } } auto & elems = ast->as_list()->elements; string mod_name; if (elems[0]) mod_name = elems[0]->as_leaf<string>()->value; else mod_name = "m"; #if 0 if (m_named_modules.find(mod_name) != m_named_modules.end()) { ostringstream msg; msg << "Module " << mod_name << " is already imported."; throw io_error(msg.str()); } #endif if (verbose<module_parser>::enabled()) cout << "Module name = " << mod_name << endl; auto mod = new module; mod->source = source; mod->name = mod_name; mod->ast = ast; m_named_modules.emplace(mod_name, mod); unordered_map<string, module*> imported_mods; auto imports_node = elems[1]; if (imports_node) { for (auto & import_node : imports_node->as_list()->elements) { auto import_decl = parse_import(mod, import_node); imported_mods.insert(import_decl); } } mod->imports = imported_mods; m_ordered_modules.push_back(mod); if (verbose<module_parser>::enabled()) cout << "Done parsing " << source.path << endl; return mod; }