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 + -
显示快捷键?