📄 process.cpp.svn-base
字号:
{ triad<ClassHierarchy::Class *, int, int> cnr=nonterminal.type->find_data_member_in_direct_relatives(name_we_shall_use.c_str()); if(cnr.first) { // I think this can be replaced by // 'already_processed' data member // of type vector<DataMember *> in // ProcDataII. cout << "Unable to generate data member " << name_we_shall_use << " in class " << nonterminal.type->get_full_name() << " for " << data.full_symbol_name(expr_s.sn, false) << " at "; t->print_location(cout); cout << ", because identifier " << name_we_shall_use << " is already in use.\n"; flag=false; continue; } ClassHierarchy::DataMember *new_data_member=new ClassHierarchy::DataMember; new_data_member->name=name_we_shall_use; new_data_member->was_implicitly_declared=prototype_data_member->was_implicitly_declared; new_data_member->declared_at=prototype_data_member->declared_at; new_data_member->number_of_nested_iterations=iteration_depth-i-1; new_data_member->type=type_we_shall_use; if(i>0) { new_data_member->senior=expr_s.data_members_in_bodies[i-1]; new_data_member->senior_rests_in_a_body=true; } else { new_data_member->senior=prototype_data_member; new_data_member->senior_rests_in_a_body=false; } #ifdef DEBUG_DATA_MEMBERS_IN_BODIES cout << "\n\t\tmaking dm " << new_data_member->name << " in " << nonterminal.type->get_full_name() << " (senior " << new_data_member->senior->get_full_name() << ").\n"; #endif classes.put_data_member_to_class(new_data_member, nonterminal.type); expr_s.data_members_in_bodies.push_back(new_data_member); proc_data.data_members_already_processed[make_pair(prototype_data_member, sn.nonterminal_number())]=&expr_s; } } else assert(i==iteration_depth-1); } return flag; } else if(typeid(*expr)==typeid(NonterminalExpressionMemberName)) { NonterminalExpressionMemberName &expr_mn=*dynamic_cast<NonterminalExpressionMemberName *>(expr); return process_expression_proc_ii(expr_mn.expr, proc_data); } else if(typeid(*expr)==typeid(NonterminalExpressionCreate)) { NonterminalExpressionCreate &expr_create=*dynamic_cast<NonterminalExpressionCreate *>(expr); proc_data.make_operator=&expr_create; return true; } else if(typeid(*expr)==typeid(NonterminalExpressionUpdate)) return true; else if(typeid(*expr)==typeid(NonterminalExpressionConnectUp)) return true; else if(typeid(*expr)==typeid(NonterminalExpressionCode)) return true; else if(typeid(*expr)==typeid(NonterminalExpressionPrecedence)) return true; else { assert(false); return false; }}bool process_terminal_type_declaration(TerminalData &terminal, NonterminalTypeExpression *type){ if(type) { Terminal *t1=type->name; if(!identifier_contains_no_hyphens(t1)) return false; Terminal *t2=type->base_name; ClassHierarchy::Class *previous_declaration=classes.find(t1->text); ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : classes.terminal); if(previous_declaration) { cout << "Class " << t1->text << ", "; previous_declaration->print_where_it_was_declared(cout); cout << ", cannot be used as a class for terminal " << terminal.name << " at "; t1->print_location(cout); cout << ".\n"; return false; } if(!base_class) { report_undefined_base_class(cout, t2); return false; } if(!base_class->is_abstract || !base_class->is_derivative_of_terminal || base_class->is_a_built_in_template) { cout << "Class " << t2->text << ", "; base_class->print_where_it_was_declared(cout); cout << ", cannot be used as a base class for " << t1->text << " at "; t2->print_location(cout); cout << ": either Terminal or an abstract derivative of Terminal is required.\n"; return false; } terminal.type=new ClassHierarchy::Class(t1->text, base_class, NULL); terminal.type->declared_at=t1; } else { string class_name=default_terminal_class_name(terminal.name); if(!class_name.size()) { cout << "Unable to generate default class name for terminal " << terminal.name << " at "; terminal.declaration->print_location(cout); cout << ".\n"; return false; } ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str()); if(previous_declaration) { cout << "Unable to generate default class name for terminal " << terminal.name << " at "; terminal.declaration->print_location(cout); cout << ", because the name " << class_name << " is already in use"; if(previous_declaration->declared_at) { cout << " (it was "; previous_declaration->print_where_it_was_declared(cout); cout << ")"; } cout << ".\n"; return false; } terminal.type=new ClassHierarchy::Class(class_name, classes.terminal, NULL); terminal.type->was_implicitly_declared=true; terminal.type->declared_at=terminal.declaration; } terminal.type->is_abstract=false; terminal.type->assigned_to=SymbolNumber::for_terminal(data.terminals.size()); return true;}bool process_nonterminal_type_declaration(int nn, NonterminalTypeExpression *type){ NonterminalData &nonterminal=data.nonterminals[nn]; ClassHierarchy::Class *default_base_class; if(nonterminal.category==NonterminalData::EXTERNAL) { assert(("fix me!", false)); default_base_class=classes.wrapper; } else default_base_class=classes.nonterminal; if(type) { Terminal *t1=type->name; if(!identifier_contains_no_hyphens(t1)) return false; Terminal *t2=type->base_name; ClassHierarchy::Class *previous_declaration=classes.find(t1->text); ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : default_base_class); if(previous_declaration) { cout << "Class " << t1->text << ", "; previous_declaration->print_where_it_was_declared(cout); cout << ", cannot be used as a class for nonterminal " << nonterminal.name << " at "; t1->print_location(cout); cout << ".\n"; return false; } if(!base_class) { report_undefined_base_class(cout, t2); return false; } if(!base_class->is_abstract || !base_class->is_derivative_of_nonterminal || base_class->is_a_built_in_template) { cout << "Class " << t2->text << ", "; base_class->print_where_it_was_declared(cout); cout << ", cannot be used as a base class for " << t1->text << " at "; t2->print_location(cout); cout << ": either Nonterminal or an abstract derivative of Nonterminal is required.\n"; return false; } nonterminal.type=new ClassHierarchy::Class(t1->text, base_class, NULL); nonterminal.type->declared_at=t1; } else { string class_name=default_nonterminal_class_name(nonterminal.name); assert(class_name.size()); ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str()); if(previous_declaration) { cout << "Unable to generate default class name for nonterminal " << nonterminal.name << " at "; nonterminal.declaration->print_location(cout); cout << ", because the name " << class_name << " is already in use"; if(previous_declaration->declared_at) { cout << " (it was "; previous_declaration->print_where_it_was_declared(cout); cout << ")"; } cout << ".\n"; return false; } nonterminal.type=new ClassHierarchy::Class(class_name, default_base_class, NULL); nonterminal.type->was_implicitly_declared=true; nonterminal.type->declared_at=nonterminal.declaration; } nonterminal.type->is_abstract=false; nonterminal.type->assigned_to=SymbolNumber::for_nonterminal(nn); return true;}ClassHierarchy::Class *process_external_type_declaration(NonterminalExternalTypeExpression *external_type, NonterminalData *nonterminal){ // if external_type!=NULL and nonterminal!=NULL: // explicit declaration of an external type for a nonterminal: // can appear both in 'nonterminal' and 'external' statements. // if external_type!=NULL and nonterminal==NULL: // when does _that_ happen, I wonder?! // if external_type==NULL and nonterminal!=NULL: // implicit declaration of an external type for a nonterminal: // currently only from withing 'external' statement. assert(external_type!=NULL || nonterminal!=NULL); if(external_type!=NULL && nonterminal==NULL) { // remove me! cout << "Finally it happened!\n" "If you ever see this message printed, please report the fact to the author!\n"; throw QuietException(); } string s; if(external_type) { try { s=serialize_external_type_expression(*external_type); } catch(TerminalId *) { return NULL; } } else { cout << "process_external_type_declaration(): got NULL, using " << nonterminal->name << " as class name.\n"; s=nonterminal->name; } ClassHierarchy::Class *previous_declaration=classes.find(s.c_str()); if(!previous_declaration) { ClassHierarchy::Class *new_class=new ClassHierarchy::Class(s); if(external_type) new_class->declared_at=external_type->id; else { new_class->declared_at=nonterminal->declaration; new_class->was_implicitly_declared=true; } if(nonterminal) nonterminal->external_type=new_class; return new_class; } else if(!previous_declaration->is_internal) { if(nonterminal) nonterminal->external_type=previous_declaration; return previous_declaration; } else { cout << "Class " << s << ", "; previous_declaration->print_where_it_was_declared(cout); if(nonterminal) cout << ", cannot be used as an external class for nonterminal " << nonterminal->name << " at "; else cout << ", cannot be used as external class at "; external_type->id->print_location(cout); cout << ".\n"; return NULL; }}bool process_alternative_type_declaration(AlternativeData &alternative, NonterminalData &nonterminal, int alternative_number, NonterminalTypeExpression *type){ if(!nonterminal.type) return false; assert(nonterminal.type->nonterminal_class_category==ClassHierarchy::Class::BASE); if(type) { Terminal *t1=type->name; if(!identifier_contains_no_hyphens(t1)) return false; Terminal *t2=type->base_name; ClassHierarchy::Class *previous_declaration=classes.find(t1->text); ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : nonterminal.type); if(previous_declaration) { cout << "Class " << t1->text << ", "; previous_declaration->print_where_it_was_declared(cout); cout << ", cannot be used as a class for the " << english2_itoa(alternative_number+1, false) << " alternative "; cout << "of nonterminal " << nonterminal.name << " at "; t1->print_location(cout); cout << ".\n"; return false; } if(!base_class) { report_undefined_base_class(cout, t2); return false; } // checking whether base_class is a derivative of nonterminal.type bool flag=false; for(ClassHierarchy::Class *m=base_class; m!=NULL; m=m->ancestor) if(m==nonterminal.type) { flag=true; break; } if(!flag || (!base_class->nonterminal_class_category==ClassHierarchy::Class::ABSTRACT && !base_class->nonterminal_class_category==ClassHierarchy::Class::BASE)) { cout << "Class " << t2->text << ", "; base_class->print_where_it_was_declared(cout); cout << ", cannot be used as a base class for " << t1->text << " at "; t2->print_location(cout); cout << ": either " << nonterminal.type->name << " or an abstract derivative of "; cout << nonterminal.type->name << " is required.\n"; return false; } alternative.type=new ClassHierarchy::Class(t1->text, base_class, NULL); alternative.type->declared_at=t1; } else { string class_name=default_alternative_class_name(nonterminal.type->name, alternative_number); ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str()); if(previous_declaration) { cout << "Unable to generate default class name for the "; cout << english2_itoa(alternative_number+1, false) << " alternative of nonterminal " << nonterminal.name << " at "; nonterminal.declaration->print_location(cout); cout << ", because the name " << class_name << " is already in use"; if(previous_declaration->declared_at) { cout << " (it was "; previous_declaration->print_where_it_was_declared(cout); cout << ")"; } cout << ".\n"; return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -