📄 codegen.cpp.svn-base
字号:
{ fprintf(a, "%s\n", further_indent); fprintf(a, "%svoid accept(Visitor &v) const { v.visit(*this); }\n", further_indent); } if(data.variables.xml_support) { fprintf(a, "%svoid write_xml(std::ostream &os, int step=4, int position=0) const\n", further_indent); fprintf(a, "%s{\n", further_indent); fprintf(a, "%s for (int i = 0; i < position; ++i) os << ' ';\n", further_indent); fprintf(a, "%s os << \"<text kind=\\\"\" << xml_escape(symbol_name()) << \"\\\">\" << xml_escape(text) << \"</text>\";\n", further_indent); fprintf(a, "%s}\n", further_indent); } if(!data.variables.shallow_destructor) { fprintf(a, "%s~Terminal();\n", further_indent); } } else if(m->name=="Nonterminal") { if (data.variables.generate_visitor || !data.variables.shallow_destructor) fprintf(a, "%sNonterminal() : first_child(0) {}\n", further_indent); fprintf(a, "%sbool is_terminal() const { return false; }\n", further_indent); fprintf(a, "%sbool is_nonterminal() const { return true; }\n", further_indent); fprintf(a, "%svirtual int number() const =0;\n", further_indent); if(data.variables.generate_visitor || !data.variables.shallow_destructor) fprintf(a, "\n%sSymbol *first_child;\n", further_indent); if(data.variables.xml_support) { fprintf(a, "%svoid write_xml(std::ostream &os, int step=4, int position=0) const\n", further_indent); fprintf(a, "%s{\n", further_indent); fprintf(a, "%s for (int i=0; i<position; i++) os << ' ';\n", further_indent); fprintf(a, "%s os << \"<\" << symbol_name() << \">\\n\";\n", further_indent); fprintf(a, "%s for (Symbol *s=first_child; s; s=s->next_sibling)\n", further_indent); fprintf(a, "%s {\n", further_indent); fprintf(a, "%s s->write_xml(os, step, position+step);\n", further_indent); fprintf(a, "%s os << \"\\n\";\n", further_indent); fprintf(a, "%s }\n", further_indent); fprintf(a, "%s for (int i=0; i<position; i++) os << ' ';\n", further_indent); fprintf(a, "%s os << \"</\" << symbol_name() << \">\";\n", further_indent); fprintf(a, "%s}\n", further_indent); } if (!data.variables.shallow_destructor) { fprintf(a, "%s~Nonterminal();\n", further_indent); } } else if(m->name=="Creator") { fprintf(a, "%svirtual Nonterminal *object()=0;\n", further_indent); } else if(m->is_abstract) { // fprintf(a, "/* here */\n"); } else if(m->assigned_to.is_terminal()) { fprintf(a, "%sint number() const { return %d; }\n", further_indent, m->assigned_to.terminal_number()); if (data.variables.generate_names || data.variables.generate_verbose_prints) { string name = data.terminals[m->assigned_to.terminal_number()].name; name = unquote(name); fprintf(a, "%sconst char* symbol_name() const { return \"%s\"; }\n", further_indent, name.c_str()); } if(m->assigned_to.terminal_number()==data.error_terminal_number) { fprintf(a, "%s\n", further_indent); fprintf(a, "%sstd::vector<Symbol *> garbage;\n", further_indent); fprintf(a, "%sint error_position;\n", further_indent); } } else if(m->assigned_to.is_nonterminal() && (m->nonterminal_class_category==ClassHierarchy::Class::SINGLE || m->nonterminal_class_category==ClassHierarchy::Class::WRAPPER || m->nonterminal_class_category==ClassHierarchy::Class::BASE)) { bool it_is_the_only_class=m->nonterminal_class_category==ClassHierarchy::Class::SINGLE; int nn=m->assigned_to.nonterminal_number(); NonterminalData &nonterminal=data.nonterminals[nn]; fprintf(a, "%sint number() const { return %d; }\n", further_indent, nn); if (data.variables.generate_names || data.variables.generate_verbose_prints) { string name = data.nonterminals[m->assigned_to.nonterminal_number()].name; name = unquote(name); fprintf(a, "%sconst char* symbol_name() const { return \"%s\"; }\n", further_indent, name.c_str()); } if(data.variables.generate_visitor && m->nonterminal_class_category!=ClassHierarchy::Class::BASE) fprintf(a, "%svoid accept(Visitor &v) const { v.visit(*this); }\n", further_indent); if(data.variables.xml_support) { bool start=!m->is_abstract && m->assigned_to.nonterminal_number()==data.start_nonterminal_number; if(start) { fprintf(a, "%svoid write_xml(std::ostream& os, int step=4, int position=0) const\n", further_indent); fprintf(a, "%s{\n", further_indent); fprintf(a, "%s\tos << \"<?xml version=\\\"1.0\\\"?>\\n\";\n", further_indent); fprintf(a, "%s\tNonterminal::write_xml(os, step, position);\n", further_indent); fprintf(a, "%s}\n", further_indent); } } if(nonterminal.category==NonterminalData::CREATOR) { // fprintf(a, "%sNonterminal *object() { return static_cast<Nonterminal *>(n); }\n", further_indent); fprintf(a, "%sNonterminal *object() { return (Nonterminal *)n; }\n", further_indent); } if(m->nonterminal_class_category==ClassHierarchy::Class::BASE) fprintf(a, "%svirtual int alternative_number() const =0;\n", further_indent); else if(m->nonterminal_class_category==ClassHierarchy::Class::WRAPPER) { assert(nonterminal.external_type); // fprintf(a, "%s\n", further_indent); // fprintf(a, "%s%s contents;\n", further_indent, nonterminal.external_type->name.c_str()); // fprintf(a, "%s// [ WRAPPER ]\n", further_indent); } } else if(m->assigned_to.is_nonterminal() && m->nonterminal_class_category==ClassHierarchy::Class::SPECIFIC) { fprintf(a, "%sint alternative_number() const { return %d; }\n", further_indent, m->nonterminal_alternative_number); if(data.variables.generate_visitor) fprintf(a, "%svoid accept(Visitor &v) const { v.visit(*this); }\n", further_indent); } else assert(false);// fprintf(a, "%s// Assigned to %s, nonterminal_class_category=%d\n", further_indent, data.full_symbol_name(m->assigned_to, false).c_str(), m->nonterminal_class_category); if(m->data_members.size() && (!m->assigned_to.is_nonterminal() || m->nonterminal_class_category!=ClassHierarchy::Class::WRAPPER)) { fprintf(a, "%s\n", further_indent); for(int i=0; i<m->data_members.size(); i++) generate_data_member(m->data_members[i], a, further_indent); } if(m->code) fprintf(a, "%s%s\n", further_indent, m->code); fprintf(a, "%s};\n", indent); } else assert(false);}void generate_class_proc(ClassHierarchy::Class *m, FILE *a, const char *indent, int mode, int submode, bool generate_top_class){ assert(submode==1 || submode==2); if((submode==1 && m->assigned_to) || (submode==2 && m->nonterminal_class_category==ClassHierarchy::Class::SPECIFIC)) return; if(generate_top_class) generate_single_class(m, a, indent, mode); for(set<ClassHierarchy::Class *>::const_iterator p=m->descendants.begin(); p!=m->descendants.end(); p++) generate_class_proc(*p, a, indent, mode, submode, true);}void generate_symbol_class_templates(FILE *a, const char *indent){ if(classes.single_iterator) { fprintf(a, "%stemplate<class Body> struct Iterator : Nonterminal\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%s\tstd::vector<Body *> body;\n", indent); fprintf(a, "%s};\n", indent); } if(classes.pair_iterator) { fprintf(a, "%stemplate<class BodyA, class BodyB> struct PairIterator : Nonterminal\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%s\tstd::vector<BodyA *> body_a;\n", indent); fprintf(a, "%s\tstd::vector<BodyB *> body_b;\n", indent); fprintf(a, "%s};\n", indent); } if(classes.wrapper) { fprintf(a, "%stemplate<class T> struct Wrapper : Nonterminal\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%s\tT x;\n", indent); fprintf(a, "%s};\n", indent); }#if 0 if(classes.basic_creator) { fprintf(a, "%sstruct BasicCreator : Nonterminal\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%s\tvirtual Nonterminal *object()=0;\n", indent); fprintf(a, "%s};\n", indent); } if(classes.creator) { // assert(classes.basic_creator); // fprintf(a, "%stemplate<class NonterminalType> struct Creator : BasicCreator\n", indent); fprintf(a, "%stemplate<class NonterminalType> struct Creator : Nonterminal\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%s\tNonterminalType *n;\n", indent); // fprintf(a, "%s\t\n", indent); // fprintf(a, "%s\tNonterminal *object() { return n; }\n", indent); fprintf(a, "%s};\n", indent); }#endif}void generate_visit_function(ClassHierarchy::Class *m, FILE *a, const char *indent, int mode){ if(m->nonterminal_class_category!=ClassHierarchy::Class::BASE) { if(mode==1) { if(m->nonterminal_class_category!=ClassHierarchy::Class::BASE) fprintf(a, "%s\tvirtual void visit(const %s &);\n", indent, m->name.c_str()); } else { fprintf(a, "%svoid Visitor::visit(const %s &l)\n", indent, m->name.c_str()); fprintf(a, "%s{\n", indent); if (m->is_derivative_of_nonterminal) fprintf(a, "%s\ttraverse_children(l);\n", indent); fprintf(a, "%s}\n", indent); } }}void generate_classes(FILE *a, const char *indent, int mode){ assert(mode==1 || mode==2); // i. Symbol, Terminal and Nonterminal. // ii. Abstract terminal classes // iii. Terminal classes. // iv. Abstract nonterminal classes. // v. For each nonterminal: base class, then abstract classes, then // alternatives. fprintf(a, "%sstruct Symbol;\n", indent); fprintf(a, "%sstruct Terminal;\n", indent); fprintf(a, "%sstruct Nonterminal;\n", indent); generate_class_proc(classes.terminal, a, indent, mode, 1, false); for(int i=0; i<data.terminals.size(); i++) generate_single_class(data.terminals[i].type, a, indent, mode); fprintf(a, "%s\n", indent); generate_class_proc(classes.nonterminal, a, indent, mode, 1, false); for(int i=0; i<data.nonterminals.size(); i++) { NonterminalData &nonterminal=data.nonterminals[i]; if(!nonterminal.is_ancillary) { generate_class_proc(nonterminal.type, a, indent, mode, 2, true); for(int j=0; j<nonterminal.alternatives.size(); j++) { AlternativeData &alternative=nonterminal.alternatives[j]; if(alternative.type) generate_single_class(alternative.type, a, indent, mode); } } } if(mode==1) { if(data.variables.generate_visitor) { fprintf(a, "%s\n", indent); fprintf(a, "%sclass Visitor\n", indent); fprintf(a, "%s{\n", indent); fprintf(a, "%spublic:\n", indent); generate_visit_function(classes.terminal, a, indent, 1); generate_visit_function(classes.nonterminal, a, indent, 1); for(int i=0; i<data.nonterminals.size(); i++) { NonterminalData &nonterminal=data.nonterminals[i]; if(!nonterminal.is_ancillary) { generate_visit_function(nonterminal.type, a, indent, 1); for(int j=0; j<nonterminal.alternatives.size(); j++) { AlternativeData &alternative=nonterminal.alternatives[j]; if(alternative.type) generate_visit_function(alternative.type, a, indent, 1); } } } fprintf(a, "\n%svoid traverse_children(const Nonterminal&);\n\n", indent); fprintf(a, "%svirtual ~Visitor() {}\n", indent); fprintf(a, "%s};\n\n", indent); } if(data.variables.make_up_connection) generate_single_class(classes.nonterminal, a, indent, 1); generate_single_class(classes.symbol, a, indent, 2); generate_single_class(classes.terminal, a, indent, 2); generate_single_class(classes.nonterminal, a, indent, 2); // if(classes.creator) // generate_single_class(classes.creator, a, indent, 2); generate_symbol_class_templates(a, indent); fprintf(a, "%s\n", indent); }}void generate_parse_function(FILE *a){ const char *S_name=data.nonterminals[data.start_nonterminal_number].type->name.c_str(); fprintf(a, "%s *%s::Parser::parse()\n", S_name, data.variables.whale_namespace); fprintf(a, "{\n"); fprintf(a, "\tinitialize();\n"); fprintf(a, "\tfor(;;)\n"); fprintf(a, "\t{\n"); fprintf(a, "\t\tint state=state_stack[state_stack.size()-1];\n"); if(data.variables.input_queue) { fprintf(a, "\t\tif(input_symbols.empty()) {\n\t\t\tinput_symbols.push(%s);\n", data.variables.get_token_expression.c_str()); if (data.variables.generate_verbose_prints) { fprintf(a, "\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\tif (m_debug)\n"); fprintf(a, "\t\t\tcout << \x22read token \\x22\x22 << " "input_symbol->symbol_name() << \x22\\x22\\n\x22;\n"); fprintf(a, "\t\t#endif\n"); } } const char *ref_to_input_symbol=(data.variables.input_queue ? "input_symbols.front()" : "input_symbol"); fprintf(a, "\t\tLRAction lr_action=access_action_table(state, %s->number());\n", ref_to_input_symbol); fprintf(a, "\t\tif(lr_action.is_shift() && %s->number()!=error_terminal_number)\n", ref_to_input_symbol); fprintf(a, "\t\t{\n"); fprintf(a, "\t\t\tint new_state=lr_action.shift_state();\n"); if(data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -