lex.cpp
来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C++ 代码 · 共 727 行 · 第 1/2 页
CPP
727 行
while ((SetMacro(ret))) ((void) 0); if ( ret == ID) while ((CallMacro(ret))) ((void) 0); return ret;} int mylex::scan(int lvl){ int ret= scan1(); if ( ret == ID) { if (! InMotClef(plglval->type,ret)) { int ft = FindType(buf); // if( ft) cout << "( ft == " << ft << " ) "<< endl; int feid3[4] ={ ID,FESPACE1,FESPACE,FESPACE3}; assert ( ft >= 0 && ft <= 3) ; ret = feid3[ft]; plglval->str = newcopy(buf); }} if ( ret =='{') { //cout << " listMacroDef->push_back"<< endl; listMacroDef->push_back( MapMacroDef() );} else if (ret == '}') {//cout << " listMacroDef->pop_back"<< endl; listMacroDef->pop_back( );} if (! lexdebug && echo && lvl==0 ) print(cout); return ret;} string mylex::token() const { int i=-1; string f; if (typetoken == STRING) { f += '"'; while (buf[++i]) if (buf[i]=='\n') f += "\\n"; else if (buf[i]=='"') f += "\\\""; else f += buf[i] ; f+= '"'; } else while (buf[++i]) if (buf[i]=='\n') f += "\\n"; else f += buf[i] ; return f; } void mylex::print(ostream &f) const { int i=-1; int k=0; if (typetoken == STRING) { f <<'"'; while (buf[++i]) { k++; if (buf[i]=='\n') k++, f << "\\n"; else if (buf[i]=='"') k++,f << "\\\""; else f << buf[i] ; if ( k%50==49) f << "\n ... : "; } f << '"'; } else while (buf[++i]) if (buf[i]=='\n') f << "\\n"; else f << buf[i] ; } char * mylex::match(int i) { if ( i != basescan() ) {// basescan -> scan1 change 2/2/2007 (non pas des substitution de parametres FH) cerr << " we waiting for a '" << char(i) <<"'" << endl; ErrorScan(" err macro ");}; return buf; }bool mylex::SetMacro(int &ret){ bool rt=false; if (strcmp(buf,"macro")==0) { char *macroname=newcopy(match(ID)); int nbparam =0; deque<string> macroparm; int rr=basescan(); string def; if (rr!='(') def += buf; else { // a '(' after macro name rr = basescan(); if (rr != ')' ) do { if (nbparam++>= 100) { cerr << "in macro " <<macroname << endl; ErrorScan(" Too much (more than 100) parameters"); } //cout << " \t\t " << ID << " " << rr << " " << buf << endl; if (rr != ID) { cerr <<" Erreur waiting of an ID: " << buf << " " << rr << endl; erreur("in macro def: waiting for a ID"); } macroparm.push_back(buf); rr = basescan(); if (rr == ')') break; if ( rr != ',') erreur("in macro def: waiting , or ) "); rr = basescan(); } while(1); } do { int i = source().get(); if (i == EOF) { cerr << "in macro " <<macroname << endl; ErrorScan(" ENDOFFILE in macro definition. remark:a macro end with // ");} int ii = source().peek(); if (i == '/' && ii == '/') { source().putback('/'); break;} def +=char(i); } while(1); macroparm.push_back(def); if(echo) cout << "macro " << macroname ; for (size_t i=0;i<macroparm.size()-1;i++) if(echo) cout << ( (i == 0) ? '(' : ',') << macroparm[i]; if (nbparam) if(echo) cout << " ) " ; for (size_t i=0;i<def.size();i++) if (def[i] == 10 || (def[i] == 13 ) ) { def[i]='\n'; linenumber++; if(echo) cout << '\n' << setw(5) <<linenumber << " : " ; } else if(echo) cout << def[i] ; // cout << macroparm.back() ; MapMacroDef & MacroDef =listMacroDef->back(); MapMacroDef::const_iterator i=MacroDef.find(macroname); if ( i == MacroDef.end() ) MacroDef[macroname]=macroparm; else { cerr << "ERREUR in macro name:" <<macroname << endl; ErrorScan(" The macro already exists, sorry");} rt=true; ret= basescan(); } return rt;}bool mylex::CallMacro(int &ret){ // New Version with direct macro expansion // FH jan 2005 // ----------------------------------------- for (list<MapMacroDef>::const_iterator i=listMacroDef->begin(); i != listMacroDef->end(); i++) { MapMacroDef::const_iterator j= i->find(buf); if (j != i->end()) { // int inmacroold=withmacropara; if(debugmacro) cout <<"call macro : " << buf << endl; string * macronn= new string(" macro: "); *macronn+= buf; const deque<string> & macroparm= j->second; int nbparam= macroparm.size()-1; MapMacroParam lp; if (nbparam > 0 ) { match('('); for (int k=0;k<nbparam;k++) { string p; int kend= ( k+1 == nbparam) ? ')' : ','; int lvl=0; while (1) { int rr = basescan();// basescan -> scan1 change 2/2/2007 ( not change to pass macro name as a parameter) if(lvl && rr==')') lvl--; // if ( then we eat next ) else if(lvl && rr==']') lvl--; // if ( then we eat next ) else if (rr=='(') lvl++ ; // eat next else if (rr=='[') lvl++ ; // eat next else if (lvl<=0) { if (rr==kend ) break; else if (rr==')' || rr==',') {// Correction FH 2/06/2004 cerr << "Error in macro expantion "<< j->first << ", we wait for "<< char(kend) << " and we get " << char(rr)<< endl; cerr << " number of macro parameter in definition is " << nbparam << endl; ErrorScan(" Wrong number of parameter in macro call"); }} if (rr==ENDOFFILE) ErrorScan(" ENDOFFILE in macro usage"); p += token(); // Correction FH 2/06/2004 of string parameter } if(debugmacro) cout << "macro arg "<< k << " :" << macroparm[k] << " -> " << p << endl; lp.insert(make_pair<string,string>(macroparm[k],p)); //lp[macroparm[k]] = p; } } if(debugmacro) cout << " input in : -> " << macroparm[nbparam] << " " << nbparam << endl; input(macroparm[nbparam]); // ici il faut faire la substitution de parameter // ----------------------------------------------- string expandtxt; bool echosave=echo; while(1) { int c= EatCommentAndSpace(&expandtxt); // eat comment to save it; if (c == EOF) break; ret = basescan(); if(ret== ENDOFFILE) break; if (nbparam && ret == ID) { MapMacroParam::const_iterator j=lp.find(buf); if ( j != lp.end()) expandtxt+=j->second; else expandtxt+=buf; } else if (ret!='#') // macro concatenation operator expandtxt+=token(); } echo=echosave; if(debugmacro) cout <<" (macro) eadin : " << expandtxt << endl; input(expandtxt,macronn); ret = scan1(); // Correction FH 6/06/2004 of string parameter return true; } } return false;}void mylex::xxxx::open(mylex *lex,const char * ff) { //filename=ff; l=0; nf=f=0; if(lex->ffincludedir.empty()) // if no liste nf=f= new ifstream(ff); if (!f || !*f) { if ( f) { delete f; f=0; } for (ICffincludedir k=lex->ffincludedir.begin(); k!=lex->ffincludedir.end(); ++k) { string dif_ff(*k+ff); if (verbosity>=50) lex->cout << " --lex open :" << dif_ff << endl; nf=f= new ifstream(dif_ff.c_str()); if ( f) { if ( f->good()) { filename = new string(dif_ff); break; } delete f; f=0; } } } else filename=new string(ff); if (!f || !*f) { lex->cout << " Error openning file " <<ff<< endl; lgerror("lex: Error input openning file ");};}void mylex::xxxx::readin(mylex *lex,const string & s,const string *name)//,int nbparam,int bstackparam) { filename=name; l=0; nf=f= new istringstream(s.c_str()); if (!f || !*f) { lex->cout << " Error readin string :" <<s<< endl; lgerror("lex: Error readin macro ");};}void mylex::xxxx::close() { if( nf) delete nf; if (filename) delete filename; }void mylex::input(const char * filename) { ffassert(level<99 && level >= -1); if (level>=0) pilesource[level].l =linenumber; pilesource[level+1].open(this,filename); pilesource[level+1].l =0; // cout << "\n ++include " << filename << ";" << level+1 << endl; linenumber = 1; level++; }void mylex::input(const string & str,const string * name) { ffassert(level<99 && level >= -1); if (level>=0) { pilesource[level].l =linenumber; } pilesource[level+1].readin(this,str,name); linenumber = 0; level++; } bool mylex::close() { if(debugmacro ) cout << "\n close " << level ; ffassert(level >=0 && level < 100); // cout << "\n-- close " << level << endl; pilesource[level].close(); // cout << "\n ++ " << level << endl; if (--level<0) return false; linenumber = pilesource[level].l; return true;} mylex::~mylex(){ delete listMacroDef; while( ! strdata.empty()) { // commente july 2005 FH ???. a test plus finement. // delete [] strdata.top(); // bug ????? FH 25032005 strdata.pop(); }} mylex::mylex(ostream & out): linenumber(1), charnumber(0), ffincludedir(ffenvironment["include"]), firsttime(true), level(-1), echo(mpirank == 0 && verbosity), cout(out), listMacroDef(new list<MapMacroDef>), listMacroParam(0) { listMacroDef->push_front(MapMacroDef()); }; mylex * Newlex( ostream & out) { return new mylex(out); }void Destroylex(mylex * m) { delete m; }ostream & mylex::ShowStack(ostream & f){ for (int i=0;i<level;++i) if( pilesource[i].filename ) f << " \t"<<i<<"\t"<<" in " << *pilesource[i].filename<< " line : " << pilesource[i].l << endl; return f; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?