📄 codegen.cpp.svn-base
字号:
fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22Shift \x22 << new_state << \x22\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } fprintf(a, "\t\t\tsymbol_stack.push_back(%s);\n", ref_to_input_symbol); fprintf(a, "\t\t\tstate_stack.push_back(new_state);\n"); if(!data.variables.input_queue) { fprintf(a, "\t\t\tinput_symbol=%s;\n", data.variables.get_token_expression.c_str()); if (data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22read token \\x22\x22 << " "input_symbol->symbol_name() << \x22\\x22\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } } else fprintf(a, "\t\t\tinput_symbols.pop();\n"); fprintf(a, "\t\t}\n"); fprintf(a, "\t\telse if(lr_action.is_reduce())\n"); fprintf(a, "\t\t{\n"); fprintf(a, "\t\t\tint rule_number=lr_action.reduce_rule();\n"); if(data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22Reduce \x22 << rule_number << \x22\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } fprintf(a, "\t\t\tint rule_length=rules[rule_number].length;\n"); fprintf(a, "\t\t\tint rule_start=symbol_stack.size()-rule_length;\n"); if(data.variables.generate_sanity_checks) fprintf(a, "\t\t\tif(rule_start<0) throw logic_error(\x22Whale: rule_start<0\x22);\n"); fprintf(a, "\t\t\tNonterminal *new_symbol;\n"); fprintf(a, "\t\t\t\n"); fprintf(a, "\t\t\tswitch(rule_number)\n"); fprintf(a, "\t\t\t{\n"); for(int i=1 /* S->S' excluded */; i<data.rules.size(); i++) generate_reduce_code(a, "\t\t\t", i); if(data.variables.generate_sanity_checks) fprintf(a, "\t\t\tdefault:\n" "\t\t\t\tthrow logic_error(\x22Whale: Invalid rule number.\x22);\n"); fprintf(a, "\t\t\t}\n"); fprintf(a, "\t\t\t\n"); fprintf(a, "\t\t\tfor(int i=0; i<rule_length; i++)\n"); fprintf(a, "\t\t\t{\n"); fprintf(a, "\t\t\t\tsymbol_stack.pop_back();\n"); fprintf(a, "\t\t\t\tstate_stack.pop_back();\n"); fprintf(a, "\t\t\t}\n"); fprintf(a, "\t\t\tint nn=rules[rule_number].nn;\n"); fprintf(a, "\t\t\tsymbol_stack.push_back(new_symbol);\n"); fprintf(a, "\t\t\tint new_state=access_goto_table(state_stack[state_stack.size()-1], nn);\n"); if(data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22Goto \x22 << new_state << \x22\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } fprintf(a, "\t\t\tstate_stack.push_back(new_state);\n"); fprintf(a, "\t\t}\n"); fprintf(a, "\t\telse if(lr_action.is_accept())\n"); fprintf(a, "\t\t{\n"); if(data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22" "Accept\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } if(data.variables.generate_sanity_checks) fprintf(a, "\t\t\tif(symbol_stack.size()!=1)\n" "\t\t\t\tthrow logic_error(\x22Whale: Stack size !=1 while accepting.\x22);\n"); fprintf(a, "\t\t\t%s *result = dynamic_cast<%s *>(symbol_stack.back());\n", S_name, S_name); if(data.variables.make_up_connection) fprintf(a, "\t\t\tresult->up = 0;\n"); fprintf(a, "\t\t\treturn result;\n"); fprintf(a, "\t\t}\n"); fprintf(a, "\t\telse\n"); fprintf(a, "\t\t{\n"); if(data.variables.generate_verbose_prints) { fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n"); fprintf(a, "\t\t\tif (m_debug)\n"); fprintf(a, "\t\t\t\tcout << \x22" "Error\\n\x22;\n"); fprintf(a, "\t\t\t#endif\n"); } if(data.variables.error_handler) { fprintf(a, "\t\t\t// User-specified error handler.\n"); fprintf(a, "\t\t\t%s\n", data.variables.error_handler); } else { fprintf(a, "\t\t\tif(typeid(*%s)!=typeid(TerminalError))\n", ref_to_input_symbol); fprintf(a, "\t\t\t\treport_error(cout, %s);\n", ref_to_input_symbol); fprintf(a, "\t\t\tif(!recover_from_error())\n"); fprintf(a, "\t\t\t\treturn NULL;\n"); } fprintf(a, "\t\t}\n"); fprintf(a, "\t}\n"); fprintf(a, "}\n");}void generate_reduce_code(FILE *a, const char *indent, int rn){ RuleData &rule=data.rules[rn]; NonterminalData &nonterminal=data.nonterminals[rule.nn]; SymbolNumber sn=SymbolNumber::for_nonterminal(rule.nn); string fi=string(indent)+string("\t"); const char *further_indent=fi.c_str(); ClassHierarchy::Class *type=data.get_class_assigned_to_alternative(rule.nn, rule.an);#ifdef ANNOUNCE_REDUCE_CODE_GENERATION cout << "Generating reduce code for nonterminal " << nonterminal.name << "\n";#endif fprintf(a, "%scase %d: {\t// %s\n", indent, rn, rule.in_printable_form().c_str()); if(nonterminal.category==NonterminalData::NORMAL || nonterminal.category==NonterminalData::BODY) { AlternativeData &alternative=nonterminal.alternatives[rule.an]; if(data.variables.generate_verbose_prints) { fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent); fprintf(a, "%sif (m_debug)\n", further_indent); fprintf(a, "%s\tcout << \x22Reducing by rule %s\\n\x22;\n", further_indent, prepare_for_printf(rule.in_printable_form()).c_str()); fprintf(a, "%s#endif\n", further_indent); } // const char *n_name=((nonterminal.category==NonterminalData::BODY && // rule.code_to_execute_upon_reduce) ? "body_n" : "n"); const char *n_name=(nonterminal.category==NonterminalData::BODY ? "body_n" : "n"); // string n_with_arrow=string(n_name)+string("->"); int first_position; if(rule.create_and_update_operator_locations.size()==0) { fprintf(a, "%s%s *%s=new %s;\n", further_indent, type->get_full_name().c_str(), n_name, type->get_full_name().c_str()); first_position=0; } else { SymbolNumber creator_sn=rule.body[rule.create_and_update_operator_locations[0]]; assert(creator_sn.is_nonterminal()); NonterminalData &creator=data.nonterminals[creator_sn.nonterminal_number()]; fprintf(a, "%s%s *%s=(", further_indent, type->get_full_name().c_str(), n_name); generate_expression_that_gets_single_symbol_from_stack(a, creator.type, "rule_start", rule.create_and_update_operator_locations[0]); fprintf(a, ")->n;\n"); first_position=rule.create_and_update_operator_locations.back()+1; } if(alternative.connect_up && rule.creator_nn==-1) { /* here we have to look for a creator of our parent. * (a remarkable situation: a completely born child * is looking for his parent, while the latter is * still in his egg, waiting to be born. This is * bottom-up parsing...) */ // if(data.variables.generate_sanity_checks) // else // assert(false); // ***BUOY*** fprintf(a, "%s%s->up=dynamic_cast<Creator *>(symbol_stack[find_some_creator_in_stack(rule_start-1)])->object();\n", further_indent, n_name); } set<ClassHierarchy::DataMember *> initialized_data_members; if(first_position<rule.body.size()) { fprintf(a, "%s\n", further_indent); for(int i=first_position; i<rule.expr_body.size(); i++) { ClassHierarchy::DataMember *dm=generate_code_that_copies_single_symbol_from_stack_to_one_or_more_data_members(a, further_indent, type, rule.expr_body[i], n_name, "rule_start", i); if(dm!=NULL) initialized_data_members.insert(dm); } fprintf(a, "%s\n", further_indent); } if(rule.create_and_update_operator_locations.size()==0) generate_code_that_initializes_all_remaining_data_members(a, further_indent, type, n_name, initialized_data_members); fprintf(a, "%snew_symbol=%s;\n", further_indent, n_name); // if it is an iteration body and there is a code to execute // upon reduce, then it's possible that there is a Creator to // connect to. if(nonterminal.category==NonterminalData::BODY && rule.code_to_execute_upon_reduce) { fprintf(a, "%s\n", further_indent); int creator_nn=find_creator_somewhere_around_rule(rn); if(creator_nn==-1) fprintf(a, "%s/* Code operates without an object */\n", further_indent); else if(creator_nn==0) generate_code_to_establish_connection_to_unknown_creator(a, further_indent, nonterminal.master_nn, nonterminal.master_an); else { fprintf(a, "%s/* Establishing connection to the object */\n", further_indent); generate_code_to_establish_connection_to_creator(a, further_indent, creator_nn); } } } else if(nonterminal.category==NonterminalData::EXTERNAL) { fprintf(a, "%s/* Reduce to an external nonterminal. */\n", further_indent); } else if(nonterminal.category==NonterminalData::ITERATOR) { assert(rule.code_to_execute_upon_reduce==NULL); vector<ClassHierarchy::Class *> body_types; assert(nonterminal.type->template_parameters.size()); for(int i=0; i<nonterminal.type->template_parameters.size(); i++) body_types.push_back(nonterminal.type->template_parameters[i]); if(rule.body.size()==1) { char *v_name; if(body_types.size()==1) v_name="body"; else if(body_types.size()==2) v_name="body_a"; else assert(false); if(data.variables.generate_verbose_prints) { fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent); fprintf(a, "%sif (m_debug)\n", further_indent); fprintf(a, "%s\tcout << \x22" "Creating iterator %s\\n\x22;\n", further_indent, nonterminal.name); fprintf(a, "%s#endif\n", further_indent); } fprintf(a, "%s%s *it=new %s;\n", further_indent, type->get_full_name().c_str(), type->get_full_name().c_str()); generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 0), "it", false); fprintf(a, "%sit->%s.push_back(", further_indent, v_name); generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 0); fprintf(a, ");\n"); fprintf(a, "%snew_symbol=it;\n", further_indent); } else if(rule.body.size()==2) { assert(body_types.size()==1); if(data.variables.generate_verbose_prints) { fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent); fprintf(a, "%sif (m_debug)\n", further_indent); fprintf(a, "%s\tcout << \x22" "Updating iterator %s\\n\x22;\n", further_indent, nonterminal.name); fprintf(a, "%s#endif\n", further_indent); } fprintf(a, "%s%s *it=", further_indent, type->get_full_name().c_str()); generate_expression_that_gets_single_symbol_from_stack(a, type, "rule_start", 0); fprintf(a, ";\n"); generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 1), "it", false); fprintf(a, "%sit->body.push_back(", further_indent); generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 1); fprintf(a, ");\n"); fprintf(a, "%snew_symbol=it;\n", further_indent); } else if(rule.body.size()==3) { assert(body_types.size()==2); if(data.variables.generate_verbose_prints) { fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent); fprintf(a, "%sif (m_debug)\n", further_indent); fprintf(a, "%s\tcout << \x22" "Updating pair iterator %s\\n\x22;\n", further_indent, nonterminal.name); fprintf(a, "%s#endif\n", further_indent); } fprintf(a, "%s%s *it=", further_indent, type->get_full_name().c_str()); generate_expression_that_gets_single_symbol_from_stack(a, type, "rule_start", 0); fprintf(a, ";\n"); generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 1), "it", false); fprintf(a, "%sit->body_b.push_back(", further_indent); generate_expression_that_gets_single_symbol_from_stack(a, body_types[1], "rule_start", 1); fprintf(a, ");\n"); generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 2), "it", false); fprintf(a, "%sit->body_a.push_back(", further_indent); generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 2); fprintf(a, ");\n"); fprintf(a, "%snew_symbol=it;\n", further_indent); } else assert(false); } else if(nonterminal.category==NonterminalData::INVOKER) { assert(rule.code_to_execute_upon_reduce); fprintf(a, "%s%s *invoker=new %s;\n", further_indent, type->get_full_name().c_str(), type->get_full_name().c_str()); fprintf(a, "%snew_symbol=invoker;\n", further_indent); int creator_nn=find_creator_somewhere_around_rule(rn); if(creator_nn==-1) fprintf(a, "%s/* Code operates without an object */\n", further_indent); else if(creator_nn==0) generate_code_to_establish_connection_to_unknown_creator(a, further_indent, nonterminal.master_nn, nonterminal.master_an); else { fprintf(a, "%s/* Establishing connection to the object */\n", further_indent); generate_code_to_establish_connection_to_creator(a, further_indent, creator_nn); } } else if(nonterminal.category==NonterminalData::CREATOR || nonterminal.category==NonterminalData::UPDATER) { assert(rule.code_to_execute_upon_reduce==NULL); bool it_is_creator=(nonterminal.category==NonterminalData::CREATOR); assert(nonterminal.rules_where_ancillary_symbol_is_used.size()>0); int parent_rule_number=nonterminal.rules_where_ancillary_symbol_is_used[0]; RuleData &parent_rule=data.rules[parent_rule_number]; NonterminalData &parent_nonterminal=data.nonterminals[parent_rule.nn]; AlternativeData &parent_alternative=parent_nonterminal.alternatives[parent_rule.an]; ClassHierarchy::Class *parent_type=data.get_class_assigned_to_alternative(parent_rule.nn, parent_rule.an); assert(parent_rule.create_and_update_operator_locations.size()>=(it_is_creator ? 1 : 2)); int first_position_in_this_rule; // Important note: for // creators it may differ from rule to rule. int number_of_positions_to_process; if(it_is_creator) { int creator_pos=parent_rule.create_and_update_operator_locations[0]; assert(parent_rule.body[creator_pos]==sn); first_position_in_thi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -