lex.cpp

来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C++ 代码 · 共 727 行 · 第 1/2 页

CPP
727
字号
// -*- Mode : c++ -*-//// SUMMARY  :      // USAGE    :        // ORG      : // AUTHOR   : Frederic Hecht// E-MAIL   : hecht@ann.jussieu.fr///*  This file is part of Freefem++  Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.  Freefem++  is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include  <complex>#include  <string>#include  <iostream>#include  "error.hpp"#include  <ctype.h>#include  <stdlib.h>#include  <map>#include "AFunction.hpp"//class pfes;#include  <iomanip>                                                                                                        #include "lg.tab.hpp"#include "lex.hpp"extern YYSTYPE *plglval;//  New version of macro expantion more classical//  and more  simple// FH Jan. 2005static const bool debugmacro = false;/*inline char * newcopy(const char * s){  char *r(new char  [strlen(s)+1]);  strcpy(r, s);return r;}*/void  mylex::Add(Key k,int i)   {  Check(!i,k,"mot clef");  Add(k,i,0); }void  mylex::Add(Key k,aType t)   {  Check(!t,k,"type");  Add(k,TYPE,t);}void  mylex::AddF(Key k,aType t)  {  Check(!t,k,"FUNCTION");  Add(k,FUNCTION,t); }void  mylex::AddSpace(Key k,aType t)  {  Check(!t,k,"FESPACE");  Add(k,FESPACE,t); }bool mylex::InMotClef  (aType & t, int & r) const {  const_iterator i= MotClef.find(buf);  if (i== MotClef.end()) {    t=0;r=ID;    return false;}  else {    r=i->second.first;    t=i->second.second;    ffassert(r);    return true;}}void  mylex::Add(Key k,int r,aType t){   iterator ii= MotClef.find(k);  ffassert(ii==MotClef.end());  MotClef.insert(make_pair<const Key,Value>(k,make_pair(r,t))); }void mylex::dump(ostream & f ) {  const_iterator i=MotClef.begin(),e=MotClef.end();  for (;i != e;i++)    {      f << "      " << i->first << " " << i->second.first << " " <<  i->second.second->name() << endl;    }}   int mylex::EatCommentAndSpace(string *data){ // if data is !0 then add reading char in data // return the last read char c //  --------------------  int c,caux;  int incomment =0;  do {    incomment = 0;    c = source().peek();        // eat spaces     while (isspace(c) || c == 10 || c == 13 )     {      c = source().get();      if(c==10 || c==13) c='\n';      if (echo) cout << (char) c;      if(c=='\n') { linenumber++; if (echo) cout << setw(5) <<linenumber << " : " ;};                    if(data) *data+=char(c);       c=source().peek();      }          // eat comment      if(c=='/')       { c = source().get();        caux=source().peek();         if(caux =='/') incomment = 1;        else if (caux == '*' ) incomment = 2;        if(!incomment) source().putback(c);      }                if(incomment==1)       {        if (echo) cout << "//" ;source().get();        if(data) *data+="//";        do {c=source().get();                    if(c==10 || c==13) c='\n';        if (echo) cout << (char) c;        if(data) *data+=char(c);        if(c=='\n') { linenumber++; if (echo) cout << setw(5) <<linenumber << " : " ;};                     }      while( (c!= '\n') && (c!= 10)  && (c!= 13)  &&  ( c != EOF) );      }    else if(incomment==2)       {        if (echo) cout << "/*" ;        if(data) *data+="/*";        source().get();        do {              c=source().get();           if(c==10 || c==13) c='\n';          if (echo) cout << (char) c ;          if(data) *data+=char(c);          if(c=='\n') { linenumber++; if (echo) cout << setw(5) <<linenumber << " : " ;};                       caux = source().peek();        } while(c != EOF && !(c=='*' && caux=='/') ) ;                if(c != EOF)            {     c = source().get();          if (echo) cout << (char) c ;          if(data) *data+=char(c);                    }        else erreur( " Unterminated comment");      }  } while (incomment);  return c;}int mylex::basescan(){  //  extern long mpirank;     int c;  buf[0]=0;  buf[1]=0;  buf[2]=0;  buf[3]=0; // debut:  TheCurrentLine=linenumber;  // modif FH   if (firsttime)   {      firsttime=false;    if(echo) cout << setw(5) <<linenumber << " : " ;   }  EatCommentAndSpace();   c =source().get(); // the current char   char nc = source().peek(); // next char  buf[0]=c;  buf[1]=nc;  buf[2]=0;  int ret = c;  if (c == EOF)     {       //if (echo) cout << "ENDOFFILE "<< endl;      if (close() )  goto debut;       buf[0]=0;      return ENDOFFILE;}  else if (isdigit(c) || c=='.' && isdigit(nc)) {    //  a number    int i=1;    buf[0]=c;    bool real= (c=='.');            while ( isdigit(nc) && i< 50 ) buf[i++]=source().get(),nc=source().peek();    if (!real && (nc == '.')) real=true,buf[i++]=source().get(),nc=source().peek();    while ( isdigit(nc) && i< 50 ) buf[i++]=source().get(),nc=source().peek();    if (nc =='E' || nc =='e' || nc =='D' || nc =='d') {real=true;    buf[i++]=source().get(),nc=source().peek();    if (nc =='+' || nc =='-' || isdigit(nc))  buf[i++]=source().get(),nc=source().peek();    while ( isdigit(nc) && i< 50 ) buf[i++]=source().get(),nc=source().peek();    }    if (i>= 50)  erreur("Number to long");        buf[i]=0;    if (nc=='i' )       { buf[i++]=source().get(),buf[i]=0,plglval->dnum = atof(buf),ret=CNUM;}    else       if (real)        plglval->dnum = atof(buf),ret=DNUM;      else        plglval->lnum = atoi(buf),ret=LNUM;        if(lexdebug) cout << " NUM : " << buf  << " "<<endl;  }  else if (isalpha(c) || c=='\\')    {      ret =  ID;      int i;       for (i = 1; i < 256 && isalnum(source().peek()); i++)         buf[i]=source().get();      if (i == 256)         erreur ("Identifyier too long");      buf[i] = 0;          }  else  if (c=='"')    {      int i;      char cc;      for (     i = 0,cc=source().peek();                 i < 256 &&  (isprint(cc) && cc !='\n'  && cc !='"');                cc=source().peek(),++i                )         {                 if ( cc == '\\')  //   escape             {              cc= source().get();              cc= source().get();                    switch (cc) {              case 'n': buf[i]='\n';break;              case 'f': buf[i]='\f';break;              case 10:              case 13:		cc='\n';		linenumber++;		//if (echo) cout << setw(5) <<linenumber << " : " ;		              default : buf[i]=cc  ;break;                            }            }          else             buf[i] = source().get();        }      if (i == 256) erreur ("String too long");      buf[i] = 0;      if(source().get() != '"') erreur("End of String could not be found");      plglval->str = newcopy(buf);      if(lexdebug)  cout << "STRING=" << '"' << buf << '"' << endl;            ret= STRING;    }  else     {      ret = c;      switch(c) {              case '{':       case '%':       case '}':       case '(':       case ')':       case '[':       case ']':       case ',':       case ';':       case '#':         break;      case '*':         if (nc == '=') ret=MULEQ;               break;      case '/':         if (nc == '=') ret=DIVEQ;        break;        case '^':       case '~':       case '\'': //      case '_':       case '?':        break;      case '.':         if (nc == '*') ret = DOTSTAR;        else if (nc == '/') ret = DOTSLASH;        break;      case ':':         if (nc == '=') ret= SET;        break;      case '&':        if (nc == '&') ret= AND;        break;      case '|':        if (nc == '|') ret= OR;        break;      case '!':         if (nc == '=') ret=NE;        break;                case '<':        if (nc == '=') ret=LE;        if (nc == '<') ret=LTLT;        if (nc == '>') ret= NE;        break;      case '>':        if (nc == '=') ret=GE;          if (nc == '>') ret=GTGT;        break;        case '=':         if (nc == '=')           ret=EQ;        break;      case '-':         if (nc == '>') ret=ARROW;               if (nc == '-') ret=MOINSMOINS;          if (nc == '=') ret=MOINSEQ;             break;      case '+':         if (nc == '+') ret=PLUSPLUS;            if (nc == '=') ret=PLUSEQ;              break;      default:         cerr << "'" << (char) c << (char) nc << "' <=> " << (int) c << " is " ;        erreur (" Unexpected character");      }            if (ret!=c) source().get() ;      else buf[1] = 0;      strcpy(plglval->oper,buf);      if(lexdebug)  cout << "Special '" <<  plglval->oper << "' " << ret << " ";    }  typetoken=ret;   return ret;}int mylex::scan1(){  // extern long mpirank; // bool echo = mpirank == 0;   int ret= basescan();  if ( ret == ID)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?