program.cc
来自「这个程序是关于OpenC++的反射植入机制的编译器」· CC 代码 · 共 412 行
CC
412 行
//@beginlicenses@//@license{chiba_tokyo}{}@//@license{xerox}{}@//@license{contributors}{}@//// Permission to use, copy, distribute and modify this software and its // documentation for any purpose is hereby granted without fee, provided that// the above copyright notice appears in all copies and that both that copyright// notice and this permission notice appear in supporting documentation.// // 1997-2001 Shigeru Chiba, Tokyo Institute of Technology. make(s) no representations about the suitability of this// software for any purpose. It is provided "as is" without express or implied// warranty.// // Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.//// -----------------------------------------------------------------////// Copyright (c) 1995, 1996 Xerox Corporation.// All Rights Reserved.//// Use and copying of this software and preparation of derivative works// based upon this software are permitted. Any copy of this software or// of any derivative work must include the above copyright notice of // Xerox Corporation, this paragraph and the one after it. Any// distribution of this software or derivative works must comply with all// applicable United States export control laws.//// This software is made available AS IS, and XEROX CORPORATION DISCLAIMS// ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE, AND NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY// LIABILITY FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS// EXPRESSLY DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING// NEGLIGENCE) OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED// OF THE POSSIBILITY OF SUCH DAMAGES.//// -----------------------------------------------------------------//// Permission to use, copy, distribute and modify this software and its // documentation for any purpose is hereby granted without fee, provided that// the above copyright notice appears in all copies and that both that copyright// notice and this permission notice appear in supporting documentation.// // Other Contributors (see file AUTHORS) make(s) no representations about the suitability of this// software for any purpose. It is provided "as is" without express or implied// warranty.// // Copyright (C) Other Contributors (see file AUTHORS)////@endlicenses@#include <iostream>#include <opencxx/parser/Program.h>#include <opencxx/parser/Ptree.h>#include <opencxx/parser/auxil.h>#include <opencxx/parser/token-names.h>#include <opencxx/parser/PtreeUtil.h>namespace Opencxx{char Program::Get(){ if(buf[index] == '\0') return buf[index]; else return buf[index++];}void Program::Subst(Ptree* newtext, Ptree* oldtext){ Replace(PtreeUtil::LeftMost(oldtext), PtreeUtil::RightMost(oldtext), newtext);}void Program::Insert(Ptree* pos, Ptree* before_text, Ptree* after_text){ char* p; if(before_text != 0){ p = PtreeUtil::LeftMost(pos); Replace(p, p, before_text); } if(after_text != 0){ p = PtreeUtil::RightMost(pos); Replace(p, p, after_text); }}void Program::MinimumSubst(Ptree* newtext, Ptree* oldtext){ if(MinimumSubst2(newtext, oldtext)) Subst(newtext, oldtext);}bool Program::MinimumSubst2(Ptree* newtext, Ptree* oldtext){ int what; if(oldtext == newtext) { return false; } else if(oldtext == 0 || newtext == 0) { return true; } else if(what = newtext->What(), (what == ntExprStatement || what == ntTypedef)) { return true; } else if(oldtext->IsLeaf() || newtext->IsLeaf()) { return true; } else if(oldtext->Car() == 0 && oldtext->Cdr() == 0) { return true; } else if(oldtext == newtext->Cdr()) { Insert(oldtext, newtext->Car(), 0); return false; } else if(oldtext->Car() != 0 && oldtext->Car() == PtreeUtil::Second(newtext)) { Insert(oldtext->Car(), newtext->Car(), 0); newtext = PtreeUtil::ListTail(newtext, 2); if(MinimumSubst2(newtext, oldtext->Cdr())) { if(oldtext->Cdr() == 0) { Insert(oldtext->Car(), 0, newtext); } else { Subst(newtext, oldtext->Cdr()); } } return false; } else{ bool dirty1 = MinimumSubst2(newtext->Car(), oldtext->Car()); bool dirty2 = MinimumSubst2(newtext->Cdr(), oldtext->Cdr()); if(dirty1 == dirty2) { return dirty1; } else if(dirty1) { if(oldtext->Cdr() == 0 && newtext->Cdr() == 0) { return true; } else if(oldtext->Car() == 0) { Insert(oldtext->Cdr(), newtext->Car(), 0); } else { Subst(newtext->Car(), oldtext->Car()); } } else { if(oldtext->Car() == 0 && newtext->Car() == 0) { return true; } else if(oldtext->Cdr() == 0) { Insert(oldtext->Car(), 0, newtext->Cdr()); } else { Subst(newtext->Cdr(), oldtext->Cdr()); } } return false; }}void Program::Replace(char* startpos, char* endpos, Ptree* text){ if(startpos == 0 || endpos == 0) return; unsigned start = unsigned(startpos - buf); unsigned end = unsigned(endpos - buf); Replacement* p = replacement; if(p == 0) replacement = new Replacement(0, start, end, text); else if (start < p->startpos) replacement = new Replacement(p, start, end, text); else if(p->next == 0) p->next = new Replacement(0, start, end, text); else{ for(; p->next != 0; p = p->next) if(start < p->next->startpos) break; p->next = new Replacement(p->next, start, end, text); }}/* LineNumber() returns the line number of the line pointed to by PTR.*/unsigned Program::LineNumber(char* ptr, char*& filename, int& filename_length){ int n; int len; unsigned name; int nline = 0; unsigned pos = unsigned(ptr - buf); if(pos > size){ // error? filename = defaultname; filename_length = strlen(defaultname); return 0; } int line_number = -1; filename_length = 0; while(pos > 0){ switch(Ref(--pos)){ case '\n' : ++nline; break; case '#' : len = 0; n = ReadLineDirective(pos, -1, name, len); if(n >= 0){ // unless #pragma if(line_number < 0) line_number = n + nline; if(len > 0 && filename_length == 0){ filename = (char*)Read(name); filename_length = len; } } break; } if(line_number >= 0 && filename_length > 0) return line_number; } if(filename_length == 0){ filename = defaultname; filename_length = strlen(defaultname); } if(line_number < 0) line_number = nline + 1; return line_number;}/* Write() saves the program as a file named FILE_NAME. This assumes that the first line of the program is a # line directive.*/void Program::Write(std::ostream& out, const char* file_name){ Replacement* rep = replacement; unsigned pos; unsigned nlines = 1; unsigned line_number = 1; unsigned i = 0; char c; unsigned filename = 0; int filename_length = 0; if(Ref(i) == '#') line_number = ReadLineDirective(i, (int)line_number, filename, filename_length); for(; rep != 0; rep = rep->next){ pos = rep->startpos; while(i < pos){ c = Ref(i++); if(c == '\0'){ --i; break; } out << c; if(c == '\n'){ ++nlines; ++line_number; if(Ref(i) == '#') line_number = ReadLineDirective(i, (int)line_number, filename, filename_length); } } if(i > 0 && Ref(i - 1) != '\n'){ out << '\n'; ++nlines; }#if defined(_MSC_VER) || defined(IRIX_CC) out << "#line " << nlines + 1 << " \"" << file_name << "\"\n";#else out << "# " << nlines + 1 << " \"" << file_name << "\"\n";#endif ++nlines; nlines += rep->text->Write(out); pos = rep->endpos; if(rep->next != 0 && rep->next->startpos <= pos){ rep = rep->next; out << '\n'; ++nlines; nlines += rep->text->Write(out); if(rep->endpos > pos) pos = rep->endpos; } while(i < pos){ c = Ref(i++); if(c == '\0'){ --i; break; } else if(c == '\n'){ ++line_number; if(Ref(i) == '#') line_number = ReadLineDirective(i, (int)line_number, filename, filename_length); } }#if defined(_MSC_VER) || defined(IRIX_CC) out << "\n#line " << line_number << ' ';#else out << "\n# " << line_number << ' ';#endif ++nlines; if(filename_length > 0) for(int j = 0; j < filename_length; ++j) out << (char)Ref(filename + j); else out << '"' << defaultname << '"'; out << '\n'; ++nlines; } while((c = Ref(i++)) != '\0'){ out << c; if(c == '\n') ++nlines; }#if defined(_MSC_VER) || defined(IRIX_CC) out << "\n#line " << nlines + 2 << " \"" << file_name << "\"\n";#else out << "\n# " << nlines + 2 << " \"" << file_name << "\"\n";#endif}int Program::ReadLineDirective(unsigned i, int line_number, unsigned& filename, int& filename_length){ char c; do{ c = Ref(++i); }while(is_blank(c));#if defined(_MSC_VER) || defined(IRIX_CC) if(i + 4 <= GetSize() && strncmp(Read(i), "line", 4) == 0){ i += 3; do{ c = Ref(++i); }while(is_blank(c)); }#endif if(is_digit(c)){ /* # <line> <file> */ unsigned num = c - '0'; for(;;){ c = Ref(++i); if(is_digit(c)) num = num * 10 + c - '0'; else break; } line_number = num - 1; /* line_number'll be incremented soon */ if(is_blank(c)){ do{ c = Ref(++i); }while(is_blank(c)); if(c == '"'){ unsigned fname_start = i; do{ c = Ref(++i); } while(c != '"'); if(i > fname_start + 2){ filename = fname_start; filename_length = int(i - fname_start + 1); } } } } return line_number;}// class Program::ReplacementProgram::Replacement::Replacement(Replacement* n, unsigned st, unsigned ed, Ptree* t){ next = n; startpos = st; endpos = ed; text = t;}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?