00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <StreamCenter.hpp>
00021
00022 #include <Expression.hpp>
00023 #include <RealExpression.hpp>
00024 #include <BooleanExpression.hpp>
00025 #include <Vector3Expression.hpp>
00026
00027 #include <FunctionExpression.hpp>
00028 #include <FunctionExpressionConstant.hpp>
00029 #include <FunctionExpressionMeshReferences.hpp>
00030
00031 #include <MeshExpression.hpp>
00032
00033 #include <DomainExpression.hpp>
00034 #include <InsideExpression.hpp>
00035 #include <InsideListExpression.hpp>
00036
00037 #include <FieldExpression.hpp>
00038 #include <FieldExpressionList.hpp>
00039
00040 #include <BoundaryExpression.hpp>
00041 #include <BoundaryConditionExpression.hpp>
00042 #include <BoundaryConditionListExpression.hpp>
00043
00044 #include <PDEOperatorExpression.hpp>
00045
00046 #include <PDESystemExpression.hpp>
00047 #include <PDEEquationExpression.hpp>
00048
00049 #include <SolverOptionsExpression.hpp>
00050 #include <SubOptionListExpression.hpp>
00051 #include <SubOptionExpression.hpp>
00052
00053 #include <Instruction.hpp>
00054
00055 #include <TestFunctionExpressionList.hpp>
00056 #include <IntegratedExpression.hpp>
00057 #include <IntegratedOperatorExpression.hpp>
00058
00059 #include <LinearExpression.hpp>
00060 #include <MultiLinearExpression.hpp>
00061 #include <MultiLinearFormExpression.hpp>
00062
00063 #include <UnknownExpression.hpp>
00064 #include <UnknownListExpression.hpp>
00065
00066 #include <VariationalFormulaExpression.hpp>
00067 #include <VariationalProblemExpression.hpp>
00068
00069 #include <VariationalDirichletListExpression.hpp>
00070
00071 #include <OStreamExpressionList.hpp>
00072 #include <IStreamExpressionList.hpp>
00073
00074 #include <IStreamExpression.hpp>
00075
00076 #include <ScalarFunctionNormal.hpp>
00077
00078 #include <parse.ff.h>
00079
00080 #include <cstdlib>
00081 #include <cstring>
00082 #include <cctype>
00083
00084 #include <FFLexer.hpp>
00085
00086 #include <sstream>
00087
00088 #include <VariableLexerRepository.hpp>
00089
00090 #include <ParameterCenter.hpp>
00091
00092 void FFLexer::define(Lexer::KeyWordList& kw)
00093 {
00094 kw["x"] = XYZ;
00095 kw["y"] = XYZ;
00096 kw["z"] = XYZ;
00097 kw["double"] = DOUBLE;
00098 kw["extract"] = EXTRACT;
00099
00100 kw["function"] = FUNCTION;
00101 kw["dgfunction"] = DGFUNCTION;
00102 kw["femfunction"] = FEMFUNCTION;
00103 kw["sfunction"] = SFUNCTION;
00104
00105 kw["mesh"] = MESH;
00106 kw["octree"] = OCTREEMESH;
00107 kw["periodic"] = PERIODIC;
00108 kw["simplify"] = SIMPLIFY;
00109 kw["spectral"] = SPECTRALMESH;
00110 kw["structured"] = STRUCTMESH;
00111 kw["surface"] = SURFMESH;
00112 kw["tetrahedrize"] = TETRAHEDRIZE;
00113 kw["transform"] = TRANSFORM;
00114
00115
00116 kw["vector"] = VECTOR;
00117 kw["vertex"] = VECTOR;
00118
00119 kw["scene"] = SCENE;
00120 kw["domain"] = DOMAIN_;
00121
00122 kw["ofstream"] = OFSTREAM;
00123 kw["ifstream"] = IFSTREAM;
00124
00125
00126 kw["do"] = DO;
00127 kw["while"] = WHILE;
00128 kw["for"] = FOR;
00129 kw["if"] = IF;
00130 kw["else"] = ELSE;
00131
00132 kw["true"] = TRUEVALUE;
00133 kw["false"] = FALSEVALUE;
00134 kw["not"] = NOT;
00135 kw["and"] = AND;
00136 kw["or"] = OR;
00137 kw["xor"] = XOR;
00138
00139 kw["solve"] = SOLVE;
00140
00141 kw["div"] = DIV;
00142 kw["grad"] = GRAD;
00143 kw["dnu"] = DNU;
00144
00145 kw["int"] = INT;
00146
00147 kw["min"] = MINMAX;
00148 kw["max"] = MINMAX;
00149
00150 kw["convect"] = CONVECT;
00151
00152 kw["pde"] = PDEQ;
00153
00154 kw["dx"] = DXYZ;
00155 kw["dy"] = DXYZ;
00156 kw["dz"] = DXYZ;
00157
00158 kw["nx"] = NORMALCOMPONENT;
00159 kw["ny"] = NORMALCOMPONENT;
00160 kw["nz"] = NORMALCOMPONENT;
00161
00162 kw["in"] = IN;
00163 kw["on"] = ON;
00164 kw["by"] = BY;
00165 kw["using"] = USING;
00166
00167 kw["P0"] = DISCRETIZATIONTYPE;
00168 kw["P1"] = DISCRETIZATIONTYPE;
00169 kw["P2"] = DISCRETIZATIONTYPE;
00170
00171 kw["coarsemesh"] = COARSEMESH;
00172 kw["finemesh"] = FINEMESH;
00173
00174 kw["exit"] = EXIT;
00175
00176 kw["inside"] = INSIDE;
00177 kw["outside"] = OUTSIDE;
00178
00179 kw["cout"] = COUT;
00180 kw["cerr"] = CERR;
00181 kw["cin"] = CIN;
00182
00183 kw["read"] = READ;
00184 kw["save"] = SAVE;
00185 kw["plot"] = PLOT;
00186 kw["exec"] = EXEC;
00187 kw["cat"] = CAT;
00188
00189 kw["pov"] = POV;
00190
00191 kw["gmsh"] = FILEFORMAT;
00192 kw["medit"] = FILEFORMAT;
00193 kw["am_fmt"] = FILEFORMAT;
00194 kw["opendx"] = FILEFORMAT;
00195 kw["raw"] = FILEFORMAT;
00196 kw["vtk"] = FILEFORMAT;
00197
00198 kw["abs"] = CFUNCTION;
00199 kw["sin"] = CFUNCTION;
00200 kw["cos"] = CFUNCTION;
00201 kw["tan"] = CFUNCTION;
00202 kw["asin"] = CFUNCTION;
00203 kw["acos"] = CFUNCTION;
00204 kw["atan"] = CFUNCTION;
00205 kw["sqrt"] = CFUNCTION;
00206 kw["exp"] = CFUNCTION;
00207 kw["log"] = CFUNCTION;
00208
00209 kw["one"] = ONE;
00210 kw["reference"] = REFERENCE;
00211 kw["vertices"] = ITEMS;
00212 kw["elements"] = ITEMS;
00213
00214 kw["xmin"] = FACE;
00215 kw["xmax"] = FACE;
00216 kw["ymin"] = FACE;
00217 kw["ymax"] = FACE;
00218 kw["zmin"] = FACE;
00219 kw["zmax"] = FACE;
00220
00221 kw["dos"] = FILETYPE;
00222 kw["unix"] = FILETYPE;
00223 kw["mac"] = FILETYPE;
00224 kw["binary"] = FILETYPE;
00225
00226 kw["test"] = TESTS;
00227 }
00228
00230 FFLexer::FFLexer(std::istream& In,
00231 std::ostream& Out)
00232 : Lexer(In,Out)
00233 {
00234 FFLexer::define(__keyWordList);
00236 ParameterCenter::instance().get(__optionsKeyWords);
00237 }
00238
00239 void FFLexer::switchToContext(const FFLexer::Context context)
00240 {
00241 switch (context) {
00242 case (FFLexer::defaultContext): {
00243 __keyWordList["dx"] = DXYZ;
00244 __keyWordList["dy"] = DXYZ;
00245 __keyWordList["dz"] = DXYZ;
00246 break;
00247 }
00248 case (FFLexer::variationalContext): {
00249 __keyWordList["dx"] = DXYZOP;
00250 __keyWordList["dy"] = DXYZOP;
00251 __keyWordList["dz"] = DXYZOP;
00252 break;
00253 }
00254 default: {
00255 throw ErrorHandler(__FILE__,__LINE__,
00256 "should not reach that context",
00257 ErrorHandler::unexpected);
00258 }
00259 }
00260 }
00261
00265 int FFLexer::isKeyword(const std::string& word)
00266 {
00267 KeyWordList::iterator theKeyWord
00268 = __keyWordList.find(word.c_str());
00269
00270 if(theKeyWord != __keyWordList.end()) {
00271 switch (theKeyWord->second) {
00272 case FILETYPE: {
00273 fflval.fileType = FileDescriptor::fileType(word.c_str());
00274 break;
00275 }
00276 case FILEFORMAT: {
00277 fflval.formatType = FileDescriptor::formatType(word.c_str());
00278 break;
00279 }
00280 case CFUNCTION:
00281 case DXYZ:
00282 case DXYZOP:
00283 case FACE:
00284 case ITEMS:
00285 case MINMAX:
00286 case XYZ: {
00287 fflval.str = new char[strlen(word.c_str())+1];
00288 strcpy (fflval.str, word.c_str());
00289 break;
00290 }
00291 case NORMALCOMPONENT: {
00292 const char* c = word.c_str();
00293 if (std::strcmp(c,"nx") == 0) {
00294 fflval.normalComponent = ScalarFunctionNormal::x;
00295 break;
00296 }
00297 if (std::strcmp(c,"ny") == 0) {
00298
00299 fflval.normalComponent = ScalarFunctionNormal::y;
00300 break;
00301 }
00302 if (std::strcmp(c,"nz") == 0) {
00303 fflval.normalComponent = ScalarFunctionNormal::z;
00304 break;
00305 }
00306
00307 throw ErrorHandler(__FILE__,__LINE__,
00308 "unexpected discretization type",
00309 ErrorHandler::unexpected);
00310 }
00311 case DISCRETIZATIONTYPE: {
00312 const char* c = word.c_str();
00313 if (std::strcmp(c,"P0") == 0) {
00314 fflval.discretizationType = ScalarDiscretizationTypeBase::lagrangianFEM0;
00315 break;
00316 }
00317 if (std::strcmp(c,"P1") == 0) {
00318 fflval.discretizationType = ScalarDiscretizationTypeBase::lagrangianFEM1;
00319 break;
00320 }
00321 if (std::strcmp(c,"P2") == 0) {
00322 fflval.discretizationType = ScalarDiscretizationTypeBase::lagrangianFEM2;
00323 break;
00324 }
00325 if (std::strcmp(c,"Legendre") == 0) {
00326 fflval.discretizationType = ScalarDiscretizationTypeBase::spectralLegendre;
00327 break;
00328 }
00329
00330 throw ErrorHandler(__FILE__,__LINE__,
00331 "unexpected discretization type",
00332 ErrorHandler::unexpected);
00333 }
00334 default:{
00335 ;
00336 }
00337 }
00338
00339 return theKeyWord->second;
00340 }
00341 return -1;
00342 }
00343
00347 int FFLexer::isOption(const std::string& word)
00348 {
00349 IdentifierSet::iterator theKeyWord
00350 = __optionsKeyWords.find(word.c_str());
00351 if(theKeyWord != __optionsKeyWords.end()) {
00352 return OPTION;
00353 }
00354 return -1;
00355 }
00356
00361 int FFLexer::isVariable(const std::string& word)
00362 {
00363 const int token = VariableLexerRepository::instance().find(word);
00364 if (token != -1) {
00365
00366
00367
00368 fflval.str = new char[strlen(word.c_str())+1];
00369 strcpy(fflval.str,word.c_str());
00370 }
00371 return token;
00372 }
00373
00375 int FFLexer::yylex()
00376 {
00377 char readChar = ' ';
00378 in.unsetf(std::ios::skipws);
00379
00380 while ((in)&&(isspace(readChar))) {
00381 in >> readChar;
00382 if (readChar=='\n')
00383 linenumber++;
00384 }
00385
00386 char nextChar = in.peek();
00387
00388 if (in) {
00389
00390
00391 if (isdigit(readChar) || ((readChar=='.') && isdigit(nextChar))) {
00392 in.unget();
00393
00394 if (in >> fflval.value) {
00395 std::stringstream is;
00396 is << fflval.value << std::ends;
00397 yytext = is.str();
00398
00399 return NUM;
00400 } else {
00401 throw ErrorHandler(__FILE__,__LINE__,
00402 "not implemented",
00403 ErrorHandler::unexpected);
00404 }
00405 }
00406
00407 if (isalpha(readChar) or (readChar == '_')) {
00408 std::string is;
00409 while (isalnum(readChar) or (readChar == '_')) {
00410 is += readChar;
00411 in >> readChar;
00412 }
00413 in.unget();
00414
00415 yytext = is;
00416
00417 int TOKEN = isKeyword(yytext);
00418 if (TOKEN != -1) {
00419 return TOKEN;
00420 }
00421
00422
00423
00424 TOKEN = isOption(yytext);
00425 if(TOKEN != -1) {
00426 fflval.str = new char[strlen(yytext.c_str())+1];
00427 strcpy (fflval.str, yytext.c_str());
00428 return TOKEN;
00429 }
00430
00431
00432 TOKEN = isVariable(yytext);
00433 if (TOKEN != -1) {
00434 return TOKEN;
00435 } else {
00436 fflval.aString = new std::string(yytext);
00437 return NAME;
00438 }
00439
00440
00441 }
00442
00443
00444 switch(readChar) {
00445 case '/': {
00446 if (nextChar == '/') {
00447 while ((readChar != '\n') and (not(in.eof())))
00448 in >> readChar;
00449 in.unget();
00450 return yylex();
00451 }
00452
00453 if (nextChar == '*') {
00454 bool endOfComment = false;
00455 size_t commentLines = 0;
00456
00457 in >> readChar;
00458 while (!endOfComment) {
00459 if(in >> readChar) {
00460 switch (readChar) {
00461 case '*': {
00462 if (in.peek() == '/') {
00463 endOfComment = true;
00464 }
00465 break;
00466 }
00467 case '\n': {
00468 commentLines++;
00469 break;
00470 }
00471 }
00472 } else {
00473 throw ErrorHandler(__FILE__,linenumber,
00474 "opened comment never closed",
00475 ErrorHandler::compilation);
00476 }
00477 }
00478 in >> readChar;
00479
00480 linenumber += commentLines;
00481 return yylex();
00482 }
00483 }
00484 case '+': {
00485 if (nextChar == '+') {
00486 in >> readChar;
00487 return INCR;
00488 }
00489 break;
00490 }
00491 case '{': {
00492 yytext = "{";
00493 return OPENBLOCK;
00494 }
00495 case '}': {
00496 yytext = "}";
00497 return CLOSEBLOCK;
00498 }
00499 case '-': {
00500 if (nextChar == '-') {
00501 in >> readChar;
00502 yytext = "--";
00503 return DECR;
00504 }
00505 break;
00506 }
00507 case '<':{
00508 if (nextChar == '=') {
00509 in >> readChar;
00510 yytext = "<=";
00511 return LEQ;
00512 } else if (nextChar == '<') {
00513 in >> readChar;
00514 yytext = "<<";
00515 return LRAFTER;
00516 }
00517 yytext = "<";
00518 return LT;
00519 }
00520 case '>':{
00521 if (nextChar == '=') {
00522 in >> readChar;
00523 yytext = ">=";
00524 return GEQ;
00525 } else if (nextChar == '>') {
00526 in >> readChar;
00527 yytext = ">>";
00528 return RRAFTER;
00529 }
00530 yytext = ">";
00531 return GT;
00532 }
00533 case '=': {
00534 if (nextChar == '=') {
00535 in >> readChar;
00536 yytext = "==";
00537 return EQ;
00538 }
00539 break;
00540 }
00541 case '!': {
00542 if (nextChar == '=') {
00543 in >> readChar;
00544 yytext = "!=";
00545 return NE;
00546 }
00547 return NOT;
00548 }
00549 case '|': {
00550 if (nextChar == '|') {
00551 yytext = "||";
00552 in >> readChar;
00553 return OR;
00554 }
00555 break;
00556 }
00557 case '&': {
00558 if (nextChar == '&') {
00559 in >> readChar;
00560 yytext = "&&";
00561 return AND;
00562 }
00563 break;
00564 }
00565
00566 case ')': {
00567 if (declarationToken == SOLVE)
00568 declarationToken = -1;
00569 return ')';
00570 }
00571
00572 case '"': {
00573 bool endOfString = false;
00574 size_t stringLines = 0;
00575 std::stringstream is;
00576
00577 while (!endOfString) {
00578 if(in >> readChar) {
00579 switch (readChar) {
00580 case '"': {
00581 endOfString = true;
00582 break;
00583 }
00584 case '\n': {
00585 stringLines++;
00586 is << '\n';
00587 break;
00588 }
00589 case '\\': {
00590 int peekC = in.peek();
00591 switch (peekC) {
00592 case 'n': {
00593 is << '\n';
00594 in >> readChar;
00595 break;
00596 }
00597 case 't': {
00598 is << '\t';
00599 in >> readChar;
00600 break;
00601 }
00602 case 'v': {
00603 is << '\v';
00604 in >> readChar;
00605 break;
00606 }
00607 case 'b': {
00608 is << '\b';
00609 in >> readChar;
00610 break;
00611 }
00612 case 'r': {
00613 is << '\r';
00614 in >> readChar;
00615 break;
00616 }
00617 case 'f': {
00618 is << '\f';
00619 in >> readChar;
00620 break;
00621 }
00622 case 'a': {
00623 is << '\a';
00624 in >> readChar;
00625 break;
00626 }
00627 case '\'': {
00628 is << '\'';
00629 in >> readChar;
00630 break;
00631 }
00632 case '"': {
00633 is << '"';
00634 in >> readChar;
00635 break;
00636 }
00637 case '\\': {
00638 is << '\\';
00639 in >> readChar;
00640 break;
00641 }
00642 default: {
00643 throw ErrorHandler(__FILE__,linenumber,
00644 "unknown escape sequence",
00645 ErrorHandler::compilation);
00646 }
00647 }
00648 break;
00649 }
00650 default: {
00651 is << readChar;
00652 }
00653 }
00654 } else {
00655 throw ErrorHandler(__FILE__,linenumber,
00656 "opened string never closed",
00657 ErrorHandler::compilation);
00658 }
00659 }
00660 is << std::ends;
00661
00662 fflval.str = new char[is.str().size()+1];
00663 strcpy (fflval.str, is.str().c_str());
00664
00665 linenumber += stringLines;
00666
00667 return STRING;
00668 }
00669
00670 }
00671
00672
00673 yytext = readChar;
00674 return readChar;
00675 } else {
00676 return EOF;
00677 }
00678
00679 return 0;
00680 }
00681