📄 process.cpp.svn-base
字号:
alternative.type=new ClassHierarchy::Class(class_name, nonterminal.type, NULL); alternative.type->was_implicitly_declared=true; alternative.type->declared_at=alternative.declaration; } alternative.type->is_abstract=false; alternative.type->assigned_to=nonterminal.type->assigned_to; alternative.type->nonterminal_class_category=ClassHierarchy::Class::SPECIFIC; alternative.type->nonterminal_alternative_number=alternative_number; return true;}ClassHierarchy::Class *process_standalone_type_declaration(NonterminalTypeExpression *type){ assert(type); if(!identifier_contains_no_hyphens(type->name)) return NULL; ClassHierarchy::Class *previous_declaration=classes.find(type->name->text); if(previous_declaration) { cout << "Class " << previous_declaration->name << ", "; previous_declaration->print_where_it_was_declared(cout); cout << ", cannot be redeclared at "; type->name->print_location(cout); cout << ".\n"; return NULL; } if(!type->base_name) { cout << "Class " << type->name->text << " requires an explicit base class at "; type->name->print_location(cout); cout << ".\n"; return NULL; } ClassHierarchy::Class *base_class=classes.find(type->base_name->text); if(!base_class) { report_undefined_base_class(cout, type->base_name); return NULL; } if(!base_class->assigned_to && base_class->is_internal && !base_class->is_a_built_in_template) { ClassHierarchy::Class *m=new ClassHierarchy::Class(type->name->text, base_class, NULL); m->declared_at=type->name; m->is_abstract=true; return m; } else if(base_class->assigned_to.is_nonterminal() && (base_class->nonterminal_class_category==ClassHierarchy::Class::UNKNOWN || base_class->nonterminal_class_category==ClassHierarchy::Class::BASE || base_class->nonterminal_class_category==ClassHierarchy::Class::ABSTRACT)) {// NonterminalData &nonterminal=data.nonterminals[base_class->assigned_to.nonterminal_number()]; if(base_class->nonterminal_class_category==ClassHierarchy::Class::UNKNOWN) base_class->nonterminal_class_category=ClassHierarchy::Class::BASE; ClassHierarchy::Class *m=new ClassHierarchy::Class(type->name->text, base_class, NULL); m->nonterminal_class_category=ClassHierarchy::Class::ABSTRACT; m->declared_at=type->name; m->assigned_to=base_class->assigned_to; // m->is_abstract=false; // ??????????????????????????????? m->is_abstract=true; return m; } else { cout << "Class " << base_class->name << ", "; base_class->print_where_it_was_declared(cout); cout << ", cannot be used as a base class for abstract class " << type->name->text << " at "; type->name->print_location(cout); cout << ".\n"; return NULL; }}void print_a_number_of_terminal_locations(ostream &os, vector<Terminal *> &a, char *word){ for(int k=0; k<a.size(); k++) { if(k) os << (k<a.size()-1 ? ", " : " and "); os << word << " "; a[k]->print_location(os); }}// id -> TerminalId, "for" -> TerminalFor, ";" -> TerminalSemicolon etc.string default_terminal_class_name(const char *s){ static std::map<const char *, const char *, NullTerminatedStringCompare> database; if(database.begin()==database.end()) {// cout << "default_terminal_class_name(): called for the first time, building database.\n"; database["!"]="ExclamationMark"; database["@"]="CommercialAt"; database["#"]="Sharp"; database["$"]="Dollar"; database["%"]="Percent"; database["^"]="Circumflex"; database["&"]="Ampersand"; database["*"]="Asterisk"; database["("]="LeftParenthesis"; database[")"]="RightParenthesis"; database["["]="LeftBracket"; database["]"]="RightBracket"; database["{"]="LeftBrace"; database["}"]="RightBrace"; database["+"]="Plus"; database["-"]="Minus"; database["++"]="Increment"; database["--"]="Decrement"; database[":"]="Colon"; database[";"]="Semicolon"; database[","]="Comma"; database["."]="Period"; database["..."]="Ellipsis"; database["<"]="LessThan"; database[">"]="GreaterThan"; database["<="]="LessOrEqual"; database[">="]="GreaterOrEqual"; database["="]="Equal"; database["!="]="NotEqual"; database[":="]="Assign"; database["+="]="SumAssign"; database["-="]="DifferenceAssign"; database["*="]="ProductAssign"; database["/="]="QuotientAssign"; database["/"]="Slash"; database["\\"]="Backslash"; database["?"]="QuestionMark"; database["\x22"]="QuotationMark"; database["'"]="Apostrophe"; database["_"]="Underscore"; database["~"]="Tilde"; database["->"]="Arrow"; } if(s[0]=='"') { int l=strlen(s); assert(s[l-1]=='"'); if(l==2) return string(""); string contents(s+1, s+l-1); map<const char *, const char *, NullTerminatedStringCompare>::iterator p=database.find(contents.c_str()); if(p!=database.end()) return string("Terminal")+string((*p).second); for(string::iterator p=contents.begin(); p!=contents.end(); p++) if(!(isalpha(*p) || isdigit(*p) || *p=='_' || *p=='-')) return string(""); return string("Terminal")+default_naming_proc(contents.c_str()); } else return string("Terminal")+default_naming_proc(s);}string default_nonterminal_class_name(const char *s){ return string("Nonterminal")+default_naming_proc(s);}string default_alternative_class_name(const string &s, int alternative_number){ char c=s[s.size()-1]; if((c>='a' && c<='z') || c=='_') return s+roman_itoa(alternative_number+1, true); else return s+string("_")+roman_itoa(alternative_number+1, true);}string default_naming_proc(const char *s){ string result; bool capital_flag=true; for(int i=0; s[i]; i++) if((s[i]>='A' && s[i]<='Z') || isdigit(s[i])) { result+=s[i]; capital_flag=false; } else if(s[i]>='a' && s[i]<='z') { result+=char(s[i]-(capital_flag ? 'a'-'A' : 0)); capital_flag=false; } else if(s[i]=='_' || s[i]=='-') capital_flag=true; return result;}void report_undefined_base_class(ostream &os, Terminal *t){ assert(t); os << "Undefined base class " << t->text << " at "; t->print_location(os); os << ".\n";}bool identifier_contains_no_hyphens(Terminal *t){ for(int i=0; t->text[i]; i++) if(t->text[i]=='-') { cout << "Identifier at "; t->print_location(cout); cout << " may not contain hyphens.\n"; return false; } return true;}struct ClassNamePrinter : binary_function<ostream &, const ClassHierarchy::Class *, ostream &>{ ostream &operator ()(ostream &os, const ClassHierarchy::Class *c) { os << c->name; }};ClassHierarchy::Class *process_scope_in_member_name_specification(Terminal *scope, Terminal *id, const pair<int, int> &location){ ClassHierarchy::Class *class_assigned_to_host_nonterminal=data.get_class_assigned_to_alternative(location.first, location.second); assert(class_assigned_to_host_nonterminal); if(!scope) return class_assigned_to_host_nonterminal; bool strange_coincidence=!strcmp(scope->text, data.nonterminals[location.first].name); ClassHierarchy::Class *this_class; if(strange_coincidence) this_class=data.nonterminals[location.first].type; else this_class=classes.find(scope->text); if(!this_class) { cout << "Undefined class " << scope->text << " at "; scope->print_location(cout); cout << ".\n"; return NULL; } // this_class should be an ancestor of class_assigned_to_host_nonterminal. bool found=false; for(ClassHierarchy::Class *c=class_assigned_to_host_nonterminal; c; c=c->ancestor) if(c==this_class) { found=true; break; } if(found) return this_class; else { vector<ClassHierarchy::Class *> v; for(ClassHierarchy::Class *c=class_assigned_to_host_nonterminal; c; c=c->ancestor) v.push_back(c); cout << "Class " << this_class->name << " cannot be used to store variable "; cout << id->text << " at "; scope->print_location(cout); cout << ": expecting "; custom_print(cout, v.begin(), v.end(), ClassNamePrinter(), ", ", " or "); cout << ".\n"; return NULL; }}ClassHierarchy::DataMember *process_single_data_member_declaration(Terminal *scope, Terminal *name, int nn, int an, int number_of_iterations){ ClassHierarchy::Class *scope_class=process_scope_in_member_name_specification(scope, name, make_pair(nn, an)); if(!scope_class) return NULL; assert(name); char *s=name->text; triad<ClassHierarchy::Class *, int, int> cnr=scope_class->find_data_member_in_direct_relatives(s); if(!cnr.first) { // creating a new data member. ClassHierarchy::DataMember *new_data_member=new ClassHierarchy::DataMember; new_data_member->name=s; new_data_member->type=NULL; new_data_member->was_implicitly_declared=false; new_data_member->declared_at=name; new_data_member->internal_type_if_there_is_an_external_type=NULL; new_data_member->number_of_nested_iterations=number_of_iterations; classes.put_data_member_to_class(new_data_member, scope_class); return new_data_member; } else if(!cnr.third || !scope) { // attempting to use an existing data member. ClassHierarchy::DataMember *data_member=cnr.first->data_members[cnr.second]; if(data_member->better_not_to_use_it_for_ordinary_symbols) { cout << "Warning: usage of built-in data member " << data_member->name << " at "; name->print_location(cout); cout << " would most probably lead to parser malfunction.\n"; } #if 0 if(data_member->number_of_nested_iterations!=number_of_iterations) { cout << "Data member "; cout << data_member->get_full_name() << ", "; data_member->print_where_it_was_declared(cout); cout << ", cannot be used at "; name->print_location(cout); cout << ", because " << data_member->number_of_nested_iterations << ", " << number_of_iterations << "\n"; return NULL; } else #endif data_member->number_of_nested_iterations=max(data_member->number_of_nested_iterations, number_of_iterations); return data_member; } else { cout << "Unable to create data member "; cout << scope_class->name << "::" << s; cout << " at "; name->print_location(cout); cout << ", because a there is a member bearing the same name ("; cnr.first->data_members[cnr.second]->print_where_it_was_declared(cout); cout << ") in class " << cnr.first->name << ", which is "; if(cnr.third==-1) cout << "an ancestor of "; else cout << "a descendant of "; cout << scope_class->name << ".\n"; return NULL; }}string generate_default_data_member_name(int n){ char s[20]; sprintf(s, "a%u", n); return string(s);}string serialize_external_type_expression(NonterminalExternalTypeExpression &expr){ string result; if(typeid(*expr.id)==typeid(TerminalId)) { if(!identifier_contains_no_hyphens(expr.id)) throw expr.id; result=expr.id->text; } else if(typeid(*expr.id)==typeid(TerminalString)) result=string(expr.id->text+1, expr.id->text+strlen(expr.id->text)-1); else assert(false); if(expr.template_arguments.size()) { result+="<"; for(int i=0; i<expr.template_arguments.size(); i++) { if(i) result+=", "; result+=serialize_external_type_expression(*expr.template_arguments[i]); } if(result[result.size()-1]!='>') result+=">"; else result+=" >"; } if(typeid(*expr.expr1)==typeid(NonterminalExt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -