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>
00021 #include <QVBoxLayout>
00022 #include <QPushButton>
00023
00024 #include <QtDebug>
00025
00026
00027 enum Exceptions{U_EOI, U_TOKEN, NO_STATE, STATE_EXIST, BAD_STATE_NAME, BAD_GRID, U_ERR};
00028
00029
00030
00031
00032 using namespace VaucansonKeywords;
00033
00034
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)
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 {
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':
00260 token = EOI;
00261 readed = true;
00262 DBGLOG_LEX("EOI");
00263 break;
00264 case '%':
00265 while (readChar() != 'l' && input != 'e') {
00266 tokenData += character;
00267 }
00268
00269 DBGLOG_LEX("COMMENT: " << tokenData);
00270 token = COMMENT;
00271 readed = true;
00272 break;
00273 case 'l':
00274 case 'w':
00275 while(readChar() == 'w' || input == 'l'){}
00276 break;
00277 case '\\':
00278 while (readChar() == 'c'){
00279 tokenData += character;
00280 }
00281 token = keyWordTest(tokenData);
00282 if (token == ERR) {
00283
00284 DBGLOG_LEX("not keyword" << tokenData);
00285 tokenData = "\\" + tokenData;
00286 token = SPECIAL;
00287 }
00288 if (token == kwBegin){
00289 if (input == '{'){
00290 tokenData = "";
00291 while (readChar() == 'c'){
00292 tokenData += character;
00293 }
00294 if (tokenData == "VCPicture" && input == '}'){
00295 readChar();
00296 token = kwBeginVCPicture;
00297
00298 DBGLOG_LEX("VCPicture founded!");
00299 }
00300 else {
00301 token = ERR;
00302 }
00303 }
00304 }
00305 readed = true;
00306 break;
00307 case '{':
00308 token = LBRACE;
00309 readChar();
00310 readed = true;
00311 break;
00312 case '}':
00313 token = RBRACE;
00314 readChar();
00315 readed = true;
00316 break;
00317 case '[':
00318 token = LBRACKET;
00319 readChar();
00320 readed = true;
00321 break;
00322 case ']':
00323 token = RBRACKET;
00324 readChar();
00325 readed = true;
00326 break;
00327 case '(':
00328 token = LPAR;
00329 readChar();
00330 readed = true;
00331 break;
00332 case ')':
00333 token = RPAR;
00334 readChar();
00335 readed = true;
00336 break;
00337 case ',':
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':
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':
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
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;
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
00438
00439
00440
00441
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
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
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
00471 stateLineDoubleCoef = DEF_STATE_LINE_DBL_COEF;
00472 stateLineDoubleSep = DEF_STATE_LINE_DBL_SEP;
00473
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
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
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
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;
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
00567
00568 bool Parser::checkNameCorrectness(const QString &name, QString *error)
00569 {
00570
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
00583
00584 bool Parser::run(const QString &filename, QList<State*> &stateList, QRect &gridRect)
00585 {
00586
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();
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
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 << "------------------------------";
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 }
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();
00700 }
00701 catch (Exceptions v)
00702 {
00703 if (v != U_TOKEN) throw;
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
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()){};
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);
00857 break;
00858 case kwEnd:
00859 DBGLOG_PAR("end");
00860 return false;
00861 default:
00862 ChgParam();
00863 }
00864 }
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;
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
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
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();
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
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 case rstStateLineStyle:
01164 matching(rstStateLineStyle);
01165 stateLineStyle = editor->stateLineStyle;
01166 break;
01167 case rstStateLineWidth:
01168 matching(rstStateLineWidth);
01169 stateLineWidth = 1;
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
01212
01213
01214
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 }
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 }
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 }
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;
01352 }
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
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
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:
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();
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();
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)
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
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
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("");
01731 param = "";
01732 QString typeName;
01733 bool left = false; float pos = 0; bool isPosParam = false;
01734 bool small = false;
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:;
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;
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
01865 errorReportUTOKEN();
01866 throw U_TOKEN;
01867 }
01868 break;
01869 default:;
01870 }
01871 }
01872
01873 void Parser::VCurveParam(){
01874 cParam.isAngleA = false;
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
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;
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
01935 TransitionLabel();
01936 label = param;
01937
01938
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;
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 {}
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
02154 void Parser::NameNextPart(){
02155 if (lexan->getToken() == RBRACE){
02156 return;
02157 }
02158 NameAllowedToken();
02159 NameNextPart();
02160 }
02161
02162
02163
02164
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 {
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
02279 bool Parser::NoBracketsToken()
02280 {
02281 int brace_count = 0;
02282 int bracket_count = 0;
02283 do{
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;
02364 else
02365 throw U_TOKEN;
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