• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

C:/CVUT/diplomka/Automata_editor/sources/parser.cpp

Go to the documentation of this file.
00001 #include "constants.h"
00002 
00003 #include "parser.h"
00004 #include "editor.h"
00005 #include "dialogs.h"
00006 #include "state.h"
00007 #include "stateManager.h"
00008 #include "label.h"
00009 #include "transition.h"
00010 #include "oneStateTransition.h"
00011 #include "twoStatesTransition.h"
00012 #include "transitionManager.h"
00013 #include "transforms.h"
00014 
00015 #include <QFile>
00016 #include <QMessageBox>
00017 #include <QApplication>
00018 #include <QRect>
00019 
00020 #include <QTextEdit> // due to report dialog
00021 #include <QVBoxLayout>
00022 #include <QPushButton>
00023 
00024 #include <QtDebug>
00025 
00026 // exceptions
00027 enum Exceptions{U_EOI, U_TOKEN, NO_STATE, STATE_EXIST, BAD_STATE_NAME, BAD_GRID, U_ERR};
00028 
00029 // TODO: check situation when something as "\textstyle aaa" is in label field, 
00030 //       it seems that space between is currently dropped!!!
00031 
00032 using namespace VaucansonKeywords;
00033 
00034 //<-- LexAn ---------------------------------------------------------------------------
00035 
00036 #define ADD_KEYWORD(keyword, token) keywordMap[keyword] = token
00037 
00038 LexAn::TKeywordMap LexAn::keywordMap;
00039 
00040 void LexAn::initialize()
00041 {
00042     if (keywordMap.contains("begin"))
00043         return;
00044     
00045     ADD_KEYWORD("VCPut", kwVCPut);
00046     ADD_KEYWORD("begin", kwBegin);
00047     ADD_KEYWORD("end",kwEnd);
00048     ADD_KEYWORD("State",kwState);
00049     ADD_KEYWORD("FinalState",kwFinalState);
00050     ADD_KEYWORD("StateVar", kwStateVar);
00051     ADD_KEYWORD("FinalStateVar", kwFinalStateVar);
00052     ADD_KEYWORD("Initial", kwInitial);
00053     ADD_KEYWORD("Final", kwFinal);
00054     ADD_KEYWORD("LoopN", kwLoopN);
00055     ADD_KEYWORD("LoopS", kwLoopS);
00056     ADD_KEYWORD("LoopE", kwLoopE);
00057     ADD_KEYWORD("LoopW", kwLoopW);
00058     ADD_KEYWORD("LoopNE", kwLoopNE);
00059     ADD_KEYWORD("LoopNW", kwLoopNW);
00060     ADD_KEYWORD("LoopSE", kwLoopSE);
00061     ADD_KEYWORD("LoopSW", kwLoopSW);
00062     ADD_KEYWORD("CLoopN", kwCLoopN);
00063     ADD_KEYWORD("CLoopS", kwCLoopS);
00064     ADD_KEYWORD("CLoopE", kwCLoopE);
00065     ADD_KEYWORD("CLoopW", kwCLoopW);
00066     ADD_KEYWORD("CLoopNE", kwCLoopNE);
00067     ADD_KEYWORD("CLoopNW", kwCLoopNW);
00068     ADD_KEYWORD("CLoopSE", kwCLoopSE);
00069     ADD_KEYWORD("CLoopSW", kwCLoopSW);
00070     ADD_KEYWORD("LoopVarN", kwLoopVarN);
00071     ADD_KEYWORD("LoopVarS", kwLoopVarS);
00072     ADD_KEYWORD("VarLoopOn", kwVarLoopOn);
00073     ADD_KEYWORD("VarLoopOff", kwVarLoopOff);
00074     ADD_KEYWORD("EdgeL", kwEdgeL);
00075     ADD_KEYWORD("EdgeR", kwEdgeR);
00076     ADD_KEYWORD("ArcL", kwArcL);
00077     ADD_KEYWORD("ArcR", kwArcR);
00078     ADD_KEYWORD("LArcL", kwLArcL);
00079     ADD_KEYWORD("LArcR", kwLArcR);
00080     ADD_KEYWORD("VArcL", kwVArcL);
00081     ADD_KEYWORD("VArcR", kwVArcR);
00082     ADD_KEYWORD("VCurveL", kwVCurveL);
00083     ADD_KEYWORD("VCurveR", kwVCurveR);
00084     ADD_KEYWORD("LabelL", kwLabelL);
00085     ADD_KEYWORD("LabelR", kwLabelR);
00086     ADD_KEYWORD("DimState", kwDimState);
00087     ADD_KEYWORD("RstState", kwRstState);
00088     ADD_KEYWORD("DimEdge", kwDimEdge);
00089     ADD_KEYWORD("RstEdge", kwRstEdge);
00090     ADD_KEYWORD("ShowGrid", kwShowGrid);
00091     ADD_KEYWORD("ShowFrame", kwShowFrame);
00092     ADD_KEYWORD("HideGrid", kwHideGrid);
00093     ADD_KEYWORD("HideFrame", kwHideFrame);
00094     ADD_KEYWORD("StateLineDouble", kwStateLineDouble);
00095     ADD_KEYWORD("StateLineSimple", kwStateLineSimple);
00096     ADD_KEYWORD("EdgeLineDouble", kwEdgeLineDouble);
00097     ADD_KEYWORD("EdgeLineSimple", kwEdgeLineSimple);
00098     ADD_KEYWORD("EdgeBorder", kwEdgeBorder);
00099     ADD_KEYWORD("EdgeBorderOff", kwEdgeBorderOff);
00100     ADD_KEYWORD("SetStateLineStyle", setStateLineStyle);
00101     ADD_KEYWORD("SetStateLineWidth", setStateLineWidth);
00102     ADD_KEYWORD("SetStateLineColor", setStateLineColor);
00103     ADD_KEYWORD("SetStateLabelColor", setStateLabelColor);
00104     ADD_KEYWORD("SetStateLabelScale", setStateLabelScale);
00105     ADD_KEYWORD("SetStateFillStatus", setStateFillStatus);
00106     ADD_KEYWORD("SetStateFillColor", setStateFillColor);
00107     ADD_KEYWORD("SetEdgeLineStyle", setEdgeLineStyle);
00108     ADD_KEYWORD("SetEdgeLineWidth", setEdgeLineWidth);
00109     ADD_KEYWORD("SetEdgeLineColor", setEdgeLineColor);
00110     ADD_KEYWORD("SetEdgeLabelColor", setEdgeLabelColor);
00111     ADD_KEYWORD("SetEdgeLabelScale", setEdgeLabelScale);
00112     ADD_KEYWORD("ChgStateLineStyle", chgStateLineStyle);
00113     ADD_KEYWORD("ChgStateLineWidth", chgStateLineWidth);
00114     ADD_KEYWORD("ChgStateLineColor", chgStateLineColor);
00115     ADD_KEYWORD("ChgStateLabelColor", chgStateLabelColor);
00116     ADD_KEYWORD("ChgStateLabelScale", chgStateLabelScale);
00117     ADD_KEYWORD("ChgStateFillStatus", chgStateFillStatus);
00118     ADD_KEYWORD("ChgStateFillColor", chgStateFillColor);
00119     ADD_KEYWORD("ChgEdgeLineStyle", chgEdgeLineStyle);
00120     ADD_KEYWORD("ChgEdgeLineWidth", chgEdgeLineWidth);
00121     ADD_KEYWORD("ChgEdgeLineColor", chgEdgeLineColor);
00122     ADD_KEYWORD("ChgEdgeLabelColor", chgEdgeLabelColor);
00123     ADD_KEYWORD("ChgEdgeLabelScale", chgEdgeLabelScale);
00124     ADD_KEYWORD("RstStateLineStyle", rstStateLineStyle);
00125     ADD_KEYWORD("RstStateLineWidth", rstStateLineWidth);
00126     ADD_KEYWORD("RstStateLineColor", rstStateLineColor);
00127     ADD_KEYWORD("RstStateLabelColor", rstStateLabelColor);
00128     ADD_KEYWORD("RstStateLabelScale", rstStateLabelScale);
00129     ADD_KEYWORD("RstStateFillStatus", rstStateFillStatus);
00130     ADD_KEYWORD("RstStateFillColor", rstStateFillColor);
00131     ADD_KEYWORD("RstEdgeLineStyle", rstEdgeLineStyle);
00132     ADD_KEYWORD("RstEdgeLineWidth", rstEdgeLineWidth);
00133     ADD_KEYWORD("RstEdgeLineColor", rstEdgeLineColor);
00134     ADD_KEYWORD("RstEdgeLabelColor", rstEdgeLabelColor);
00135     ADD_KEYWORD("RstEdgeLabelScale", rstEdgeLabelScale);
00136     ADD_KEYWORD("FixDimState", fixDimState);
00137     ADD_KEYWORD("FixStateLineDouble", fixStateLineDouble);
00138     ADD_KEYWORD("FixDimEdge", fixDimEdge);
00139     ADD_KEYWORD("FixEdgeBorder", fixEdgeBorder);
00140     ADD_KEYWORD("FixEdgeLineDouble", fixEdgeLineDouble);
00141 }
00142 
00143 LexAn::LexAn() : fileOpened(false), input('w'), lineNumber(1), lineIndex(0), lineLength(0)
00144 {
00145     initialize();
00146 }
00147 
00148 LexAn::~LexAn()
00149 {
00150     if (inFile)
00151     {
00152         inFile->close();
00153         delete inFile;
00154     }
00155 }
00156 
00157 bool LexAn::openFile(const QString &fn)
00158 {
00159     inFile = new QFile(fn);
00160     if (!inFile->open(QIODevice::ReadOnly))
00161     {
00162         DBGLOG_LEX("file couldn't be opened!");
00163         return false;
00164     }
00165     fileOpened = true;
00166 
00167     DBGLOG_LEX("file is opened");
00168     return true;
00169 }
00170 
00171 char LexAn::readChar()
00172 {
00173     if (lineIndex >= lineLength) // necessary to read next line
00174     {
00175         lineIndex = 0;
00176         lineLength = inFile->readLine(line, sizeof(line));        
00177         if (lineLength == -1)
00178         {
00179             input = 'e';
00180             return input;
00181         }
00182     }
00183     character = line[lineIndex++];
00184     if((character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z'))
00185     {
00186         input = 'c';
00187     }
00188     else if(character >= '0' && character <= '9')
00189     {
00190         input = 'n';
00191     }
00192     else if (character == '\n')
00193     {   //end of line
00194         lineNumber++;        
00195         input = 'l';
00196     }
00197     else if(character <= ' ')
00198     {
00199         input = 'w';
00200     }
00201     else
00202     {
00203         input = character;
00204     }
00205     return input;
00206 }
00207 
00208 QString LexAn::readStringBetween(const QChar &opening, const QChar &closing, bool allowMatching)
00209 {
00210     Token returnToken = EOI;
00211     switch(closing.toAscii())
00212     {
00213     case '}':
00214         returnToken = RBRACE;
00215         break;
00216     case ']':
00217         returnToken = RBRACKET;
00218         break;
00219     default:
00220         Q_ASSERT(0 && "unexpected closing character!!!");
00221         break;
00222     }
00223 
00224     QString str;
00225     int balance = 1;
00226     while (input != 'e')
00227     {
00228         if (opening == character) balance++;
00229         else if (closing == character)
00230         {
00231             balance--;
00232             if (balance == 0 || !allowMatching)
00233             {
00234                 token = returnToken;
00235                 tokenData = closing;
00236                 readChar();
00237                 return str;
00238             }
00239         }
00240 
00241         str += character;
00242         readChar();
00243     }
00244     RELLOG("Unbalanced " << opening << " and " << closing << " pair!");
00245     token = EOI;
00246     return str;
00247 }
00248 
00249 Token LexAn::readToken()
00250 {
00251   if (!fileOpened) return EOI;
00252   bool readed = false; 
00253   while(input == 'w' || input == 'l') readChar();
00254 
00255   DBGLOG_LEX("next token input: " << input);
00256   while (!readed){
00257     tokenData = "";
00258     switch(input){
00259     case 'e': // end of file 
00260       token = EOI;
00261       readed = true;
00262       DBGLOG_LEX("EOI");
00263       break;
00264     case '%': // comment
00265       while (readChar() != 'l' && input != 'e') { // while not end of line, read a store comment
00266         tokenData += character;
00267       }
00268 
00269       DBGLOG_LEX("COMMENT: " << tokenData);
00270       token = COMMENT;
00271       readed = true;
00272       break;
00273     case 'l': // discard whitespaces
00274     case 'w':
00275       while(readChar() == 'w' || input == 'l'){}
00276       break;
00277     case '\\': // should be keyword
00278       while (readChar() == 'c'){ // while input is char
00279         tokenData += character;
00280       } 
00281       token = keyWordTest(tokenData); // control if keyword
00282       if (token == ERR) {
00283 
00284     DBGLOG_LEX("not keyword" << tokenData);
00285     tokenData = "\\" + tokenData; // special symbol (e.g. greek symbol)
00286     token = SPECIAL; // strings as \sigma, \varepsilon
00287       }
00288       if (token == kwBegin){ // looking for kwBeginVCPicture 
00289         if (input == '{'){
00290           tokenData = "";
00291           while (readChar() == 'c'){
00292             tokenData += character;
00293           }
00294           if (tokenData == "VCPicture" && input == '}'){
00295             readChar(); // '}' is too part of kwBeginVCPicture
00296             token = kwBeginVCPicture;
00297 
00298             DBGLOG_LEX("VCPicture founded!");
00299           }
00300           else {
00301             token = ERR;
00302           }
00303         } // if {
00304       } // if kwBegin
00305       readed = true;
00306       break;
00307     case '{': // LBRACE
00308       token = LBRACE;
00309       readChar();
00310       readed = true;
00311       break;
00312     case '}': // RBRACE
00313       token = RBRACE;
00314       readChar();
00315       readed = true;
00316       break;
00317     case '[': //LBRACKET
00318       token = LBRACKET;
00319       readChar();
00320       readed = true;
00321       break;
00322     case ']': //RBRACKET
00323       token = RBRACKET;
00324       readChar();
00325       readed = true;
00326       break;
00327     case '(': //LPAR
00328       token = LPAR;
00329       readChar();
00330       readed = true;
00331       break;
00332     case ')': //RPAR
00333       token = RPAR;
00334       readChar();
00335       readed = true;
00336       break;
00337     case ',': // COMMA
00338       token = COMMA;  
00339       readChar();
00340       readed = true;
00341       break;
00342     case '-':
00343       token = MINUS;  
00344       readChar();
00345       readed = true;
00346       break;
00347     case '=':
00348       token = EQUAL;  
00349       readChar();
00350       readed = true;
00351       break;
00352     case '_':
00353       token = UNDERLINE;
00354       readChar();
00355       readed = true;
00356       break;
00357     case '.':
00358       tokenData += character;
00359       if (readChar() == 'n'){
00360         tokenData += character;
00361         while (readChar() == 'n'){
00362           tokenData += character;
00363         }
00364         token = FLOAT;
00365         readed = true;
00366         break;
00367       }
00368       token = DOT;
00369       readed = true;
00370       break;
00371     case 'n': // number or float
00372       tokenData = character;
00373       while (readChar() == 'n'){
00374         tokenData += character;
00375       }
00376       if (input == '.'){
00377         tokenData += character;
00378         while (readChar() == 'n')
00379           tokenData += character;
00380         token = FLOAT;
00381 
00382         DBGLOG_LEX("FLOAT" << tokenData);
00383       }
00384       else{
00385         token = NUMB;
00386 
00387         DBGLOG_LEX("NUMB" << tokenData);
00388       }      
00389       readed = true;
00390       break;
00391     case 'c': // ident - label, name, or constant symbol (as arcangle, angleA, ...)
00392       tokenData = character;
00393       while (readChar() == 'c' || input == 'n'){
00394         tokenData += character;
00395       }
00396       token = IDENT;
00397 
00398       DBGLOG_LEX("IDENT" << tokenData);
00399       readed = true;
00400       break;
00401     default:
00402       // return the other character
00403       tokenData = character;
00404       token = OTHER;
00405       readed = true;
00406       readChar();
00407     }
00408   }
00409   return token;
00410 }
00411 
00412 Token LexAn::keyWordTest(const QString &tokenData)
00413 {
00414     if (keywordMap.contains(tokenData))
00415     {
00416         DBGLOG_LEX(keywordMap[tokenData]);
00417         return keywordMap[tokenData];
00418     }
00419     return ERR; // unknown keyword
00420 }
00421 
00422 QString LexAn::getTokenData()
00423 {
00424     return tokenData;
00425 }
00426 
00427 Token LexAn::getToken()
00428 {
00429     return token;
00430 }
00431 
00432 int LexAn::getLineNumber()
00433 {
00434     return lineNumber;
00435 }
00436 
00437 //--------------------------------------------------------------------------- LexAn -->
00438 
00439 
00440 
00441 //<-- Parser --------------------------------------------------------------------------
00442 
00443 #define IF_CAN_CHANGE_EDITOR(x) if (m_canChangeEditor) {x}
00444 
00445 Parser::Parser(Editor *editor, bool canChangeEditor)
00446 : editor(editor), lexan(NULL), m_canChangeEditor(canChangeEditor), lastTr(NULL), err_count(0), war_count(0),
00447   dimState(false), dimEdge(false), edgeBorder(false), stateLineDouble(false), varLoop(false)
00448 {
00449     resetParams();
00450     
00451     // default in Vaucanson-G
00452     IF_CAN_CHANGE_EDITOR
00453     (
00454         editor->showGrid = false;
00455         editor->showFrame = false;  
00456         emit editor->showChanged(false, false);
00457     )
00458 }
00459 
00460 void Parser::resetParams()
00461 {
00462     // all parameters - to save
00463     stateLineStyle = DEF_LINE_STYLE;
00464     stateLineWidth = 1;
00465     stateLineColor = DEF_COLOR;
00466     stateLabelColor = DEF_COLOR;
00467     stateLabelScale = 1;
00468     stateFillStatus = DEF_FILL_STATUS;
00469     stateFillColor = DEF_FILL_COLOR;
00470     // state parametres preset
00471     stateLineDoubleCoef = DEF_STATE_LINE_DBL_COEF;
00472     stateLineDoubleSep = DEF_STATE_LINE_DBL_SEP;
00473     // state parametres dimmed
00474     dimStateLineStyle = DEF_DIM_LINE_STYLE;
00475     dimStateLineColor = DEF_DIM_COLOR;
00476     dimStateLineCoef = DEF_DIM_STATE_LINE_COEF;
00477     dimStateLabelColor = DEF_DIM_COLOR;
00478     dimStateFillColor = DEF_DIM_FILL_COLOR;
00479     // transition parameters
00480     edgeLineStyle = DEF_LINE_STYLE;
00481     edgeLineWidth = 1;
00482     edgeLineColor = DEF_COLOR;
00483     edgeLabelColor = DEF_COLOR;
00484     edgeLabelScale = 1;
00485     edgeLineDblStatus = DEF_EDGE_LINE_DBL_STATUS;
00486     // transition parameters preset
00487     edgeLineBorderCoef = DEF_EDGE_LINE_BORDER_COEF;
00488     edgeLineBorderColor = DEF_EDGE_LINE_BORDER_COLOR;
00489     edgeLineDblCoef = DEF_EDGE_LINE_DBL_COEF;
00490     edgeLineDblSep = DEF_EDGE_LINE_DBL_SEP;
00491     // transition parameters dimmed
00492     dimEdgeLineStyle = DEF_DIM_LINE_STYLE;
00493     dimEdgeLineColor = DEF_DIM_COLOR;
00494     dimEdgeLineCoef = DEF_DIM_EDGE_LINE_COEF;
00495     dimEdgeLabelColor = DEF_DIM_COLOR;
00496 }
00497 
00498 Parser::~Parser()
00499 {
00500     if (lexan) delete lexan; // close file - this shouldn't be never done, only for sure
00501 }
00502 
00503 void Parser::matching(Token token, bool end)
00504 {
00505     if (lexan->getToken() != token)
00506     {
00507         errorReportUTOKEN();
00508         throw U_TOKEN;
00509     }
00510     if (lexan->readToken() == EOI && !end)
00511     {
00512         DBGLOG_PAR("End");
00513         throw U_EOI;
00514     }
00515 }
00516 
00517 void Parser::checkTrParam(Transition *tr){
00518   if (edgeLineStyle != editor->edgeLineStyle) tr->edgeLineStyle = edgeLineStyle;
00519   if (edgeLineWidth != 1) tr->setEdgeLineWidth(edgeLineWidth);
00520   if (edgeLineColor != editor->edgeLineColor) tr->edgeLineColor = edgeLineColor;
00521   if (edgeLabelColor != editor->edgeLabelColor) tr->edgeLabelColor = edgeLabelColor;
00522   if (edgeLabelScale != 1) {
00523     tr->setEdgeLabelScale(edgeLabelScale);
00524   }
00525   if (edgeLineDblStatus != editor->edgeLineDblStatus) tr->edgeLineDblStatus = edgeLineDblStatus;
00526   
00527   if (edgeLineDblCoef != DEF_EDGE_LINE_DBL_COEF) tr->edgeLineDblCoef = edgeLineDblCoef;
00528   if (edgeLineDblSep != DEF_EDGE_LINE_DBL_SEP) tr->edgeLineDblSep = edgeLineDblSep;
00529   if (edgeLineBorderCoef != DEF_EDGE_LINE_BORDER_COEF) tr->edgeLineBorderCoef = edgeLineBorderCoef;
00530   if (edgeLineBorderColor != DEF_EDGE_LINE_BORDER_COLOR) tr->edgeLineBorderColor = edgeLineBorderColor;
00531   
00532   if (dimEdgeLineStyle != DEF_DIM_LINE_STYLE) tr->dimEdgeLineStyle = dimEdgeLineStyle;
00533   if (dimEdgeLineCoef != DEF_DIM_EDGE_LINE_COEF) tr->setDimEdgeLineCoef(dimEdgeLineCoef);
00534   if (dimEdgeLineColor != DEF_DIM_COLOR) tr->dimEdgeLineColor = dimEdgeLineColor;
00535   if (dimEdgeLabelColor != DEF_DIM_COLOR) tr->dimEdgeLabelColor = dimEdgeLabelColor;
00536   tr->adjust();
00537 }
00538 
00539 bool Parser::kwTest(Token token)
00540 {
00541     return (eFirstKw <= token && token <= eLastKw);
00542 }
00543 
00544 void Parser::resetStateParams(){
00545   stateLineStyle = DEF_LINE_STYLE;
00546   stateLineWidth = 1;
00547   stateLineColor = DEF_COLOR;
00548   stateLabelColor = DEF_COLOR;
00549   stateLabelScale = 1;
00550   stateFillStatus = DEF_FILL_STATUS;
00551   stateFillColor = DEF_FILL_COLOR;
00552 }
00553 
00554 void Parser::resetTrParams()
00555 {
00556     edgeLineStyle = DEF_LINE_STYLE;
00557     edgeLineWidth = 1;
00558     edgeLineColor = DEF_COLOR;
00559     edgeLabelColor = DEF_COLOR;
00560     edgeLabelScale = 1;
00561     edgeLineDblStatus = DEF_EDGE_LINE_DBL_STATUS;
00562 }
00563 
00564 
00565 
00566 // static methods
00567 
00568 bool Parser::checkNameCorrectness(const QString &name, QString *error)
00569 {
00570     // TODO: fix this method to check all possible problems, but which are they? :)
00571     if (name.contains(QRegExp("(?:\\[|\\]|,)")))
00572     {
00573         if (error) *error = "Characters '[', ']' and ',' are not allowed in state name due to VauCanSon-G format!";
00574         return false;
00575     }
00576 
00577     return true;
00578 }
00579 
00580 
00581 
00582 // recursive descent
00583 
00584 bool Parser::run(const QString &filename, QList<State*> &stateList, QRect &gridRect)
00585 {
00586     // reset info
00587     lexan = new LexAn();
00588     report.clear();
00589     err_count = 0;
00590     war_count = 0;
00591 
00592     if(lexan->openFile(filename))
00593     {
00594         try
00595         {
00596             lexan->readToken(); // read first token
00597             File();
00598         }  
00599         catch (Exceptions v)
00600         {
00601             switch (v)
00602             {
00603             case U_EOI: 
00604                 report << QString("%1: Error %2 - Unexpected end of file!").arg(lexan->getLineNumber()).arg(++err_count);
00605                 break;
00606             case BAD_GRID:
00607                 report << QString("%1: Error %2 - Invalid GridRect proportion!").arg(lexan->getLineNumber()).arg(++err_count);
00608                 break;
00609             case U_TOKEN:
00610                 // message is added to report list in Parser::matching
00611                 break; 
00612             default:
00613                 report << QString("%1: Error %2 - Unknown error").arg(lexan->getLineNumber()).arg(++err_count);
00614             }
00615         }
00616     }  
00617     else report << QString("File %1 couldn't be opened!").arg(filename);
00618 
00619     stateList = m_stateMap.values();
00620     gridRect = m_gridRect;
00621 
00622     m_stateMap.clear();
00623     m_gridRect = QRect();
00624 
00625     delete lexan; lexan = NULL;
00626 
00627     if (report.isEmpty() && !err_count && !war_count)
00628     {
00629         report << "VCPicture loaded sucessfully!"
00630                << "-------------------------"
00631                << "<b>Errors: 0, Warnings: 0</b>";
00632         return true;
00633     }
00634     else
00635     {
00636         report         << "------------------------------"; // for html coding, must be join("<br>"), no "\n"!    
00637         report << QString("<b>Errors: %1, Warnings: %2</b>").arg(err_count).arg(war_count);        
00638         return false;
00639     }
00640 }
00641 
00642 void Parser::File()
00643 {
00644     Predeclaration();
00645     DBGLOG_PAR("predeclaration ok ...");
00646     VCPicture();
00647 }
00648 
00649 void Parser::Predeclaration()
00650 {
00651   while (!kwTest(lexan->getToken()) && lexan->getToken() != EOI)
00652   {
00653     lexan->readToken();
00654     IF_CAN_CHANGE_EDITOR
00655     (
00656     editor->addition = true;
00657     )
00658   } // accept only key word or EOI!
00659   switch (lexan->getToken()){
00660   case kwShowGrid:
00661     IF_CAN_CHANGE_EDITOR
00662     (
00663     editor->showGrid = true;
00664     emit editor->showChanged(editor->showGrid, editor->showFrame);
00665     )
00666     lexan->readToken();
00667     break;
00668   case kwShowFrame:
00669     IF_CAN_CHANGE_EDITOR
00670     (
00671     editor->showFrame = true;
00672     emit editor->showChanged(editor->showGrid, editor->showFrame);
00673     )
00674     lexan->readToken();
00675     break;
00676   case kwHideGrid:
00677     IF_CAN_CHANGE_EDITOR
00678     (
00679     editor->showGrid = false;
00680     emit editor->showChanged(editor->showGrid, editor->showFrame);
00681     )
00682     lexan->readToken();
00683     break;
00684   case kwHideFrame:
00685     IF_CAN_CHANGE_EDITOR
00686     (
00687     editor->showFrame = false;
00688     emit editor->showChanged(editor->showGrid, editor->showFrame);
00689     )
00690     lexan->readToken();
00691     break;
00692   case kwBeginVCPicture:
00693     return;
00694   case EOI:
00695     throw U_EOI;
00696     break;
00697   default:
00698     try{
00699       ChgParam(); // most keywords
00700     }
00701     catch (Exceptions v)
00702     {
00703         if (v != U_TOKEN) throw;    // if U_TOKEN, it's ok, whatever should be in .tex file
00704         lexan->readToken();
00705     }
00706   }
00707   Predeclaration();
00708 }
00709 
00710 void Parser::VCPicture()
00711 {
00712     int lx, ly, rx, ry;
00713     DBGLOG_PAR("VCPicture loading");
00714     matching(kwBeginVCPicture);
00715     matching(LBRACE);
00716     matching(LPAR);
00717     lx = Numb();
00718     matching(COMMA);
00719     ly = Numb();
00720     matching(RPAR);
00721     matching(LPAR);
00722     rx = Numb();
00723     matching(COMMA);
00724     ry = Numb();
00725     matching(RPAR);
00726     matching(RBRACE);
00727     if (lx < rx && ly < ry)
00728     {
00729       // set grid rect
00730       m_gridRect = QRect(lx,ly,rx-lx,ry-ly);
00731       IF_CAN_CHANGE_EDITOR(editor->setGridRect(m_gridRect);)
00732     }
00733     else
00734     {
00735       throw BAD_GRID;
00736     }
00737     DBGLOG_PAR("entering to main part - Element");
00738     while (Element()){}; // main part of parsing
00739     matching(kwEnd);
00740     matching(LBRACE);
00741     if (lexan->getToken() == IDENT)
00742     {
00743         if (lexan->getTokenData() != "VCPicture")
00744         {
00745             errorReportUTOKEN();
00746             throw U_TOKEN;
00747         }
00748     }
00749     matching(IDENT);
00750     matching(RBRACE, true);
00751 }
00752 
00753 void Parser::VCPut()
00754 {
00755     matching(kwVCPut);
00756 
00757     if (lexan->getToken() == LBRACKET)
00758     {
00759         matching(LBRACKET);
00760         Number();
00761         matching(RBRACKET);
00762     }
00763 
00764     matching(LBRACE);
00765     matching(LPAR);
00766     Number();
00767     matching(COMMA);
00768     Number();
00769     matching(RPAR);
00770     matching(RBRACE);
00771     param = lexan->readStringBetween('{', '}');
00772     RELLOG("VCPut ignored content: " << param);
00773     matching(RBRACE);
00774 
00775     report << QString("%1: Warning %2 - VCPut is unsupported element, will be ignored (with all its content)!")
00776                   .arg(lexan->getLineNumber())
00777                   .arg(++war_count);
00778 }
00779 
00780 bool Parser::Element()
00781 {
00782     try
00783     {
00784         switch (lexan->getToken())
00785         {
00786             case kwVCPut:
00787                 VCPut();
00788                 break;
00789             case kwDimState:
00790             case kwDimEdge:
00791             case kwRstState:
00792             case kwRstEdge:  
00793             case kwStateLineDouble:
00794             case kwStateLineSimple:
00795             case kwEdgeLineDouble:
00796             case kwEdgeLineSimple:  
00797                 Switch();
00798                 break;
00799             case kwEdgeBorder:
00800             case kwEdgeBorderOff:
00801                 report << QString("%1: Warning %2 - EdgeBorder is not yet supported -> so ignored")
00802                     .arg(lexan->getLineNumber())      
00803                     .arg(++war_count);
00804                 Switch();
00805                 break;
00806             case kwVarLoopOn:
00807             case kwVarLoopOff:      
00808                 Switch();
00809                 break;
00810             case kwState:
00811             case kwFinalState:
00812             case kwStateVar:
00813             case kwFinalStateVar:
00814                 DBGLOG_PAR("found State");
00815                 State_r();
00816                 break;
00817             case kwInitial:
00818             case kwFinal:
00819             case kwLoopN:
00820             case kwLoopS:
00821             case kwLoopE:
00822             case kwLoopW:
00823             case kwLoopNE:
00824             case kwLoopNW:
00825             case kwLoopSE:
00826             case kwLoopSW:
00827             case kwCLoopN:
00828             case kwCLoopS:
00829             case kwCLoopE:
00830             case kwCLoopW:
00831             case kwCLoopNE:
00832             case kwCLoopNW:
00833             case kwCLoopSE:
00834             case kwCLoopSW:
00835             case kwLoopVarN:
00836             case kwLoopVarS:
00837             case kwEdgeL:
00838             case kwEdgeR:
00839             case kwArcL:
00840             case kwArcR:
00841             case kwLArcL:
00842             case kwLArcR:
00843             case kwVArcL:
00844             case kwVArcR:
00845             case kwVCurveL:
00846             case kwVCurveR:
00847                 DBGLOG_PAR("founded Transition");
00848                 Transition_r();
00849                 break;  
00850             case kwLabelL:
00851             case kwLabelR:
00852                 DBGLOG_PAR("founded Label");
00853                 Label_r();
00854                 break;
00855             case COMMENT:
00856                 matching(COMMENT); // TODO: maybe inflictable?
00857                 break; 
00858             case kwEnd: // end of picture
00859                 DBGLOG_PAR("end");
00860                 return false;
00861             default:
00862                 ChgParam(); // the longest list of keywords
00863         }
00864     }//try
00865     catch (Exceptions v)
00866     {
00867         switch (v)
00868         {
00869             case STATE_EXIST:
00870                 report << QString("%1: Error%2 - State with same name already exists. Skipping to next element ...")
00871                     .arg(lexan->getLineNumber()).arg(++err_count);
00872                 break;
00873             case NO_STATE:
00874                 report << QString("%1: Error%2 - Required state doesn't exist. Skipping to next element ...")
00875                     .arg(lexan->getLineNumber()).arg(++err_count);
00876                 break;
00877             case U_TOKEN:
00878                 errorReportUTOKEN();
00879                 break;
00880             default:
00881                 throw;
00882                 break;
00883         }
00884         while (!kwTest(lexan->readToken()) && lexan->getToken() != EOI){}
00885         if (lexan->getToken() == EOI) throw EOI;
00886     }
00887     return true;
00888 }
00889 
00890 void Parser::Switch()
00891 {
00892   switch (lexan->getToken()){
00893   case kwDimState: dimState = true; matching(kwDimState);
00894     break;
00895   case kwRstState: dimState = false; matching(kwRstState);
00896     resetStateParams();
00897     break;
00898   case kwDimEdge: dimEdge = true; matching(kwDimEdge);
00899     break;
00900   case kwRstEdge: dimEdge = false; matching(kwRstEdge);
00901     resetTrParams();
00902     break;
00903   case kwEdgeBorder: edgeBorder = true; matching(kwEdgeBorder);
00904     break;
00905   case kwEdgeBorderOff: edgeBorder = false; matching(kwEdgeBorderOff);
00906     break;
00907   case kwStateLineDouble: stateLineDouble = true; matching(kwStateLineDouble);
00908     break;
00909   case kwStateLineSimple: stateLineDouble = false; matching(kwStateLineSimple);
00910     break;
00911   case kwEdgeLineDouble: edgeLineDblStatus = true; matching(kwEdgeLineDouble);
00912     break;
00913   case kwEdgeLineSimple: edgeLineDblStatus = false; matching(kwEdgeLineSimple);
00914     break;
00915   case kwVarLoopOn: varLoop = true; matching(kwVarLoopOn);
00916       break;
00917   case kwVarLoopOff: varLoop = false; matching(kwVarLoopOff);
00918       break;
00919   default:
00920       report << QString("%1: Error %2 - Unexpected token '%3', expected Switch")
00921           .arg(lexan->getLineNumber())    
00922           .arg(++err_count)
00923           .arg(lexan->getTokenData());
00924     throw U_TOKEN;
00925   }
00926 }
00927 
00928 void Parser::ChgParam(){
00929   float number, number2;
00930   switch (lexan->getToken()){
00931   case setStateLineStyle:
00932     matching(setStateLineStyle);
00933     matching(LBRACE);
00934     stateLineStyle = LineStyle();
00935     IF_CAN_CHANGE_EDITOR(editor->stateLineStyle = stateLineStyle;)
00936     matching(RBRACE);
00937     break;
00938   case setStateLineWidth:
00939     matching(setStateLineWidth);
00940     matching(LBRACE);
00941     number = Number();
00942     if (lexan->getToken() == IDENT){
00943       if (lexan->getTokenData() != "pt"){
00944           report << QString("%1: Warning %2 - Unexpected IDENT '%3' -> expected 'pt' -> substituted to 'pt'")
00945             .arg(lexan->getLineNumber())      
00946             .arg(++war_count)
00947             .arg(lexan->getTokenData());
00948       }
00949       matching(IDENT);
00950     }
00951     else{
00952         report << QString("%1: Warning %2 - Missing IDENT -> expected 'pt' -> inserted 'pt'")
00953             .arg(lexan->getLineNumber())    
00954             .arg(++war_count);
00955     }
00956     IF_CAN_CHANGE_EDITOR(editor->stateLineWidth = number;)
00957     stateLineWidth = 1; // change to default
00958     matching(RBRACE);
00959     break;
00960   case setStateLineColor:
00961     matching(setStateLineColor);
00962     matching(LBRACE);
00963     stateLineColor = Color();
00964     IF_CAN_CHANGE_EDITOR(editor->stateLineColor = stateLineColor;)
00965     matching(RBRACE);
00966     break;
00967   case setStateLabelColor:
00968     matching(setStateLabelColor);
00969     matching(LBRACE);
00970     stateLabelColor = Color();
00971     IF_CAN_CHANGE_EDITOR(editor->stateLabelColor = stateLabelColor;)
00972     matching(RBRACE);
00973     break;
00974   case setStateLabelScale:
00975     matching(setStateLabelScale);
00976     matching(LBRACE);
00977     number = Number();
00978     stateLabelScale = number;
00979     IF_CAN_CHANGE_EDITOR(editor->stateLabelScale = stateLabelScale;)
00980     matching(RBRACE);
00981     break;
00982   case setStateFillStatus:
00983     matching(setStateFillStatus);
00984     matching(LBRACE);
00985     stateFillStatus = FillStatus();
00986     IF_CAN_CHANGE_EDITOR(editor->stateFillStatus = stateFillStatus;)
00987     matching(RBRACE);
00988     break;
00989   case setStateFillColor:
00990     matching(setStateFillColor);
00991     matching(LBRACE);
00992     stateFillColor = Color();
00993     IF_CAN_CHANGE_EDITOR(editor->stateFillColor = stateFillColor;)
00994     matching(RBRACE);
00995     break;
00996   case setEdgeLineStyle:
00997     matching(setEdgeLineStyle);
00998     matching(LBRACE);
00999     edgeLineStyle = LineStyle();
01000     IF_CAN_CHANGE_EDITOR(editor->edgeLineStyle = edgeLineStyle;)
01001     matching(RBRACE);
01002     break;
01003   case setEdgeLineWidth:
01004     matching(setEdgeLineWidth);
01005     matching(LBRACE);
01006     number = Number();
01007     if (lexan->getToken() == IDENT){
01008       if (lexan->getTokenData() != "pt"){
01009         report << QString("%1: Warning %2 - Unexpected IDENT '%3'  -> expected 'pt' -> substituted to 'pt'")
01010             .arg(lexan->getLineNumber())      
01011             .arg(++war_count)
01012             .arg(lexan->getTokenData());
01013       }
01014       matching(IDENT);
01015     }
01016     else{
01017       report << QString("%1: Warning %2 - Missing IDENT -> expected 'pt' -> inserted 'pt'")
01018             .arg(lexan->getLineNumber())    
01019             .arg(++war_count);
01020     }
01021     edgeLineWidth = number;
01022     IF_CAN_CHANGE_EDITOR(editor->edgeLineWidth = edgeLineWidth;)
01023     matching(RBRACE);
01024     break;
01025   case setEdgeLineColor:
01026     matching(setEdgeLineColor);
01027     matching(LBRACE);
01028     edgeLineColor = Color();
01029     IF_CAN_CHANGE_EDITOR(editor->edgeLineColor = edgeLineColor;)
01030     matching(RBRACE);
01031     break;
01032   case setEdgeLabelColor:
01033     matching(setEdgeLineStyle);
01034     matching(LBRACE);
01035     edgeLabelColor = Color();
01036     IF_CAN_CHANGE_EDITOR(editor->edgeLabelColor = edgeLabelColor;)
01037     matching(RBRACE);
01038     break;
01039   case setEdgeLabelScale:
01040     matching(setEdgeLabelScale);
01041     matching(LBRACE);
01042     number = Number();
01043     edgeLabelScale = number;
01044     IF_CAN_CHANGE_EDITOR(editor->edgeLabelScale = edgeLabelScale;)
01045     matching(RBRACE);
01046     break;
01047   /*case setEdgeLineDblStatus:
01048     matching(setEdgeLineDblStatus);
01049     matching(LBRACE);
01050     if (lexan->getToken() == IDENT){
01051     if (lexan->getTokenData() == "true"){
01052       editor->edgeLineDblStatus = true;
01053       edgeLineDblStatus = true;
01054     }
01055     else if (lexan->getTokenData() == "false"){
01056       editor->edgeLineDblStatus = false;
01057       edgeLineDblStatus = false;
01058     }
01059     matching(RBRACE);
01060     break;
01061     } // if IDENT
01062     report << QString("Error %1: Unexpected token in line %2, expected bool")
01063               .arg(++err_count)
01064               .arg(lexan->getLineNumber());
01065     throw U_TOKEN;
01066     break;*/
01067   case chgStateLineStyle:
01068     DBGLOG_PAR(lexan->getTokenData());
01069     matching(chgStateLineStyle);
01070     DBGLOG_PAR(lexan->getTokenData());
01071     matching(LBRACE);
01072     stateLineStyle = LineStyle();
01073     matching(RBRACE);
01074     break;
01075   case chgStateLineWidth:
01076     matching(chgStateLineWidth);
01077     matching(LBRACE);
01078     number = Number(); // radsi pres promennou
01079     stateLineWidth = number;
01080     matching(RBRACE);
01081     break;
01082   case chgStateLineColor:
01083     matching(chgStateLineColor);
01084     matching(LBRACE);
01085     stateLineColor = Color();
01086     matching(RBRACE);
01087     break;
01088   case chgStateLabelColor:
01089     matching(chgStateLabelColor);
01090     matching(LBRACE);
01091     stateLabelColor = Color();
01092     matching(RBRACE);
01093     break;
01094   case chgStateLabelScale:
01095     matching(chgStateLabelScale);
01096     matching(LBRACE);
01097     number = Number();
01098     stateLabelScale = number;
01099     matching(RBRACE);
01100     break;
01101   case chgStateFillStatus:
01102     matching(chgStateFillStatus);
01103     matching(LBRACE);
01104     stateFillStatus = FillStatus();
01105     matching(RBRACE);
01106     break;
01107   case chgStateFillColor:
01108     matching(chgStateFillColor);
01109     matching(LBRACE);
01110     stateFillColor = Color();
01111     matching(RBRACE);
01112     break;
01113   case chgEdgeLineStyle:
01114     matching(chgEdgeLineStyle);
01115     matching(LBRACE);
01116     edgeLineStyle = LineStyle();
01117     matching(RBRACE);
01118     break;
01119   case chgEdgeLineWidth:
01120     matching(chgEdgeLineWidth);
01121     matching(LBRACE);
01122     number = Number();
01123     edgeLineWidth = number;
01124     matching(RBRACE);
01125     break;
01126   case chgEdgeLineColor:
01127     matching(chgEdgeLineColor);
01128     matching(LBRACE);
01129     edgeLineColor = Color();
01130     matching(RBRACE);
01131     break;
01132   case chgEdgeLabelColor:
01133     matching(chgEdgeLabelColor);
01134     matching(LBRACE);
01135     edgeLabelColor = Color();
01136     matching(RBRACE);
01137     break;
01138   case chgEdgeLabelScale:
01139     matching(chgEdgeLabelScale);
01140     matching(LBRACE);
01141     number = Number();
01142     edgeLabelScale = number;
01143     matching(RBRACE);
01144     break;
01145   /*case chgEdgeLineDblStatus:
01146     matching(setEdgeLineDblStatus);
01147     matching(LBRACE);
01148     if (lexan->getToken() == IDENT){
01149     if (lexan->getTokenData() == "true"){
01150       edgeLineDblStatus = true;  
01151     }
01152     else if(lexan->getTokenData() == "false"){
01153       edgeLineDblStatus = false;
01154     }
01155     matching(RBRACE);
01156     break;
01157     } // if IDENT
01158     report << QString("Error %1: Unexpected token in line %2, expected bool")
01159               .arg(++err_count)
01160               .arg(lexan->getLineNumber());
01161     throw U_TOKEN;
01162     break;*/
01163   case rstStateLineStyle:
01164     matching(rstStateLineStyle);
01165     stateLineStyle = editor->stateLineStyle;
01166     break;
01167   case rstStateLineWidth:
01168     matching(rstStateLineWidth);
01169     stateLineWidth = 1; // it's only coeficient, no value!
01170     break;
01171   case rstStateLineColor:
01172     matching(rstStateLineColor);
01173     stateLineColor = editor->stateLineColor;
01174     break;
01175   case rstStateLabelColor:
01176     matching(rstStateLabelColor);
01177     stateLabelColor = editor->stateLabelColor;
01178     break;
01179   case rstStateLabelScale:
01180     matching(rstStateLabelScale);
01181     stateLabelScale = 1;
01182     break;
01183   case rstStateFillStatus:
01184     matching(rstStateFillStatus);
01185     stateFillStatus = editor->stateFillStatus;
01186     break;
01187   case rstStateFillColor:
01188     matching(rstStateFillColor);
01189     stateFillColor = editor->stateFillColor;
01190     break;
01191   case rstEdgeLineStyle:
01192     matching(rstEdgeLineStyle);
01193     edgeLineStyle = editor->edgeLineStyle;
01194     break;
01195   case rstEdgeLineWidth:
01196     matching(rstEdgeLineWidth);
01197     edgeLineWidth = 1;
01198     break;
01199   case rstEdgeLineColor:
01200     matching(rstEdgeLineColor);
01201     edgeLineColor = editor->edgeLineColor;
01202     break;
01203   case rstEdgeLabelColor:
01204     matching(rstStateLabelColor);
01205     stateLabelColor = editor->stateLabelColor;
01206     break;
01207   case rstEdgeLabelScale:
01208     matching(rstEdgeLabelScale);
01209     edgeLabelScale = 1;
01210     break;
01211   /*case rstEdgeLineDblStatus:
01212     matching(rstEdgeLineDblStatus);
01213     edgeLineDblStatus = editor->edgeLineDblStatus;
01214     break;*/
01215   case fixDimState:
01216     matching(fixDimState);
01217     matching(LBRACE);
01218       dimStateLineStyle = LineStyle();
01219     matching(RBRACE);
01220     matching(LBRACE);
01221       dimStateLineColor = Color();
01222     matching(RBRACE);
01223     matching(LBRACE);
01224       dimStateLineCoef = Number();
01225     matching(RBRACE);
01226     matching(LBRACE);
01227       dimStateLabelColor = Color();
01228     matching(RBRACE);
01229     matching(LBRACE);
01230       dimStateFillColor = Color();
01231     matching(RBRACE);
01232     break;
01233   case fixStateLineDouble:
01234     matching(fixStateLineDouble);
01235     matching(LBRACE);
01236       number = Number();
01237     matching(RBRACE);
01238     matching(LBRACE);
01239       number2 = Number();
01240     matching(RBRACE);
01241       stateLineDoubleCoef = number;
01242       stateLineDoubleSep = number2;
01243     break;
01244   case fixDimEdge:
01245     matching(fixDimEdge);
01246     matching(LBRACE);
01247       dimEdgeLineStyle = LineStyle();
01248     matching(RBRACE);
01249     matching(LBRACE);
01250       number = Number();
01251       dimEdgeLineCoef = number;
01252     matching(RBRACE);
01253     matching(LBRACE);
01254       dimEdgeLineColor = Color();
01255     matching(RBRACE);
01256     matching(LBRACE);
01257       dimEdgeLabelColor = Color();
01258     matching(RBRACE);
01259     break;
01260   case fixEdgeBorder:
01261     matching(fixEdgeBorder);
01262     matching(LBRACE);
01263       number = Number();
01264       edgeLineBorderCoef = number;
01265     matching(RBRACE);
01266     matching(LBRACE);
01267       edgeLineBorderColor = Color();
01268     matching(RBRACE);
01269     break;
01270   case fixEdgeLineDouble:
01271     matching(fixEdgeLineDouble);
01272     matching(LBRACE);
01273       number = Number();
01274     matching(RBRACE);
01275     matching(LBRACE);
01276       number2 = Number();
01277     matching(RBRACE);
01278       edgeLineDblCoef = number;
01279       edgeLineDblSep = number2;
01280     break;
01281   default:
01282     throw U_TOKEN;
01283   } // switch
01284 }
01285 
01286 Qt::BrushStyle Parser::FillStatus(){
01287   QString s;
01288   if (lexan->getToken() == IDENT){
01289     s = lexan->getTokenData();
01290     matching(IDENT);
01291     if(s == "vlines"){ 
01292       return Qt::FDiagPattern;
01293     }
01294     else if(s == "hlines"){
01295       return Qt::BDiagPattern;
01296     }
01297     else if(s == "crosshatch"){
01298       return Qt::DiagCrossPattern;
01299     }
01300     else if(s == "none"){
01301       return Qt::NoBrush;
01302     }
01303     else if(s == "solid"){
01304       return Qt::SolidPattern;
01305     }
01306     report << QString("%1: Warning %2 - Bad fill status '%3', substituted by none!")
01307         .arg(lexan->getLineNumber())    
01308         .arg(++war_count)
01309         .arg(s);
01310     return Qt::NoBrush;
01311   } // if IDENT
01312   
01313   errorReportUTOKEN();
01314   throw U_TOKEN;
01315 }
01316 
01317 Qt::PenStyle Parser::LineStyle(){
01318   QString s;
01319   if (lexan->getToken() == IDENT){
01320     s = lexan->getTokenData();
01321     matching(IDENT);
01322     if (s == "dashed"){
01323       return Qt::DashLine;
01324     }
01325     else if (s == "dotted"){
01326       return Qt::DotLine;
01327     }
01328     else if (s == "solid"){
01329       return Qt::SolidLine;
01330     }
01331     else if (s == "none"){
01332       return Qt::NoPen;
01333     }
01334     report << QString("%1: Warning %2 - Bad line style '%3', substituted by solid!")
01335         .arg(lexan->getLineNumber())      
01336         .arg(++war_count)
01337         .arg(s);
01338     return Qt::SolidLine;
01339   } // if IDENT
01340   
01341   errorReportUTOKEN();
01342   throw U_TOKEN;  
01343 }
01344 
01345 QString Parser::Color(){
01346     QString s;
01347         if (lexan->getToken() == IDENT)
01348         {
01349             s = lexan->getTokenData();
01350             matching(IDENT);
01351             return s; // TODO: checking color string!
01352         } // if IDENT
01353     errorReportUTOKEN();
01354     throw U_TOKEN;  
01355 }
01356 
01357 void Parser::State_r(){
01358   param = lexan->getTokenData();
01359   switch (lexan->getToken())
01360   {
01361   case kwState:         
01362     matching(kwState);
01363     StateDeclaration(param);
01364     break;
01365   case kwFinalState:
01366     matching(kwFinalState);
01367     StateDeclaration(param);
01368     break;
01369   case kwStateVar:
01370     matching(kwStateVar);
01371     StateDeclaration(param);
01372     break;
01373   case kwFinalStateVar:
01374     matching(kwFinalStateVar);
01375     StateDeclaration(param);
01376     break;
01377   default:
01378       errorReportUTOKEN();
01379     throw U_TOKEN;
01380   }
01381   
01382 }
01383 
01384 void Parser::StateDeclaration(const QString& typeN){
01385     QString typeName = typeN;
01386     QString label, name;
01387     float x, y;
01388     switch (lexan->getToken())
01389     {
01390     case LBRACKET: // [ 
01391         //matching(LBRACKET);
01392         StateLabel(); label = param;
01393         matching(RBRACKET);
01394         break;
01395     case LBRACE: // {
01396         break;
01397     default:
01398         errorReportUTOKEN();
01399         throw U_TOKEN;
01400     }
01401     matching(LBRACE);
01402     matching(LPAR);
01403     x = Number();
01404     matching(COMMA);
01405     y = Number();
01406     matching(RPAR);
01407     matching(RBRACE);
01408     matching(LBRACE);
01409     Name();
01410     name = param;
01411     matching(RBRACE);
01412 
01413     if (m_stateMap.contains(name))
01414     {
01415         report << QString("%1: Error %2 - State name '%3' already exists (state names conflict)!")
01416             .arg(lexan->getLineNumber())    
01417             .arg(++err_count)
01418             .arg(name);
01419         throw STATE_EXIST;
01420     }
01421     
01422     DBGLOG_PAR(typeName << QString("[%1]{(%2,%3)}{%4}")
01423                                 .arg(label)
01424                                 .arg(x)
01425                                 .arg(y)
01426                                 .arg(name));
01427   
01428     if (stateLineDouble) typeName = "Final" + typeName;
01429 
01430     QPoint pos = editor->toScenePos(QPointF(x,y));
01431     
01432     StateManager *stateManager = StateManager::getInstance();
01433     State *state = stateManager->createState(typeName, editor, pos, label, name, dimState);
01434     Q_ASSERT(state != NULL);
01435 
01436 #ifdef MEASURE_PARSER_RUN
01437     static int s_stateCount = 0;
01438     s_stateCount++;
01439     if (s_stateCount % 1000 == 0)
01440         RELLOG(DBGPAR(s_stateCount));
01441 #endif
01442 
01443     // parameters setting
01444     if (stateLineStyle != editor->stateLineStyle) state->stateLineStyle = stateLineStyle;
01445     if (stateLineWidth != 1) state->setStateLineWidth(stateLineWidth);
01446     if (stateLineColor != editor->stateLineColor) state->stateLineColor = stateLineColor;
01447     if (stateLabelColor != editor->stateLabelColor) state->stateLabelColor = stateLabelColor;
01448     if (stateLabelScale != 1) state->setStateLabelScale(stateLabelScale);
01449     if (stateFillStatus != editor->stateFillStatus) state->stateFillStatus = stateFillStatus;
01450     if (stateFillColor != editor->stateFillColor) state->stateFillColor = stateFillColor;
01451 
01452     if (stateLineDoubleCoef != (float) DEF_STATE_LINE_DBL_COEF)
01453     state->setStateLineDoubleCoef(stateLineDoubleCoef);
01454     if (stateLineDoubleSep != (float) DEF_STATE_LINE_DBL_SEP)
01455     state->setStateLineDoubleSep(stateLineDoubleSep);
01456 
01457     if (dimStateLineStyle != DEF_DIM_LINE_STYLE) state->dimStateLineStyle = dimStateLineStyle;
01458     if (dimStateLineColor != DEF_DIM_COLOR) state->dimStateLineColor = dimStateLineColor;
01459     if (dimStateLineCoef != (float) DEF_DIM_STATE_LINE_COEF) state->setDimStateLineCoef(dimStateLineCoef);
01460     if (dimStateLabelColor != DEF_DIM_COLOR) state->dimStateLabelColor = dimStateLabelColor;
01461     if (dimStateFillColor != DEF_DIM_FILL_COLOR) state->dimStateFillColor = dimStateFillColor;
01462     
01463     m_stateMap.insert(name, state);
01464 }
01465 
01466 void Parser::StateLabel()
01467 {
01468     param = lexan->readStringBetween('[', ']', false);
01469 }
01470 
01471 void Parser::Transition_r(){
01472   switch (lexan->getToken()){
01473   case kwInitial:
01474   case kwFinal:
01475   case kwLoopN:
01476   case kwLoopS:
01477   case kwLoopE:
01478   case kwLoopW:
01479   case kwLoopNE:
01480   case kwLoopNW:
01481   case kwLoopSE:
01482   case kwLoopSW:
01483   case kwCLoopN:
01484   case kwCLoopS:
01485   case kwCLoopE:
01486   case kwCLoopW:
01487   case kwCLoopNE:
01488   case kwCLoopNW:
01489   case kwCLoopSE:
01490   case kwCLoopSW:
01491   case kwLoopVarN:
01492   case kwLoopVarS:
01493     OneStateTransition();
01494     break;
01495   default: // solved by Element
01496     TwoStateTransition();
01497   }
01498 }
01499 
01500 void Parser::Label_r()
01501 {
01502     bool left = false;
01503     switch (lexan->getToken()){
01504         case kwLabelL:
01505             matching(kwLabelL);
01506             left = true;
01507             break;
01508         case kwLabelR:
01509             matching(kwLabelR);
01510             left = false;
01511             break;
01512         default:
01513             RELLOG("Unexpected parser state!!!");
01514             left = true;
01515     }
01516 
01517     float pos_param = 0; bool isParam = false;
01518     pos_param = PosParam(isParam);
01519     if(!isParam) pos_param = DEF_EDGE_LAB_POS;
01520     TransitionLabel();
01521     matching(RBRACE);
01522 
01523     DBGLOG_PAR(isParam << pos_param << "Label" << (left ? "L" : "R") 
01524         << "[" << pos_param<< "]" << "{" << param << "}");
01525 
01526     if (lastTr == NULL)
01527     {
01528         report << QString("%1: Error %2 - Trying to add LabelX and no transition exist!")
01529             .arg(lexan->getLineNumber())    
01530             .arg(++err_count);
01531         throw U_ERR;
01532     }
01533     LabelX *pLabel = new LabelX(lastTr, param, left, lastTr->m_labelFontSize, 
01534         lastTr->getLabelColor(), pos_param);    
01535     
01536     lastTr->addNextLabel(pLabel);
01537     
01538     lastTr->setLabelPosition(); // TODO: check if this should be removed (maybe it is aplied later again -> so performance can be better)
01539 }
01540 
01541 void Parser::OneStateTransition()
01542 {
01543 #ifdef MEASURE_PARSER_RUN
01544     static int s_oneTrCount = 0;
01545 #endif
01546     param = "";
01547     Transition *tr; State *state;
01548     TransitionManager *transitionManager = TransitionManager::getInstance();
01549     QString stateName, typeName, label;
01550     int dir;
01551     float pos_param; bool isParam;
01552     typeName = lexan->getTokenData(); // type name -> VauCanSon-G keyword
01553     switch (lexan->getToken())
01554     {
01555     case kwInitial:
01556         matching(kwInitial);        
01557     break;
01558     case kwFinal:
01559         matching(kwFinal);        
01560         break;
01561     default:
01562         dir = Loop();
01563         pos_param = PosParam(isParam);
01564         matching(LBRACE);
01565         Name();
01566         stateName = param; param = "";
01567         matching(RBRACE);        
01568         TransitionLabel(); label = param;
01569                     
01570         dir = trLoopDirection(dir);
01571     
01572         if (varLoop) // switch is set, so this will be LoopVar
01573         {                     
01574             typeName = "LoopVar";
01575         }
01576         else if (typeName.startsWith("LoopVar"))
01577             typeName = "LoopVar";
01578         else if (typeName.startsWith("CLoop"))
01579             typeName = "CLoop";
01580         else if (typeName.startsWith("Loop"))
01581             typeName = "Loop";
01582         else
01583         {
01584             RELLOG("Parser::OneStateTransition -> Unexpected loop type!!!");
01585             report << QString("%1: Warning %2 - Loop type name '%3' isn't supported, Loop used!")
01586                 .arg(lexan->getLineNumber())
01587                 .arg(++war_count)
01588                 .arg(typeName);
01589             typeName = "Loop";
01590         }
01591 
01592         DBGLOG_PAR(isParam << pos_param
01593             << typeName << " " << dir << "{" << param << "}" << "{" << stateName << "}");
01594 
01595         // insert loop
01596         if (!m_stateMap.contains(stateName))
01597         {
01598             report << QString("%1: Error %2 - State name '%3' doesn't exist!")
01599                 .arg(lexan->getLineNumber())
01600                 .arg(++err_count)
01601                 .arg(stateName);
01602             throw NO_STATE;
01603         }
01604         
01605         state = m_stateMap[stateName];
01606             
01607         tr = transitionManager->createOneStateTransition(typeName, editor, state, label, dir, dimEdge);        
01608 
01609         if (isParam) tr->setLabelPos(pos_param);
01610         checkTrParam(tr);
01611         tr->assign();
01612         
01613         lastTr = tr;
01614         
01615 #ifdef MEASURE_PARSER_RUN
01616     s_oneTrCount++;
01617     if (s_oneTrCount % 1000 == 0)
01618         RELLOG(DBGPAR(s_oneTrCount));
01619 #endif
01620         
01621         matching(RBRACE);
01622         return;
01623     }
01624     
01625     dir = DirParam(isParam);
01626     matching(LBRACE);
01627     Name(); stateName = param;
01628   
01629     DBGLOG_PAR(typeName << "{" << stateName << "}");
01630 
01631     if (!m_stateMap.contains(stateName))
01632     {
01633         report << QString("%1: Error %2 - State name '%3' doesn't exist!")
01634             .arg(lexan->getLineNumber())    
01635             .arg(++err_count)
01636             .arg(stateName);
01637         throw NO_STATE;
01638     }
01639     
01640     state = m_stateMap[stateName];
01641 
01642     if (!isParam)
01643     {
01644         if (typeName == "Initial")
01645             dir = DEF_TR_S_DIR;
01646         else
01647             dir = DEF_TR_E_DIR;
01648     }
01649 
01650     tr = transitionManager->createOneStateTransition(typeName, editor, state, "", dir, dimEdge);
01651     tr->assign();
01652     checkTrParam(tr);
01653     
01654     lastTr = tr;
01655 
01656 #ifdef MEASURE_PARSER_RUN
01657     s_oneTrCount++;
01658     if (s_oneTrCount % 1000 == 0)
01659         RELLOG(DBGPAR(s_oneTrCount));
01660 #endif
01661 
01662     matching(RBRACE);
01663 }
01664 
01665 int Parser::Loop()
01666 {
01667   switch (lexan->getToken()){
01668   case kwLoopN:
01669     matching(kwLoopN);
01670     return NORTH;
01671   case kwLoopS:
01672     matching(kwLoopS);
01673     return SOUTH;
01674   case kwLoopE:
01675     matching(kwLoopE);
01676     return EAST;
01677   case kwLoopW:
01678     matching(kwLoopW);
01679     return WEST;
01680   case kwLoopNE:
01681     matching(kwLoopNE);
01682     return NORTH_EAST;
01683   case kwLoopNW:
01684     matching(kwLoopNW);
01685     return NORTH_WEST;
01686   case kwLoopSE:
01687     matching(kwLoopSE);
01688     return SOUTH_EAST;
01689   case kwLoopSW:
01690     matching(kwLoopSW);
01691     return SOUTH_WEST;
01692   // CLoop has direction increased with num of directions (first is SOUTH_WEST+1)
01693   case kwCLoopN:
01694     matching(kwCLoopN);
01695     return trCLoopDirection(NORTH);
01696   case kwCLoopS:
01697     matching(kwCLoopS);
01698     return trCLoopDirection(SOUTH);
01699   case kwCLoopE:
01700     matching(kwCLoopE);
01701     return trCLoopDirection(EAST);
01702   case kwCLoopW:
01703     matching(kwCLoopW);
01704     return trCLoopDirection(WEST);
01705   case kwCLoopNE:
01706     matching(kwCLoopNE);
01707     return trCLoopDirection(NORTH_EAST);
01708   case kwCLoopNW:
01709     matching(kwCLoopNW);
01710     return trCLoopDirection(NORTH_WEST);
01711   case kwCLoopSE:
01712     matching(kwCLoopSE);
01713     return trCLoopDirection(SOUTH_EAST);
01714   case kwCLoopSW:
01715     matching(kwCLoopSW);
01716     return trCLoopDirection(SOUTH_WEST);
01717   case kwLoopVarN:    
01718     matching(kwLoopVarN);
01719     return trLoopVarDirection(NORTH);
01720   case kwLoopVarS:    
01721     matching(kwLoopVarS);
01722     return trLoopVarDirection(SOUTH);
01723   default:
01724     return 0;
01725   }
01726 }
01727 
01728 void Parser::TwoStateTransition()
01729 {
01730     DBGLOG_PAR(""); // only info about function
01731     param = ""; // QString as class var
01732     QString typeName;
01733     bool left = false; float pos = 0; bool isPosParam = false;
01734     bool small = false; //for Arc :+(
01735   
01736     switch (lexan->getToken())
01737     {
01738     case kwEdgeL:
01739     case kwEdgeR:
01740         left = Edge();
01741         typeName = "Edge";
01742         pos = PosParam(isPosParam);
01743         break;
01744     case kwArcL:
01745     case kwArcR:
01746     case kwLArcL:
01747     case kwLArcR:
01748         left = Arc(small);
01749         if (small)
01750             typeName = "Arc";
01751         else
01752             typeName = "LArc";
01753         pos = PosParam(isPosParam);
01754         break;
01755     case kwVArcL:
01756     case kwVArcR:
01757         left = VArc();
01758         typeName = "VArc";
01759         pos = PosParam(isPosParam);
01760         matching(LBRACE);
01761         VArcParam();
01762         matching(RBRACE);
01763         break;
01764     case kwVCurveL:
01765     case kwVCurveR:
01766         left = VCurve();
01767         typeName = "VCurve";
01768         pos = PosParam(isPosParam);
01769         matching(LBRACE);
01770         VCurveParam();
01771         matching(RBRACE);
01772     default:; // tohle nenastane, hlida to Element
01773     }  
01774     EndTransitionDeclaration(typeName ,left, pos, isPosParam);
01775 }
01776 
01777 bool Parser::Edge(){
01778     if (lexan->getToken() == kwEdgeL)
01779     {
01780         matching(kwEdgeL);
01781         return true;
01782     }
01783     matching(kwEdgeR);
01784     return false;
01785 }
01786 
01787 bool Parser::Arc(bool &small){
01788   switch (lexan->getToken()){
01789   case kwArcL:
01790     small = true;
01791     matching(kwArcL);
01792     return true;
01793   case kwArcR:
01794     small = true;
01795     matching(kwArcR);
01796     return false;
01797   case kwLArcL:
01798     small = false;
01799     matching(kwLArcL);
01800     return true;
01801   case kwLArcR:
01802     small = false;
01803     matching(kwLArcR);
01804     return false;
01805   default:
01806     return 0;
01807   }
01808 }
01809 
01810 bool Parser::VArc()
01811 {
01812   if (lexan->getToken() == kwVArcL){
01813     matching(kwVArcL);
01814     return true;
01815   }
01816   matching(kwVArcR);
01817   return false;
01818 }
01819 
01820 bool Parser::VCurve()
01821 {
01822   if (lexan->getToken() == kwVCurveL){
01823     matching(kwVCurveL);
01824     return true;
01825   }
01826   matching(kwVCurveR);
01827   return false;
01828 }
01829 
01830 void Parser::VArcParam()
01831 {
01832   cParam.isAngleA = false; // vynuluju co budu potrebovat
01833   cParam.isNCurv = false;
01834   if (lexan->getToken() != RBRACE){
01835     VArcParamIdent();
01836     VArcParamNext();
01837   }
01838 }
01839 
01840 void Parser::VArcParamNext()
01841 {
01842   if (lexan->getToken() != RBRACE){
01843     matching(COMMA);
01844     VArcParamIdent();
01845     VArcParamNext();
01846   }
01847 }
01848 
01849 void Parser::VArcParamIdent()
01850 {
01851   switch(lexan->getToken()){
01852   case IDENT:
01853     if (lexan->getTokenData() == "arcangle"){
01854       matching(IDENT);
01855       matching(EQUAL);
01856       cParam.angleA = Numb(); cParam.isAngleA = true; 
01857     }
01858     else if (lexan->getTokenData() == "ncurv"){
01859       matching(IDENT);
01860       matching(EQUAL);
01861       cParam.ncurv = Number(); cParam.isNCurv = true;
01862     }
01863     else{
01864       // TODO: jump to next IDENT or "}"
01865       errorReportUTOKEN();
01866       throw U_TOKEN;
01867     }
01868     break;
01869   default:;
01870   }
01871 }
01872 
01873 void Parser::VCurveParam(){
01874   cParam.isAngleA = false; // vynuluju co budu potrebovat
01875   cParam.isAngleB = false;
01876   cParam.isNCurv = false;
01877   if (lexan->getToken() != RBRACE){
01878     VCurveParamIdent();
01879     VCurveParamNext();
01880   }
01881 }
01882 
01883 void Parser::VCurveParamNext(){
01884   if (lexan->getToken() != RBRACE){
01885     matching(COMMA);
01886     VCurveParamIdent();
01887     VCurveParamNext();
01888   }
01889 }
01890 
01891 void Parser::VCurveParamIdent(){
01892  switch(lexan->getToken()){
01893   case IDENT:
01894     if (lexan->getTokenData() == "angleA"){
01895       matching(IDENT);
01896       matching(EQUAL);
01897       cParam.angleA = Numb(); cParam.isAngleA = true; 
01898     }
01899     else if (lexan->getTokenData() == "angleB"){
01900       matching(IDENT);
01901       matching(EQUAL);
01902       cParam.angleB = Numb(); cParam.isAngleB = true; 
01903     }
01904     else if (lexan->getTokenData() == "ncurv"){
01905       matching(IDENT);
01906       matching(EQUAL);
01907       cParam.ncurv = Number(); cParam.isNCurv = true;
01908     }
01909     else{
01910       // TODO: jump to next IDENT or "}"
01911         errorReportUTOKEN();
01912       throw U_TOKEN;
01913     }
01914     break;
01915   default:;
01916   }
01917 }
01918 
01919 void Parser::EndTransitionDeclaration(const QString &typeName, bool left, float pos, bool isPosParam)
01920 {
01921     QString s1, s2, label;
01922     Transition *tr; State *state1, *state2; // for save to scene
01923     TransitionManager *transitionManager = TransitionManager::getInstance();
01924     matching(LBRACE);
01925     param = "";
01926     Name();
01927     s1 = param;
01928     matching(RBRACE);
01929     matching(LBRACE);
01930     param = "";
01931     Name();
01932     s2 = param;
01933     matching(RBRACE);
01934     //matching(LBRACE);
01935     TransitionLabel(); 
01936     label = param;
01937   
01938     // place transition to graph
01939     DBGLOG_PAR(typeName << left << pos << isPosParam
01940         << "{" << s1 << "}" << "{" << s2 << "}" << "{" << label << "}");
01941   
01942     if (!m_stateMap.contains(s1) ||
01943         !m_stateMap.contains(s2))
01944     {
01945         report << QString("%1: Error %2 - State name '%3' or '%4' doesn't exist!")
01946             .arg(lexan->getLineNumber())
01947             .arg(++err_count)
01948             .arg(s1)
01949             .arg(s2);
01950         throw NO_STATE;
01951     }
01952   
01953     state1 = m_stateMap[s1];
01954     state2 = m_stateMap[s2];
01955   
01956     tr = transitionManager->createTwoStatesTransition(typeName, editor, state1, state2, label, left, dimEdge);
01957     tr->assign();
01958     
01959     if (cParam.isAngleA) tr->setArcAngle(cParam.angleA);
01960     else if (!left) tr->setArcAngle(-DEF_ARC_ANGLE);
01961 
01962     if (cParam.isAngleB) tr->setArcAngleB(cParam.angleB);
01963     if (cParam.isNCurv) tr->setNCurv(cParam.ncurv);
01964   
01965     if (isPosParam)
01966         tr->setLabelPos(pos);
01967   
01968     checkTrParam(tr);
01969     
01970     lastTr = tr;
01971     
01972 #ifdef MEASURE_PARSER_RUN
01973     static int s_twoTrCount = 0;
01974     s_twoTrCount++;
01975     if (s_twoTrCount % 1000 == 0)
01976         RELLOG(DBGPAR(s_twoTrCount));
01977 #endif
01978     
01979     matching(RBRACE);
01980 }
01981 
01982 void Parser::TransitionLabel()
01983 {
01984     param = lexan->readStringBetween('{', '}');
01985 }
01986 
01987 float Parser::PosParam(bool &isParam){
01988   float pos = 0;
01989   switch (lexan->getToken()){
01990   case LBRACKET:
01991     matching(LBRACKET);
01992     pos = Pos(isParam);
01993     matching(RBRACKET);
01994     break;
01995   default:
01996     isParam = false;
01997   }
01998   return pos;
01999 }
02000 
02001 float Parser::Pos(bool &isParam){
02002   float pos = 0;
02003   switch (lexan->getToken()){
02004   case MINUS:
02005   case NUMB:
02006   case FLOAT:
02007     pos = Number();
02008     isParam = true;
02009     break;
02010   case RBRACKET:
02011     pos = 0.5; // IMHO this do VauCanSon-G too! (or Latex do it)
02012     isParam = true;
02013     break;
02014   default:
02015     isParam = false;
02016   }
02017   return pos;
02018 }
02019 
02020 int Parser::DirParam(bool &isParam){
02021   int dir = NORTH;
02022   switch (lexan->getToken()){
02023   case LBRACKET:
02024     matching(LBRACKET);
02025     dir = Dir(isParam);
02026     matching(RBRACKET);
02027     break;
02028   default:
02029     isParam = false;
02030   }
02031   return dir;
02032 }
02033 
02034 int Parser::Dir(bool &isParam){
02035   int dir = NORTH; QString dir_s;
02036   switch(lexan->getToken()){
02037   case IDENT:
02038     dir_s = lexan->getTokenData();
02039     if (dir_s == "n"){
02040       dir = NORTH;
02041     }
02042     else if (dir_s == "s"){
02043       dir = SOUTH;
02044     }
02045     else if (dir_s == "e"){
02046       dir = EAST;
02047     }
02048     else if (dir_s == "w"){
02049       dir = WEST;
02050     }
02051     else if (dir_s == "ne"){
02052       dir = NORTH_EAST;
02053     }
02054     else if (dir_s == "nw"){
02055       dir = NORTH_WEST;
02056     }
02057     else if (dir_s == "se"){
02058       dir = SOUTH_EAST;
02059     }
02060     else if (dir_s == "sw"){
02061       dir = SOUTH_WEST;
02062     }
02063     else {
02064       errorReportUTOKEN();
02065       throw U_TOKEN;
02066     }
02067     matching(IDENT);
02068     isParam = true;
02069     break;
02070   default:
02071     isParam = false;
02072   }
02073   return dir;
02074 }
02075 
02076 float Parser::Number(){
02077   float number = Sign() ? -1 : 1;
02078   number = number * NumberNextPart();  
02079   DBGLOG_PAR(number);
02080   return number;
02081 }
02082 
02083 float Parser::NumberNextPart(){
02084     float number=0;
02085     if (lexan->getToken() == NUMB)
02086     {
02087         number = lexan->getTokenData().toInt();
02088         matching(NUMB);
02089     }
02090     else if(lexan->getToken() == FLOAT)
02091     {
02092         number = lexan->getTokenData().toFloat();
02093         matching(FLOAT);
02094     }
02095     else if(lexan->getToken() == IDENT)
02096     {}// it can be pt
02097     else
02098     {
02099       report << QString("%1: Warning %2 - No NUMB or FLOAT token, substituted by 0")
02100           .arg(lexan->getLineNumber())    
02101           .arg(++war_count);
02102       throw U_TOKEN;
02103     }
02104     return number;
02105 }
02106 
02107 int Parser::Numb(){
02108   int numb = Sign() ? -1 : 1;
02109   
02110   if (lexan->getToken() == NUMB) {
02111     numb = numb * lexan->getTokenData().toInt();
02112     matching(NUMB);
02113   }
02114   else {
02115     numb = 0;
02116     report << QString("%1: Warning %2 - No NUMB token, substituted by 0")
02117         .arg(lexan->getLineNumber())
02118         .arg(++war_count); 
02119     if (lexan->getToken() == IDENT || lexan->getToken() == FLOAT) lexan->readToken();
02120     else throw U_TOKEN;
02121   }
02122   
02123   DBGLOG_PAR(numb);
02124   return numb;
02125 }
02126 
02127 bool Parser::Sign(){
02128   if (lexan->getToken() == MINUS){
02129     matching(MINUS);
02130     return true;
02131   }
02132   else
02133     return false;
02134 }
02135 
02136 void Parser::Name()
02137 {
02138     param="";
02139     while (NoBracesToken()){}
02140 
02141     QString errorMsg;
02142     if (!checkNameCorrectness(param, &errorMsg))
02143     {
02144         report << QString("%1: Error %2 - %3 (%4)!")
02145             .arg(lexan->getLineNumber())
02146             .arg(++err_count)
02147             .arg(errorMsg)
02148             .arg(param);
02149         throw BAD_STATE_NAME;
02150     }
02151 }
02152 
02153 // TODO: delete this, not used anymore, see NameAllowedToken, checkNameCorrectness
02154 void Parser::NameNextPart(){ 
02155   if (lexan->getToken() == RBRACE){
02156     return;
02157   }
02158   NameAllowedToken();
02159   NameNextPart();
02160 }
02161 
02162 // Now exchanged for NoBracesToken, due to more than only these character can be used for Name
02163 // But no all combinations are allowed!
02164 // TODO: fix this and use it again
02165 void Parser::NameAllowedToken(){
02166   switch (lexan->getToken()){
02167   case IDENT:
02168     param += lexan->getTokenData();
02169     matching(IDENT);
02170     break;
02171   case NUMB:
02172     param += lexan->getTokenData();
02173     matching(NUMB);
02174     break;
02175   case FLOAT:
02176     param += lexan->getTokenData();
02177     matching(FLOAT);
02178     break;  
02179   case DOT:
02180     param += ".";
02181     matching(DOT);
02182     break;
02183   default:
02184       errorReportUTOKEN();
02185     throw U_TOKEN;
02186   }
02187 }
02188 
02189 bool Parser::NoBracesToken()
02190 {
02191   int brace_count = 0;
02192   do { // pairing loop
02193   switch (lexan->getToken()){
02194   case LPAR: // ( 
02195     param += "(";
02196     matching(LPAR);
02197     break;
02198   case RPAR:
02199     param += ")";
02200     matching(RPAR);
02201     break;
02202   case COMMA:
02203     param += ",";
02204     matching(COMMA);
02205     break;
02206   case DOT:
02207     param += ".";
02208     matching(DOT);
02209     break;
02210   case EQUAL:
02211     param += "=";
02212     matching(EQUAL);
02213     break;
02214   case MINUS:
02215     param += "-";
02216     matching(MINUS);
02217     break;
02218   case UNDERLINE:
02219     param += "_";
02220     matching(UNDERLINE);
02221     break;
02222   case IDENT:
02223     param += lexan->getTokenData();
02224     matching(IDENT);
02225     break;
02226   case NUMB:
02227     param += lexan->getTokenData();
02228     matching(NUMB);
02229     break;  
02230   case FLOAT:
02231     param += lexan->getTokenData();
02232     matching(FLOAT);
02233     break;
02234   case OTHER:
02235     param += lexan->getTokenData();
02236     DBGLOG_PAR("OTHER" << lexan->getTokenData());
02237     matching(OTHER);
02238     break;
02239   case SPECIAL:
02240     param += lexan->getTokenData();
02241     DBGLOG_PAR("SPECIAL" << lexan->getTokenData());
02242     matching(SPECIAL);
02243     break;
02244   case LBRACE:
02245     brace_count++;
02246     param += "{";
02247     DBGLOG_PAR("{" << brace_count);
02248     matching(LBRACE);
02249     break;
02250   case RBRACE:
02251     if (brace_count) {
02252       brace_count--;
02253       param += "}";
02254       matching(RBRACE);
02255       DBGLOG_PAR("}" << brace_count);
02256     }
02257     else {
02258       DBGLOG_PAR("}" << brace_count);
02259       return false;
02260     }
02261     break;
02262   case LBRACKET:
02263     param += "[";
02264     matching(LBRACKET);
02265     break;
02266   case RBRACKET:
02267     param += "]";
02268     matching(RBRACKET);
02269     break;
02270   default:
02271       errorReportUTOKEN();
02272     throw U_TOKEN;
02273   }
02274   }while (brace_count);
02275   return true;
02276 }
02277 
02278 // TODO: is this used anymore?
02279 bool Parser::NoBracketsToken()
02280 {
02281   int brace_count = 0;
02282   int bracket_count = 0;
02283   do{ // due to pairing of parentheses
02284   switch (lexan->getToken()){
02285   case LPAR: // ( 
02286     param += "(";
02287     matching(LPAR);
02288     break;
02289   case RPAR:
02290     param += ")";
02291     matching(RPAR);
02292     break;
02293   case COMMA:
02294     param += ",";
02295     matching(COMMA);
02296     break;
02297   case DOT:
02298     param += ".";
02299     matching(DOT);
02300     break;
02301   case EQUAL:
02302     param += "=";
02303     matching(EQUAL);
02304     break;
02305   case MINUS:
02306     param += "-";
02307     matching(MINUS);
02308     break;
02309   case UNDERLINE:
02310     param += "_";
02311     matching(UNDERLINE);
02312     break;
02313   case IDENT:
02314     param += lexan->getTokenData();
02315     matching(IDENT);
02316     break;
02317   case NUMB:
02318     param += lexan->getTokenData();
02319     matching(NUMB);
02320     break;  
02321   case FLOAT:
02322     param += lexan->getTokenData();
02323     matching(FLOAT);
02324     break;
02325   case OTHER:
02326     param += lexan->getTokenData();
02327     DBGLOG_PAR("OTHER" << lexan->getTokenData());
02328     matching(OTHER);
02329     break;
02330   case SPECIAL:
02331     param += lexan->getTokenData();
02332     DBGLOG_PAR("SPECIAL" << lexan->getTokenData());
02333     matching(SPECIAL);
02334     break;
02335   case LBRACE: // {
02336     brace_count++;
02337     param += "{";
02338     DBGLOG_PAR("{" << brace_count);
02339     matching(LBRACE);
02340     break;
02341   case RBRACE: // }
02342     if (brace_count) brace_count--;
02343     else throw U_TOKEN;
02344     param += "}";
02345     matching(RBRACE);
02346     DBGLOG_PAR("}" << brace_count);
02347     break;
02348   case LBRACKET: // [
02349     bracket_count++;
02350     param += "[";
02351     DBGLOG_PAR("[" << bracket_count);
02352     matching(LBRACKET);
02353     break;
02354   case RBRACKET: // ]
02355     if (bracket_count) {
02356       bracket_count--;
02357       param += "]";
02358       matching(RBRACKET);
02359       DBGLOG_PAR("]" << bracket_count);
02360     }
02361     else{
02362       if (brace_count == 0)
02363         return false; // end
02364       else
02365         throw U_TOKEN; // not balanced '{' and '}' !!!
02366     }
02367     break;
02368   default:
02369       errorReportUTOKEN();
02370       throw U_TOKEN;
02371       break;
02372   }
02373   } while (bracket_count || brace_count);
02374   
02375   return true;
02376 }
02377 
02378 //-------------------------------------------------------------------------- Parser -->

Generated on Tue Jan 4 2011 03:03:23 for Autoamata editor by  doxygen 1.7.0