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