1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifdef WIN32 23 #pragma warning (disable : 4786) 24 #endif 25 26 #include <stdlib.h> 27 28 #include "UtlException.h" 29 #include "ScpStream.h" 30 #include "CppCompilerEnvironment.h" 31 #include "CGRuntime.h" 32 33 #include "ExprScriptVariable.h" 34 #include "DtaScriptVariable.h" 35 #include "DtaProject.h" 36 #include "DtaClass.h" 37 #include "BNFDisjunction.h" 38 #include "BNFConjunction.h" 39 #include "BNFString.h" 40 #include "BNFEndOfFile.h" 41 #include "BNFEndOfLine.h" 42 #include "BNFNextStep.h" 43 #include "BNFScanWindow.h" 44 #include "BNFAndOrJunction.h" 45 #include "BNFBreak.h" 46 #include "BNFComplementary.h" 47 #include "BNFFindToken.h" 48 #include "BNFNot.h" 49 #include "BNFCharLitteral.h" 50 #include "BNFCharBoundaries.h" 51 #include "BNFPushItem.h" 52 #include "BNFInsert.h" 53 #include "BNFReadChar.h" 54 #include "BNFReadByte.h" 55 #include "BNFReadAdaString.h" 56 #include "BNFReadCString.h" 57 #include "BNFReadCChar.h" 58 #include "BNFReadIdentifier.h" 59 #include "BNFReadCompleteIdentifier.h" 60 #include "BNFReadInteger.h" 61 #include "BNFReadNumeric.h" 62 #include "BNFReadPythonString.h" 63 #include "BNFReadText.h" 64 #include "BNFReadBytes.h" 65 #include "BNFReadChars.h" 66 #include "BNFCheck.h" 67 #include "BNFForeach.h" 68 #include "BNFClauseCall.h" 69 #include "BNFMultiplicity.h" 70 #include "BNFClause.h" 71 #include "BNFRatchet.h" 72 #include "BNFTryCatch.h" 73 #include "BNFStepintoHook.h" 74 #include "BNFStepoutHook.h" 75 //##markup##"includes" 76 //##begin##"includes" 77 #include "GrfAttachInputToSocket.h" 78 #include "GrfDetachInputFromSocket.h" 79 #include "GrfGoBack.h" 80 #include "GrfSetInputLocation.h" 81 //##end##"includes" 82 #include "DtaASTNavigator.h" 83 #include "ASTCommand.h" 84 #include "GrfParsedFile.h" 85 #include "GrfParsedString.h" 86 #include "GrfGeneratedFile.h" 87 #include "GrfGeneratedString.h" 88 #include "GrfAppendedFile.h" 89 #include "GrfDebugExecution.h" 90 #include "DtaBNFScript.h" 91 92 #include "DtaTranslateScript.h" 93 #include "BNFIgnore.h" 94 #include "BNFSkipIgnore.h" 95 #include "BNFMoveAhead.h" 96 #include "BNFReadUptoIgnore.h" 97 98 99 namespace CodeWorker { 100 class BNFDisengageIgnore { 101 private: 102 DtaBNFScript* _pBNFScript; 103 104 public: BNFDisengageIgnore(DtaBNFScript * pBNFScript)105 BNFDisengageIgnore(DtaBNFScript* pBNFScript) : _pBNFScript(pBNFScript) { 106 pBNFScript->setIgnoreMode(NOT_IGNORE); 107 } 108 ~BNFDisengageIgnore()109 ~BNFDisengageIgnore() { 110 _pBNFScript->setIgnoreMode(IGNORE_CLAUSE); 111 } 112 }; 113 114 115 class BNFTransformRules { 116 private: 117 ExprScriptExpression* _pFilter; 118 DtaTranslateScript* _pPrototypeScript; 119 DtaTranslateScript* _pProductionRuleScript; 120 121 public: BNFTransformRules()122 inline BNFTransformRules() : _pFilter(NULL), _pPrototypeScript(NULL), _pProductionRuleScript(NULL) {} ~BNFTransformRules()123 ~BNFTransformRules() { 124 delete _pFilter; 125 delete _pPrototypeScript; 126 delete _pProductionRuleScript; 127 } 128 getFilter() const129 inline ExprScriptExpression* getFilter() const { return _pFilter; } setFilter(ExprScriptExpression * pFilter)130 inline void setFilter(ExprScriptExpression* pFilter) { _pFilter = pFilter; } getPrototypeScript() const131 inline DtaTranslateScript* getPrototypeScript() const { return _pPrototypeScript; } setPrototypeScript(DtaTranslateScript * pPrototypeScript)132 inline void setPrototypeScript(DtaTranslateScript* pPrototypeScript) { _pPrototypeScript = pPrototypeScript; } getProductionRuleScript() const133 inline DtaTranslateScript* getProductionRuleScript() const { return _pProductionRuleScript; } setProductionRuleScript(DtaTranslateScript * pProductionRuleScript)134 inline void setProductionRuleScript(DtaTranslateScript* pProductionRuleScript) { _pProductionRuleScript = pProductionRuleScript; } 135 applyRuleTransformer(ScpStream & script,GrfBlock & block,int iStatementBeginning,int iProductionRuleBeginning,const std::string & sClauseName,const std::string & sPrototype,const std::string & sProductionRule)136 virtual bool applyRuleTransformer(ScpStream& script, GrfBlock& block, int iStatementBeginning, int iProductionRuleBeginning, const std::string& sClauseName, const std::string& sPrototype, const std::string& sProductionRule) { 137 DtaScriptVariable theContext; 138 theContext.setValueAtVariable("x", sClauseName.c_str()); 139 std::string sResult = _pFilter->getValue(theContext); 140 if (sResult.empty()) return false; 141 if (_pPrototypeScript != NULL) { 142 std::string sNewPrototype; 143 _pPrototypeScript->translateString(sPrototype, sNewPrototype, DtaProject::getInstance()); 144 if (sNewPrototype != sPrototype) script.insertText(sNewPrototype, iStatementBeginning, sPrototype.size()); 145 } 146 if (_pProductionRuleScript != NULL) { 147 std::string sNewProductionRule; 148 _pProductionRuleScript->translateString(sProductionRule, sNewProductionRule, DtaProject::getInstance()); 149 if (sNewProductionRule != sProductionRule) { 150 script.insertText(sNewProductionRule, iProductionRuleBeginning, sProductionRule.size()); 151 } 152 } 153 return true; 154 } 155 }; 156 157 158 struct TemporaryMatchingStorage { 159 bool bBegin; 160 DtaScriptVariable* pClauseNode; TemporaryMatchingStorageCodeWorker::TemporaryMatchingStorage161 TemporaryMatchingStorage(bool b, DtaScriptVariable* p) : bBegin(b), pClauseNode(p) {} 162 }; 163 164 DtaBNFScript()165 DtaBNFScript::DtaBNFScript() : DtaPatternScript(true), _bBNFMode(true), _pIgnoreClause(NULL), _bNoCase(false), _bImplicitCopy(false), _bParsedFile(false), _pStream(NULL), _pImplicitCopyFunction(NULL), _eIgnoreMode(NOT_IGNORE), _bTrace(false), _pStepintoHook(NULL), _pStepoutHook(NULL), _iRatchetPosition(-1), _pMatchingAreasContainer(NULL), _pASTContainer(NULL), _pParentClauseMatching(NULL) { 166 } 167 DtaBNFScript(GrfBlock * pParentBlock)168 DtaBNFScript::DtaBNFScript(GrfBlock* pParentBlock) : DtaPatternScript(pParentBlock, true), _bBNFMode(true), _pIgnoreClause(NULL), _bNoCase(false), _bImplicitCopy(false), _bParsedFile(false), _pStream(NULL), _pImplicitCopyFunction(NULL), _eIgnoreMode(NOT_IGNORE), _bTrace(false), _pStepintoHook(NULL), _pStepoutHook(NULL), _iRatchetPosition(-1), _pMatchingAreasContainer(NULL), _pASTContainer(NULL), _pParentClauseMatching(NULL) { 169 } 170 DtaBNFScript(EXECUTE_FUNCTION * executeFunction)171 DtaBNFScript::DtaBNFScript(EXECUTE_FUNCTION* executeFunction) : DtaPatternScript(executeFunction, true), _bBNFMode(true), _pIgnoreClause(NULL), _bNoCase(false), _bImplicitCopy(false), _bParsedFile(false), _pStream(NULL), _pImplicitCopyFunction(NULL), _eIgnoreMode(NOT_IGNORE), _bTrace(false), _pStepintoHook(NULL), _pStepoutHook(NULL), _iRatchetPosition(-1), _pMatchingAreasContainer(NULL), _pASTContainer(NULL), _pParentClauseMatching(NULL) { 172 } 173 ~DtaBNFScript()174 DtaBNFScript::~DtaBNFScript() { 175 delete _pImplicitCopyFunction; 176 for (std::map<std::string, std::list<BNFClause*> >::const_iterator i = _listOfClauses.begin(); i != _listOfClauses.end(); i++) { 177 // for (std::list<BNFClause*>::const_iterator j = i->second.begin(); j != i->second.end(); j++) delete *j; 178 } 179 for (std::list<BNFTransformRules*>::const_iterator j = _listOfTransformRules.begin(); j != _listOfTransformRules.end(); ++j) { 180 delete *j; 181 } 182 delete _pStepintoHook; 183 delete _pStepoutHook; 184 delete _pMatchingAreasContainer; 185 delete _pASTContainer; 186 delete _pParentClauseMatching; 187 } 188 getType() const189 DtaScriptFactory::SCRIPT_TYPE DtaBNFScript::getType() const { return DtaScriptFactory::BNF_SCRIPT; } isAParseScript() const190 bool DtaBNFScript::isAParseScript() const { return true; } isAGenerateScript() const191 bool DtaBNFScript::isAGenerateScript() const { return false; } 192 traceEngine() const193 void DtaBNFScript::traceEngine() const { 194 if (getFilenamePtr() == NULL) CGRuntime::traceLine("Extended-BNF script (no filename):"); 195 else CGRuntime::traceLine("Extended-BNF script \"" + std::string(getFilenamePtr()) + "\":"); 196 traceInternalEngine(); 197 } 198 traceInternalEngine() const199 void DtaBNFScript::traceInternalEngine() const { 200 char tcMessage[80]; 201 sprintf(tcMessage, "\tNumber of production rules = %d", _listOfClauses.size()); 202 CGRuntime::traceLine(tcMessage); 203 if (_eIgnoreMode == NOT_IGNORE) CGRuntime::traceLine("\tignore insignificant chars = OFF"); 204 else if (_pIgnoreClause == NULL) CGRuntime::traceLine("\tignore insignificant chars = " + IGNORE_MODEtoString(_eIgnoreMode)); 205 else CGRuntime::traceLine("\tignore insignificant chars = clause '#ignore'"); 206 if (_bNoCase) CGRuntime::traceLine("\tignore case = ON"); 207 208 if (!_mapOfIgnoreClauses.empty()) { 209 CGRuntime::traceText("\tignore clauses: "); 210 for (std::map<std::string, BNFClause*>::const_iterator i = _mapOfIgnoreClauses.begin(); i != _mapOfIgnoreClauses.end(); ++i) { 211 if (i != _mapOfIgnoreClauses.begin()) CGRuntime::traceText(", "); 212 CGRuntime::traceText(i->first); 213 } 214 CGRuntime::traceLine(""); 215 } 216 217 if (_bTrace) CGRuntime::traceLine("\ttrace = ON"); 218 if (_bImplicitCopy) CGRuntime::traceLine("\timplicitCopy = ON"); 219 if (_pImplicitCopyFunction != NULL) { 220 CGRuntime::traceLine("\timplicitCopy function = " + _pImplicitCopyFunction->toString()); 221 } 222 DtaScript::traceInternalEngine(); 223 } 224 getAlienParser() const225 DtaBNFScript& DtaBNFScript::getAlienParser() const { 226 DtaBNFScript* pScript = DtaProject::getInstance().getBNFAlienParser(); 227 if (pScript == NULL) throw UtlException("compiling a BNF script in " + _sTargetLanguage + " requires \"($CODEWORKER_HOME)/" + _sTargetLanguage + "/default-scripts/" + _sTargetLanguage + "BNFScript.cwp\""); 228 return *pScript; 229 } 230 skipEmptyChars(DtaScriptVariable & visibility)231 int DtaBNFScript::skipEmptyChars(DtaScriptVariable& visibility) { 232 int iImplicitCopyPosition; 233 int iLocation; 234 if (_bImplicitCopy) { 235 iImplicitCopyPosition = CGRuntime::getOutputLocation(); 236 iLocation = CGRuntime::getInputLocation(); 237 } else { 238 iImplicitCopyPosition = -1; 239 } 240 if ((_eIgnoreMode != NOT_IGNORE) && (_eIgnoreMode != UNDEFINED_IGNORE)) { 241 bool bCopyImplicitly = _bImplicitCopy; 242 switch(_eIgnoreMode) { 243 case IGNORE_CPP: 244 case IGNORE_JAVA: 245 CGRuntime::_pInputStream->skipEmpty(); 246 break; 247 case IGNORE_HTML: 248 CGRuntime::_pInputStream->skipEmptyHTML(); 249 break; 250 case IGNORE_BLANKS: 251 CGRuntime::_pInputStream->skipBlanks(); 252 break; 253 case IGNORE_SPACES: 254 CGRuntime::_pInputStream->skipSpaces(); 255 break; 256 case IGNORE_ADA: 257 CGRuntime::_pInputStream->skipEmptyAda(); 258 break; 259 case IGNORE_LATEX: 260 CGRuntime::_pInputStream->skipEmptyLaTeX(); 261 break; 262 case IGNORE_CPP_EXCEPT_DOXYGEN: 263 CGRuntime::_pInputStream->skipEmptyCppExceptDoxygen(); 264 break; 265 case IGNORE_CLAUSE: 266 bCopyImplicitly = false; 267 if (_pIgnoreClause != NULL) { 268 BNFDisengageIgnore disengage(this); 269 _pIgnoreClause->executeClause(visibility, 0); 270 } 271 break; 272 default: 273 throw UtlException("internal error in DtaBNFScript::skipEmptyChars(): unrecognized ignore mode encountered"); 274 } 275 if (bCopyImplicitly) { 276 int iLastLocation = CGRuntime::getInputLocation(); 277 if (iLastLocation > iLocation) { 278 std::string sText = CGRuntime::getLastReadChars(iLastLocation - iLocation); 279 writeBinaryData(sText.c_str(), sText.size()); 280 } 281 } 282 } 283 return iImplicitCopyPosition; 284 } 285 writeBinaryData(const char * tcText,int iLength)286 void DtaBNFScript::writeBinaryData(const char* tcText, int iLength) { 287 if (_pImplicitCopyFunction != NULL) { 288 ExprScriptConstant* pConstant = dynamic_cast<ExprScriptConstant*>(_pImplicitCopyFunction->getParameters()[0]); 289 pConstant->setConstant(tcText, iLength); 290 std::string sNewText = _pImplicitCopyFunction->getValue(CGRuntime::getThisInternalNode()); 291 CGRuntime::_pOutputStream->writeBinaryData(sNewText.c_str(), sNewText.size()); 292 } else { 293 CGRuntime::_pOutputStream->writeBinaryData(tcText, iLength); 294 } 295 } 296 storeClauseMatching(DtaScriptVariable & ruleNames,std::map<int,std::map<int,std::list<TemporaryMatchingStorage * >>> & mapOfAreas,BNFClauseMatchingArea * pClauseMatching)297 void DtaBNFScript::storeClauseMatching(DtaScriptVariable& ruleNames, std::map<int, std::map<int, std::list<TemporaryMatchingStorage*> > >& mapOfAreas, BNFClauseMatchingArea* pClauseMatching) { 298 if (pClauseMatching == NULL) return; 299 int iBegin = pClauseMatching->beginPosition; 300 int iEnd = pClauseMatching->endPosition; 301 if (iBegin != iEnd) { 302 DtaScriptVariable* pClauseNode = ruleNames.getArrayElement(pClauseMatching->clause->getSignature()); 303 mapOfAreas[iBegin][iEnd].push_back(new TemporaryMatchingStorage(true, pClauseNode)); 304 for (std::list<BNFClauseMatchingArea*>::iterator i = pClauseMatching->childs.begin(); i != pClauseMatching->childs.end(); ++i) { 305 storeClauseMatching(ruleNames, mapOfAreas, *i); 306 } 307 mapOfAreas[iEnd][iBegin].push_back(new TemporaryMatchingStorage(false, pClauseNode)); 308 } 309 } 310 storeMatchingAreas(DtaScriptVariable & thisContext,DtaScriptVariable * pStorage)311 void DtaBNFScript::storeMatchingAreas(DtaScriptVariable& thisContext, DtaScriptVariable* pStorage) { 312 // storage of matching areas 313 if (pStorage == NULL) { 314 if (_pMatchingAreasContainer == NULL) return; 315 pStorage = thisContext.getVariable(*_pMatchingAreasContainer); 316 } 317 DtaScriptVariable* pAreas = pStorage->insertNode("areas"); 318 DtaScriptVariable* pRules = pStorage->insertNode("rules"); 319 for (std::map<std::string, std::list<BNFClause*> >::iterator i = _listOfClauses.begin(); i != _listOfClauses.end(); ++i) { 320 for (std::list<BNFClause*>::iterator j = i->second.begin(); j != i->second.end(); ++j) { 321 std::string sSignature = (*j)->getSignature(); 322 DtaScriptVariable* pClauseNode = pRules->addElement(sSignature); 323 pClauseNode->setValue(sSignature.c_str()); 324 } 325 } 326 std::map<int, std::map<int, std::list<TemporaryMatchingStorage*> > > mapOfAreas; 327 storeClauseMatching(*pRules, mapOfAreas, _pParentClauseMatching); 328 { 329 for (std::map<int, std::map<int, std::list<TemporaryMatchingStorage*> > >::iterator i = mapOfAreas.begin(); i != mapOfAreas.end(); ++i) { 330 DtaScriptVariable* pPosition = pAreas->addElement(i->first); 331 for (std::map<int, std::list<TemporaryMatchingStorage*> >::reverse_iterator j = i->second.rbegin(); j != i->second.rend(); ++j) { 332 { 333 for (std::list<TemporaryMatchingStorage*>::iterator k = j->second.begin(); k != j->second.end(); ++k) { 334 if ((*k)->bBegin) { 335 pPosition->insertNode("begin")->addElement(j->first)->pushItem("")->setValue((*k)->pClauseNode); 336 } 337 } 338 } 339 { 340 for (std::list<TemporaryMatchingStorage*>::iterator k = j->second.begin(); k != j->second.end(); ++k) { 341 if (!(*k)->bBegin) { 342 pPosition->insertNode("end")->addElement(j->first)->pushItem("")->setValue((*k)->pClauseNode); 343 } 344 } 345 } 346 { 347 // delete the temporary storage 348 for (std::list<TemporaryMatchingStorage*>::iterator k = j->second.begin(); k != j->second.end(); ++k) { 349 delete *k; 350 } 351 } 352 } 353 } 354 } 355 } 356 storeAST(DtaScriptVariable & thisContext,ScpStream & inputStream)357 void DtaBNFScript::storeAST(DtaScriptVariable& thisContext, ScpStream& inputStream) { 358 DtaASTNavigator navigator; 359 std::auto_ptr<DtaASTStructure> structure(navigator.detectASTStructure(*this)); 360 DtaScriptVariable* pStorage = thisContext.getVariable(*_pASTContainer); 361 structure->build(*pStorage); 362 structure->populateAST(*pStorage, *_pParentClauseMatching, inputStream); 363 } 364 generate(ScpStream & stream,DtaScriptVariable & thisContext)365 SEQUENCE_INTERRUPTION_LIST DtaBNFScript::generate(ScpStream& stream, DtaScriptVariable& thisContext) { 366 CGRuntimeOutputStream noOutput(NULL); 367 _bBNFMode = true; 368 _sParsedFileOrContent = ""; 369 _bParsedFile = false; 370 _pStream = &stream; 371 // TO DO PROPERLY 372 return execute(thisContext); 373 } 374 generate(const char * tcFile,DtaScriptVariable & thisContext)375 SEQUENCE_INTERRUPTION_LIST DtaBNFScript::generate(const char* tcFile, DtaScriptVariable& thisContext) { 376 CGRuntimeOutputStream noOutput(NULL); 377 _bBNFMode = true; 378 // absolute path of the parsed file: 379 // avoid ambiguities 380 std::string sAbsolutePath; 381 if (ScpStream::existInputFileFromIncludePath(tcFile, sAbsolutePath)) { 382 if (!ScpStream::existVirtualFile(tcFile)) { 383 sAbsolutePath = CGRuntime::canonizePath(sAbsolutePath); 384 } 385 } else { 386 // should have found! Do not touch the file name, for further error message 387 sAbsolutePath = tcFile; 388 } 389 _sParsedFileOrContent = sAbsolutePath; 390 _bParsedFile = true; 391 // TO DO PROPERLY 392 SEQUENCE_INTERRUPTION_LIST result = execute(thisContext); 393 if (getFilenamePtr() != NULL) { 394 DtaProject::getInstance().captureInputFile(sAbsolutePath.c_str(), getFilenamePtr()); 395 } 396 return result; 397 } 398 generateString(std::string & sContent,DtaScriptVariable & thisContext)399 SEQUENCE_INTERRUPTION_LIST DtaBNFScript::generateString(std::string& sContent, DtaScriptVariable& thisContext) { 400 CGRuntimeOutputStream noOutput(NULL); 401 _bBNFMode = true; 402 _sParsedFileOrContent = sContent; 403 _bParsedFile = false; 404 _pStream = NULL; 405 // TO DO PROPERLY 406 return execute(thisContext); 407 } 408 execute(DtaScriptVariable & thisContext)409 SEQUENCE_INTERRUPTION_LIST DtaBNFScript::execute(DtaScriptVariable& thisContext) { 410 SEQUENCE_INTERRUPTION_LIST result; 411 std::string sParsedFileOrContent = _sParsedFileOrContent; // because '_sParsedFileOrContent' is shared 412 ScpStream* pStream; 413 bool bStreamOwner = (_pStream == NULL); 414 if (bStreamOwner) { 415 if (_bParsedFile) { 416 pStream = new ScpStream(sParsedFileOrContent, ScpStream::IN | ScpStream::PATH); 417 if (pStream == NULL) throw UtlException("unable to open file \"" + sParsedFileOrContent + "\""); 418 } else { 419 pStream = new ScpStream; 420 (*pStream) << sParsedFileOrContent; 421 } 422 } else { 423 pStream = _pStream; 424 } 425 // note if 'final info' was requiring to store coverage, 426 // while this BNF script hasn't required coverage recording 427 bool bCreateMatchingAreasContainerForFinalInfo = false; 428 if ((DtaProject::getInstance().getFinalInfoFlag() & DtaProject::FINAL_INFO_PARSE_COVERAGE_FOR_EVERYBODY) != 0) { 429 if (_bParsedFile && !hasCoverageRecording()) { 430 // create a global variable expression for coverage recording 431 // when final info requires coverage on parsed files; 432 // the variable expression points to an item whose key is the name 433 // of the parsed file. 434 if (DtaProject::getInstance().getGlobalVariable("_FINAL_INFO_PARSE_COVERAGE") == NULL) { 435 DtaProject::getInstance().setGlobalVariable("_FINAL_INFO_PARSE_COVERAGE"); 436 } 437 _pMatchingAreasContainer = new ExprScriptVariable("_FINAL_INFO_PARSE_COVERAGE"); 438 _pMatchingAreasContainer->setArrayKey(new ExprScriptConstant(sParsedFileOrContent.c_str())); 439 bCreateMatchingAreasContainerForFinalInfo = true; 440 } 441 } 442 if (hasCoverageRecording()) { 443 // prepare for recording matching areas 444 delete _pParentClauseMatching; 445 _pParentClauseMatching = NULL; 446 } 447 448 ScpStream* pOldInputStream = CGRuntime::_pInputStream; 449 CGRuntime::_pInputStream = pStream; 450 try { 451 result = DtaPatternScript::execute(thisContext); 452 if (hasCoverageRecording()) { 453 // storage of matching areas / AST in the container 454 CGThisModifier thisModifier(&thisContext); 455 if (_pMatchingAreasContainer != NULL) storeMatchingAreas(thisContext); 456 if (_pASTContainer != NULL) storeAST(thisContext, *CGRuntime::_pInputStream); 457 if (!bCreateMatchingAreasContainerForFinalInfo) { 458 // the variable expression wasn't built for 'final info', but 459 // the latter requires perhaps the coverage 460 if ((DtaProject::getInstance().getFinalInfoFlag() & DtaProject::FINAL_INFO_PARSE_COVERAGE) != 0) { 461 //yes, the coverage tree must be copied for 'final info' 462 DtaScriptVariable* pGlobal = DtaProject::getInstance().getGlobalVariable("_FINAL_INFO_PARSE_COVERAGE"); 463 if (pGlobal == NULL) { 464 pGlobal = DtaProject::getInstance().setGlobalVariable("_FINAL_INFO_PARSE_COVERAGE"); 465 } 466 DtaScriptVariable* pStorage = pGlobal->addElement(sParsedFileOrContent); 467 storeMatchingAreas(thisContext, pStorage); 468 } 469 } 470 // temporary low-level structure used to build the 471 // coverage tree; won't serve anymore 472 delete _pParentClauseMatching; 473 _pParentClauseMatching = NULL; 474 } 475 } catch(UtlException& exception) { 476 int iLine = pStream->getLineCount(); 477 int iCol = pStream->getColCount(); 478 if (bStreamOwner) { 479 pStream->close(); 480 delete pStream; 481 } 482 CGRuntime::_pInputStream = pOldInputStream; 483 std::string sException = exception.getMessage(); 484 std::string sMessage; 485 char tcNumber[64]; 486 if (_bParsedFile) { 487 sMessage = sParsedFileOrContent; 488 sprintf(tcNumber, "(%d,%d):", iLine, iCol); 489 } else if (!sParsedFileOrContent.empty()) { 490 sMessage = CGRuntime::endl() + "----------------- content -----------------" + CGRuntime::endl() + sParsedFileOrContent + CGRuntime::endl() + "-------------------------------------------" + CGRuntime::endl(); 491 sprintf(tcNumber, "line %d, col %d:", iLine, iCol); 492 } 493 sMessage += tcNumber + CGRuntime::endl() + sException; 494 throw UtlException(exception.getTraceStack(), sMessage); 495 } catch(std::exception&) { 496 if (bStreamOwner) { 497 pStream->close(); 498 delete pStream; 499 } 500 CGRuntime::_pInputStream = pOldInputStream; 501 throw; 502 } catch(...) { 503 int iLine = pStream->getLineCount(); 504 int iCol = pStream->getColCount(); 505 if (bStreamOwner) { 506 pStream->close(); 507 delete pStream; 508 } 509 CGRuntime::_pInputStream = pOldInputStream; 510 std::string sMessage; 511 char tcNumber[64]; 512 if (_bParsedFile) { 513 sMessage = sParsedFileOrContent; 514 sprintf(tcNumber, "(%d,%d):", iLine, iCol); 515 } else if (!sParsedFileOrContent.empty()) { 516 sMessage = CGRuntime::endl() + "----------------- content -----------------" + CGRuntime::endl() + sParsedFileOrContent + CGRuntime::endl() + "-------------------------------------------" + CGRuntime::endl(); 517 sprintf(tcNumber, "line %d, col %d:", iLine, iCol); 518 } 519 sMessage += tcNumber + CGRuntime::endl() + "Fatal error: ellipsis exception"; 520 throw UtlException(sMessage); 521 } 522 if (bStreamOwner) { 523 pStream->close(); 524 delete pStream; 525 } 526 CGRuntime::_pInputStream = pOldInputStream; 527 return result; 528 } 529 IGNORE_MODEtoString(IGNORE_MODE eMode)530 std::string DtaBNFScript::IGNORE_MODEtoString(IGNORE_MODE eMode) { 531 std::string sResult; 532 switch(eMode) { 533 case NOT_IGNORE: break; 534 case IGNORE_CPP: sResult = "C++";break; 535 case IGNORE_JAVA: sResult = "JAVA";break; 536 case IGNORE_HTML: sResult = "HTML";break; 537 case IGNORE_BLANKS: sResult = "blanks";break; 538 case IGNORE_SPACES: sResult = "spaces";break; 539 case IGNORE_ADA: sResult = "Ada";break; 540 case IGNORE_LATEX: sResult = "LaTeX";break; 541 case IGNORE_CPP_EXCEPT_DOXYGEN: sResult = "C++/Doxygen";break; 542 case IGNORE_CLAUSE: 543 throw UtlException("IGNORE_MODEtoString('IGNORE_CLAUSE') requires a specific handling!"); 544 default: 545 throw UtlException("internal error in DtaBNFScript::IGNORE_MODEtoString(): unrecognized ignore mode encountered"); 546 } 547 return sResult; 548 } 549 buildClause(ScpStream & script,GrfBlock & parent,const std::string & sName,const std::string & sTemplateKey,bool bGenericKey,int iReturnType,const std::vector<std::string> & listOfParameters,const std::vector<EXPRESSION_TYPE> & listOfParameterTypes,bool bOverload)550 BNFClause& DtaBNFScript::buildClause(ScpStream& script, GrfBlock& parent, const std::string& sName, const std::string& sTemplateKey, bool bGenericKey, int iReturnType, const std::vector<std::string>& listOfParameters, const std::vector<EXPRESSION_TYPE>& listOfParameterTypes, bool bOverload) { 551 std::list<BNFClause*>& listOfHomonyms = _listOfClauses[sName]; 552 BNFClause* pClause = NULL; 553 std::list<BNFClause*>::iterator i; 554 for (i = listOfHomonyms.begin(); i != listOfHomonyms.end(); i++) { 555 if ((*i)->getArity() >= (int) listOfParameters.size()) { 556 for (std::string::size_type j = 0; j < listOfParameters.size(); j++) { 557 const std::string& sClauseParameter = (*i)->getParameter(j); 558 if (listOfParameters[j] != sClauseParameter) { 559 if (sClauseParameter.empty()) { 560 (*i)->setParameter(j, listOfParameters[j], listOfParameterTypes[j]); 561 } else throw UtlException(script, "parameter '" + listOfParameters[j] + "' must be called '" + sClauseParameter + "' into BNF clause declaration"); 562 } 563 } 564 if (((*i)->getArity() > (int) listOfParameters.size()) && !(*i)->isPropagatedParameter()) { 565 throw UtlException(script, "not enough parameters passed to the non-terminal '" + sName + "'"); 566 } 567 if (((*i)->getTemplateKey() == sTemplateKey) && ((*i)->isGenericKey() == bGenericKey)) { 568 pClause = (*i); 569 pClause->setParent(&parent); 570 break; 571 } 572 } else { 573 throw UtlException(script, "too many parameters passed to the non-terminal '" + sName + "'"); 574 } 575 } 576 if (pClause == NULL) { 577 if (bOverload) throw UtlException(script, "cannot overload a clause that doesn't exist yet!"); 578 BNFClause* pTemplateClause = NULL; 579 if (!sTemplateKey.empty()) pTemplateClause = &buildClause(script, parent, sName, "", false, iReturnType, listOfParameters, listOfParameterTypes, false); 580 pClause = new BNFClause(this, &parent, sName, sTemplateKey, bGenericKey, listOfParameters, listOfParameterTypes); 581 if ((sName[0] != '#') && (_graph.getNbCommands() == 0)) { 582 pClause->setPreprocessingIgnoreMode(NOT_IGNORE, NULL); 583 BNFClauseCall* pClauseCall = new BNFRootClauseCall(this, &_graph, _bNoCase); 584 if (requiresParsingInformation()) pClauseCall->setParsingInformation(getFilenamePtr(), script); 585 _graph.add(pClauseCall); 586 pClauseCall->setClause(pClause); 587 } 588 if (!sTemplateKey.empty()) pClause->setTemplateClause(pTemplateClause); 589 listOfHomonyms.push_front(pClause); 590 } else if (bOverload) { 591 BNFClause* pOverloadedClause = pClause; 592 pClause = new BNFClause(this, &parent, sName, sTemplateKey, bGenericKey, listOfParameters, listOfParameterTypes); 593 pOverloadedClause->setOverloadClause(pClause); 594 } 595 pClause->setReturnType(iReturnType); 596 return *pClause; 597 } 598 buildClause(ScpStream & script,GrfBlock & parent,const std::string & sName,unsigned int iArity)599 BNFClause& DtaBNFScript::buildClause(ScpStream& script, GrfBlock& parent, const std::string& sName, unsigned int iArity) { 600 std::list<BNFClause*>& listOfHomonyms = _listOfClauses[sName]; 601 BNFClause* pClause = NULL; 602 for (std::list<BNFClause*>::iterator i = listOfHomonyms.begin(); i != listOfHomonyms.end(); i++) { 603 if ((*i)->getArity() < iArity) { 604 throw UtlException(script, "too many parameters passed to the non-terminal '" + sName + "'"); 605 } else if (((*i)->getArity() > iArity) && !(*i)->isPropagatedParameter()) { 606 throw UtlException(script, "not enough parameters passed to the non-terminal '" + sName + "'"); 607 } else if ((*i)->getTemplateKey().empty()) { 608 pClause = (*i); 609 break; 610 } 611 } 612 if (pClause == NULL) { 613 pClause = new BNFClause(this, &parent, sName, iArity); 614 listOfHomonyms.push_front(pClause); 615 } 616 return *pClause; 617 } 618 parsePreprocessorDirective(const std::string & sDirective,ScpStream & script,GrfBlock & block)619 void DtaBNFScript::parsePreprocessorDirective(const std::string& sDirective, ScpStream& script, GrfBlock& block) { 620 if (sDirective == "#applyBNFRule") { 621 script.skipEmpty(); 622 std::string sIdentifier; 623 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "the directive #applyBNFRule should be followed by a non-terminal"); 624 BNFClauseCall* pClauseCall = parseBNFClauseCall(script, block, sIdentifier, false, _bNoCase); 625 if (requiresParsingInformation()) pClauseCall->setParsingInformation(getFilenamePtr(), script); 626 std::vector<std::string> listOfConstants; 627 bool bConcat; 628 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, true); 629 pClauseCall->setVariableToAssign(pVarToAssign, bConcat); 630 if (!listOfConstants.empty()) pClauseCall->setConstantsToMatch(listOfConstants); 631 script.skipEmpty(); 632 if (!script.isEqualTo(';')) throw UtlException(script, "syntax error, ';' expected to close the directive #applyBNFRule"); 633 } else { 634 DtaPatternScript::parsePreprocessorDirective(sDirective, script, block); 635 } 636 } 637 parseInstruction(ScpStream & script,GrfBlock & block)638 void DtaBNFScript::parseInstruction(ScpStream& script, GrfBlock& block) { 639 if (_bBNFMode) { 640 int iStatementBeginning = script.getInputLocation(); 641 if (script.isEqualTo('#')) { 642 std::string sDirective; 643 script.skipEmpty(); 644 if (!script.readIdentifier(sDirective)) throw UtlException(script, "directive name expected"); 645 sDirective = "#" + sDirective; 646 parseBNFPreprocessorDirective(iStatementBeginning, sDirective, script, block); 647 } else { 648 std::string sClauseName; 649 if (!script.readIdentifier(sClauseName)) { 650 throw UtlException(script, "identifier expected: name of a BNF clause or 'function' or 'declare'"); 651 } 652 if ((sClauseName == "function") || (sClauseName == "external") || (sClauseName == "declare")) { 653 script.skipEmpty(); 654 std::string sIdentifier; 655 int iCursor = script.getInputLocation(); 656 if (script.readIdentifier(sIdentifier)) { 657 script.setInputLocation(iCursor); 658 _bBNFMode = false; 659 if (sClauseName == "function") parseFunction(block, script); 660 else if (sClauseName == "external") parseExternal(block, script); 661 else parseDeclare(block, script); 662 _bBNFMode = true; 663 return; 664 } 665 throw UtlException("syntax error after keyword '" + sClauseName + "'"); 666 } else if ((sClauseName == "readonlyHook") || (sClauseName == "writefileHook")) { 667 _bBNFMode = false; 668 if (sClauseName == "readonlyHook") parseReadonlyHook(block, script); 669 else if (sClauseName == "writefileHook") parseWritefileHook(block, script); 670 _bBNFMode = true; 671 return; 672 } else if ((sClauseName == "stepintoHook") || (sClauseName == "stepoutHook")) { 673 _bBNFMode = false; 674 if (sClauseName == "stepintoHook") parseStepintoHook(block, script); 675 else if (sClauseName == "stepoutHook") parseStepoutHook(block, script); 676 _bBNFMode = true; 677 return; 678 } 679 parseBNFClause(script, block, iStatementBeginning, sClauseName, false); 680 } 681 } else { 682 DtaPatternScript::parseInstruction(script, block); 683 } 684 } 685 parseStepintoHook(GrfBlock & block,ScpStream & script)686 void DtaBNFScript::parseStepintoHook(GrfBlock& block, ScpStream& script) { 687 if (getStepintoHook() != NULL) throw UtlException(script, "function 'stepintoHook(<clause_signature>, <parameters>)' has already been defined and can't be implemented twice"); 688 BNFStepintoHook* pStepintoHook = new BNFStepintoHook(this, &block); 689 if (requiresParsingInformation()) pStepintoHook->setParsingInformation(getFilenamePtr(), script); 690 block.addFunction(pStepintoHook); 691 script.skipEmpty(); 692 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 693 script.skipEmpty(); 694 std::string sIdentifier; 695 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected for <clause_signature>"); 696 pStepintoHook->setClauseSignature(sIdentifier.c_str()); 697 script.skipEmpty(); 698 if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected"); 699 script.skipEmpty(); 700 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected for <parameters>"); 701 pStepintoHook->setParameters(sIdentifier.c_str()); 702 script.skipEmpty(); 703 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 704 std::string _sOldFunctionBody = _sCurrentFunctionBody; 705 std::string _sOldFunctionTemplateBody = _sCurrentFunctionTemplateBody; 706 bool bOldCurrentFunctionGenericTemplateKey = _bCurrentFunctionGenericTemplateKey; 707 _sCurrentFunctionBody = pStepintoHook->getFunctionName(); 708 _sCurrentFunctionTemplateBody = ""; 709 _bCurrentFunctionGenericTemplateKey = false; 710 pStepintoHook->isBodyDefined(true); 711 parseBlock(script, *pStepintoHook); 712 _sCurrentFunctionBody = _sOldFunctionBody; 713 _sCurrentFunctionTemplateBody = _sOldFunctionTemplateBody; 714 _bCurrentFunctionGenericTemplateKey = bOldCurrentFunctionGenericTemplateKey; 715 } 716 parseStepoutHook(GrfBlock & block,ScpStream & script)717 void DtaBNFScript::parseStepoutHook(GrfBlock& block, ScpStream& script) { 718 if (getStepoutHook() != NULL) throw UtlException(script, "function 'StepoutHook(<clause_signature>, <parameters>, <success>)' has already been defined and can't be implemented twice"); 719 BNFStepoutHook* pStepoutHook = new BNFStepoutHook(this, &block); 720 if (requiresParsingInformation()) pStepoutHook->setParsingInformation(getFilenamePtr(), script); 721 block.addFunction(pStepoutHook); 722 script.skipEmpty(); 723 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 724 script.skipEmpty(); 725 std::string sIdentifier; 726 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected for <clause_signature>"); 727 pStepoutHook->setClauseSignature(sIdentifier.c_str()); 728 script.skipEmpty(); 729 if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected"); 730 script.skipEmpty(); 731 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected for <parameters>"); 732 pStepoutHook->setParameters(sIdentifier.c_str()); 733 script.skipEmpty(); 734 if (!script.isEqualTo(',')) throw UtlException(script, "syntax error: ',' expected"); 735 script.skipEmpty(); 736 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "syntax error: argument name expected for <success>"); 737 pStepoutHook->setSuccess(sIdentifier.c_str()); 738 script.skipEmpty(); 739 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 740 std::string _sOldFunctionBody = _sCurrentFunctionBody; 741 std::string _sOldFunctionTemplateBody = _sCurrentFunctionTemplateBody; 742 bool bOldCurrentFunctionGenericTemplateKey = _bCurrentFunctionGenericTemplateKey; 743 _sCurrentFunctionBody = pStepoutHook->getFunctionName(); 744 _sCurrentFunctionTemplateBody = ""; 745 _bCurrentFunctionGenericTemplateKey = false; 746 pStepoutHook->isBodyDefined(true); 747 parseBlock(script, *pStepoutHook); 748 _sCurrentFunctionBody = _sOldFunctionBody; 749 _sCurrentFunctionTemplateBody = _sOldFunctionTemplateBody; 750 _bCurrentFunctionGenericTemplateKey = bOldCurrentFunctionGenericTemplateKey; 751 } 752 parseBNFPreprocessorDirective(int iStatementBeginning,const std::string & sDirective,ScpStream & script,GrfBlock & block)753 void DtaBNFScript::parseBNFPreprocessorDirective(int iStatementBeginning, const std::string& sDirective, ScpStream& script, GrfBlock& block) { 754 if (sDirective == "#ignore") { 755 std::string sClauseName = sDirective; 756 std::string sKey; 757 script.skipEmpty(); 758 if (script.isEqualTo('[')) { 759 script.skipEmpty(); 760 if (!script.readPythonString(sKey)) throw UtlException(script, "syntax error, constant string expected"); 761 script.skipEmpty(); 762 if (!script.isEqualTo(']')) throw UtlException(script, "syntax error, ']' expected"); 763 if (!sKey.empty()) sClauseName += "[" + sKey + "]"; 764 } 765 BNFClause& theIgnoreClause = parseBNFClause(script, block, iStatementBeginning, sClauseName, false); 766 if (theIgnoreClause.getArity() != 0) throw UtlException(script, "clause '#ignore' doesn't accept parameters"); 767 _mapOfIgnoreClauses[sClauseName] = &theIgnoreClause; 768 } else if (sDirective == "#noCase") { 769 _bNoCase = true; 770 } else if (sDirective == "#trace") { 771 _bTrace = true; 772 } else if (sDirective == "#matching") { 773 script.skipEmpty(); 774 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, '(' expected"); 775 script.skipEmpty(); 776 if (_pMatchingAreasContainer != NULL) { 777 delete _pMatchingAreasContainer; 778 _pMatchingAreasContainer = NULL; 779 } 780 _pMatchingAreasContainer = parseBNFVariableExpression(block, script); 781 script.skipEmpty(); 782 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected"); 783 } else if (sDirective == "#parameters") { 784 parseAndPropagateParameters(script, block); 785 } else if (sDirective == "#transformRules") { 786 parseTransformRules(script, block); 787 } else if (sDirective == "#overload") { 788 std::string sClauseName; 789 script.skipEmpty(); 790 if (script.isEqualTo('#')) { 791 script.skipEmpty(); 792 if (script.isEqualToIdentifier("ignore")) sClauseName = "#ignore"; 793 } else if (!script.readIdentifier(sClauseName)) throw UtlException(script, "clause name to overload expected"); 794 parseBNFClause(script, block, iStatementBeginning, sClauseName, true); 795 } else if (sDirective == "#buildAST") { 796 script.skipEmpty(); 797 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, '(' expected"); 798 script.skipEmpty(); 799 if (_pASTContainer != NULL) { 800 delete _pASTContainer; 801 _pASTContainer = NULL; 802 } 803 _pASTContainer = parseBNFVariableExpression(block, script); 804 script.skipEmpty(); 805 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, ')' expected"); 806 } else DtaPatternScript::parsePreprocessorDirective(sDirective, script, block); 807 } 808 parseAndPropagateParameters(ScpStream & script,GrfBlock & block)809 void DtaBNFScript::parseAndPropagateParameters(ScpStream& script, GrfBlock& block) { 810 std::string sFunctionQuantity; 811 script.skipEmpty(); 812 if (!script.readIdentifier(sFunctionQuantity)) throw UtlException(script, "function quantity expected"); 813 script.skipEmpty(); 814 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected"); 815 std::vector<std::string> listOfParameters; 816 std::vector<EXPRESSION_TYPE> listOfParameterTypes; 817 script.skipEmpty(); 818 if (!script.isEqualTo(')')) { 819 int iIndex = 0; 820 EXPRESSION_TYPE paramType; 821 do { 822 std::string sParameter; 823 script.skipEmpty(); 824 if (!script.readIdentifier(sParameter)) throw UtlException(script, "parameter name expected"); 825 script.skipEmpty(); 826 if (!script.isEqualTo(':')) throw UtlException(script, "':' expected after parameter '" + sParameter + "'"); 827 paramType = parseVariableType(block, script); 828 listOfParameters.push_back(sParameter); 829 listOfParameterTypes.push_back(paramType); 830 iIndex++; 831 } while (script.isEqualTo(',')); 832 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected"); 833 } 834 std::auto_ptr<ExprScriptExpression> pFilter(parseExpression(block, script)); 835 for (std::map<std::string, std::list<BNFClause*> >::iterator i = _listOfClauses.begin(); i != _listOfClauses.end(); ++i) { 836 for (std::list<BNFClause*>::iterator j = i->second.begin(); j != i->second.end(); ++j) { 837 (*j)->propagateParameters(*pFilter, sFunctionQuantity, listOfParameters, listOfParameterTypes); 838 } 839 } 840 } 841 parseTransformRules(ScpStream & script,GrfBlock & block)842 void DtaBNFScript::parseTransformRules(ScpStream& script, GrfBlock& block) { 843 BNFTransformRules* pTransformer = new BNFTransformRules; 844 _listOfTransformRules.push_back(pTransformer); 845 pTransformer->setFilter(parseExpression(block, script)); 846 script.skipEmpty(); 847 int iBeforeBrace = script.getInputLocation(); 848 if (!script.isEqualTo('{')) throw UtlException(script, "'{' expected"); 849 script.skipEmpty(); 850 if (!script.isEqualTo('}')) { 851 script.setInputLocation(iBeforeBrace); 852 pTransformer->setPrototypeScript(new DtaTranslateScript(&block)); 853 pTransformer->getPrototypeScript()->parseEmbeddedScript(script); 854 } 855 script.skipEmpty(); 856 iBeforeBrace = script.getInputLocation(); 857 if (!script.isEqualTo('{')) throw UtlException(script, "'{' expected to transform the production rule"); 858 script.skipEmpty(); 859 if (!script.isEqualTo('}')) { 860 script.setInputLocation(iBeforeBrace); 861 pTransformer->setProductionRuleScript(new DtaTranslateScript(&block)); 862 pTransformer->getProductionRuleScript()->parseEmbeddedScript(script); 863 } 864 } 865 parseBNFClause(ScpStream & script,GrfBlock & block,int iStatementBeginning,const std::string & sClauseName,bool bOverload)866 BNFClause& DtaBNFScript::parseBNFClause(ScpStream& script, GrfBlock& block, int iStatementBeginning, const std::string& sClauseName, bool bOverload) { 867 if (!_listOfTransformRules.empty()) { 868 int iLocation = script.getInputLocation(); 869 std::string sCompleteClauseName = sClauseName; 870 script.skipEmpty(); 871 if (script.isEqualTo('<')) { 872 script.skipEmpty(); 873 std::string sText; 874 bool bString = false; 875 if (script.readIdentifier(sText) || script.readPythonString(sText) && (bString = true)) { 876 script.skipEmpty(); 877 if (script.isEqualTo('>')) { 878 if (bString) sText = "\"" + CGRuntime::composeCLikeString(sText) + "\""; 879 sCompleteClauseName += "<" + sText + ">"; 880 } else { 881 // syntax error, to resolve further 882 script.setInputLocation(iLocation); 883 } 884 } else { 885 // syntax error, to resolve further 886 script.setInputLocation(iLocation); 887 } 888 } 889 if (script.findString("::=")) { 890 int iStartProductionRule = script.getInputLocation(); 891 char cChar = '\0'; 892 script.setOutputLocation(iStartProductionRule - 3); 893 script.writeBinaryData(&cChar, 1); 894 std::string sPrototype = script.readBuffer() + iStatementBeginning; 895 cChar = ':'; 896 script.setOutputLocation(iStartProductionRule - 3); 897 script.writeBinaryData(&cChar, 1); 898 int iBrackets = 0; 899 bool bInstruction = false; 900 bool bFail = true; 901 std::string sText; 902 while (bFail && script.skipEmpty()) { 903 switch(script.readChar()) { 904 case '\'': 905 case '\"': 906 script.goBack(); 907 script.readStringOrCharLiteral(sText); 908 break; 909 case '%': 910 if (!script.isEqualTo('>')) break; 911 case '@': 912 do { 913 if (script.isEqualTo('<') && script.isEqualTo('%')) break; 914 script.isEqualTo('\\'); 915 } while (!script.isEqualTo('@')); 916 break; 917 case '{': 918 bInstruction = false; 919 iBrackets++; 920 break; 921 case '}': 922 iBrackets--; 923 break; 924 case '=': 925 if (!bInstruction) bInstruction = script.isEqualTo('>'); 926 break; 927 case ';': 928 if (iBrackets == 0) { 929 if (!bInstruction) bFail = false; 930 else bInstruction = false; 931 } 932 } 933 } 934 if (!bFail) { 935 int iEndProductionRule = script.getInputLocation() - 1; 936 cChar = '\0'; 937 script.setOutputLocation(iEndProductionRule); 938 script.writeBinaryData(&cChar, 1); 939 std::string sProductionRule = script.readBuffer() + iStartProductionRule; 940 cChar = ';'; 941 script.setOutputLocation(iEndProductionRule); 942 script.writeBinaryData(&cChar, 1); 943 for (std::list<BNFTransformRules*>::const_iterator i = _listOfTransformRules.begin(); i != _listOfTransformRules.end(); ++i) { 944 // if the current rule transformer applies with success, 945 // the new rule replaces the old one in the input stream 946 if ((*i)->applyRuleTransformer(script, block, iStatementBeginning, iStartProductionRule, sCompleteClauseName, sPrototype, sProductionRule)) break; 947 } 948 } 949 script.setInputLocation(iLocation); 950 } 951 } 952 std::vector<std::string> listOfParameters; 953 std::vector<EXPRESSION_TYPE> listOfParameterTypes; 954 std::string sTemplateKey; 955 bool bGenericKey = false; 956 script.skipEmpty(); 957 if (script.isEqualTo('<')) { 958 script.skipEmpty(); 959 if (!script.readPythonString(sTemplateKey)) { 960 if (script.readIdentifier(sTemplateKey)) { 961 if (sTemplateKey != "true") { 962 if (sTemplateKey == "false") sTemplateKey = ""; 963 else bGenericKey = true; 964 } 965 } else throw UtlException(script, "template key expected for clause '" + sClauseName + "'"); 966 } 967 script.skipEmpty(); 968 if (!script.isEqualTo('>')) throw UtlException(script, "'>' to end the template key '" + sTemplateKey + "' for clause '" + sClauseName + "'"); 969 script.skipEmpty(); 970 } 971 if (script.isEqualTo('(')) { 972 do { 973 std::string sParameter; 974 script.skipEmpty(); 975 if (!script.readIdentifier(sParameter)) throw UtlException(script, "parameter expected while parsing a BNF clause for declaration"); 976 if (sParameter == sClauseName) throw UtlException(script, "the parameter '" + sParameter + "' cannot hold the same name as the BNF rule"); 977 listOfParameters.push_back(sParameter); 978 script.skipEmpty(); 979 if (!script.isEqualTo(':')) throw UtlException(script, "':' expected after parameter '" + sParameter + "' while parsing a BNF clause for declaration"); 980 script.skipEmpty(); 981 std::string sType; 982 if (!script.readIdentifier(sType)) throw UtlException(script, "parameter type expected for '" + sParameter + "' while parsing a BNF clause for declaration"); 983 EXPRESSION_TYPE exprType; 984 if (sType == "node") exprType = NODE_EXPRTYPE; 985 else if (sType == "reference") exprType = REFERENCE_EXPRTYPE; 986 else if (sType == "value") exprType = VALUE_EXPRTYPE; 987 else if (sType == "variable") { 988 std::string sErrorMessage = script.getMessagePrefix() + "warning! parameter type 'variable' is obsolete since version 3.8.7 -> replace it by 'node'"; 989 if (DtaProject::getInstance().addWarning(sErrorMessage) == 1) CGRuntime::traceLine(sErrorMessage); 990 exprType = NODE_EXPRTYPE; 991 } else throw UtlException(script, "unknown type '" + sType + "' for parameter '" + sParameter + "' while parsing a BNF clause for declaration"); 992 exprType = parseClassType(block, script, exprType); 993 listOfParameterTypes.push_back(exprType); 994 script.skipEmpty(); 995 } while (script.isEqualTo(',')); 996 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected while parsing a BNF clause declaration"); 997 script.skipEmpty(); 998 } 999 if (!script.isEqualTo(':')) throw UtlException(script, "'::=' or ':' expected after parsing a BNF clause declaration"); 1000 int iReturnType = BNFClause::NO_RETURN_TYPE; 1001 IGNORE_MODE ePreprocessingIgnoreMode = UNDEFINED_IGNORE; 1002 BNFClause* pPreprocessingIgnoreClause = NULL; 1003 if (!script.isEqualTo(':')) { 1004 std::string sReturnType; 1005 bool bDefinitionExpected = false; 1006 script.skipEmpty(); 1007 if (script.readIdentifier(sReturnType)) { 1008 if (sReturnType == "list") iReturnType = BNFClause::LIST_RETURN_TYPE; 1009 else if (sReturnType == "node") iReturnType = BNFClause::NODE_RETURN_TYPE; 1010 else if (sReturnType == "value") iReturnType = BNFClause::VALUE_RETURN_TYPE; 1011 else throw UtlException(script, "'list' or 'node' expected instead of '" + sReturnType + "', while parsing return type of a BNF clause for declaration"); 1012 script.skipEmpty(); 1013 if (script.isEqualTo("::=")) bDefinitionExpected = true; 1014 else if (!script.isEqualTo(':')) throw UtlException(script, "'::=' expected after parsing a BNF clause declaration"); 1015 } 1016 if (!bDefinitionExpected) { 1017 if (script.isEqualTo('#')) { 1018 if (script.isEqualTo('!')) { 1019 if (!script.isEqualToIdentifier("ignore")) throw UtlException(script, "'#!ignore' expected as preprocessing of a BNF clause"); 1020 ePreprocessingIgnoreMode = NOT_IGNORE; 1021 } else if (script.isEqualToIdentifier("ignore")) { 1022 ePreprocessingIgnoreMode = parseIgnoreMode(script, pPreprocessingIgnoreClause); 1023 } else { 1024 throw UtlException(script, "'::=' or ':' or '#ignore' expected after parsing a BNF clause declaration"); 1025 } 1026 script.skipEmpty(); 1027 } 1028 script.skipEmpty(); 1029 if (!script.isEqualTo("::=")) throw UtlException(script, "'::=' expected after parsing a BNF clause declaration"); 1030 } 1031 } else if (!script.isEqualTo('=')) throw UtlException(script, "'::=' expected after parsing a BNF clause declaration"); 1032 BNFClause& myClause = buildClause(script, block, sClauseName, sTemplateKey, bGenericKey, iReturnType, listOfParameters, listOfParameterTypes, bOverload); 1033 if (myClause.getNbCommands() > 0) throw UtlException(script, "clause '" + myClause.getSignature() + "' has already been described"); 1034 // register the clause name as a local variable, if returned value/node expected 1035 if ((iReturnType == BNFClause::LIST_RETURN_TYPE) || (iReturnType == BNFClause::NODE_RETURN_TYPE)) { 1036 myClause.addLocalVariable(sClauseName, NODE_EXPRTYPE); 1037 } else if (iReturnType == BNFClause::VALUE_RETURN_TYPE) { 1038 myClause.addLocalVariable(sClauseName, VALUE_EXPRTYPE); 1039 } 1040 // register the generic template key, if any 1041 if (bGenericKey && !sTemplateKey.empty()) { 1042 myClause.addLocalVariable(sTemplateKey, VALUE_EXPRTYPE); 1043 } 1044 GrfBlock* pParent; 1045 if (ePreprocessingIgnoreMode != UNDEFINED_IGNORE) { 1046 myClause.setPreprocessingIgnoreMode(ePreprocessingIgnoreMode, pPreprocessingIgnoreClause); 1047 BNFIgnore* pIgnore = new BNFIgnore(this, &myClause, ePreprocessingIgnoreMode, pPreprocessingIgnoreClause); 1048 myClause.add(pIgnore); 1049 pParent = pIgnore; 1050 } else { 1051 pParent = &myClause; 1052 } 1053 script.skipEmpty(); 1054 parseBNFDisjunction(script, myClause, *pParent, _bNoCase, NULL); 1055 script.skipEmpty(); 1056 if (!script.isEqualTo(';')) throw UtlException(script, "';' expected at the end of a BNF clause definition"); 1057 return myClause; 1058 } 1059 parseBNFDisjunction(ScpStream & script,BNFClause & rule,GrfBlock & block,bool bNoCase,BNFStepper * pStepperRE)1060 void DtaBNFScript::parseBNFDisjunction(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bNoCase, BNFStepper* pStepperRE) { 1061 BNFDisjunction* pDisjunction = new BNFDisjunction(this, &block); 1062 if (requiresParsingInformation()) pDisjunction->setParsingInformation(getFilenamePtr(), script); 1063 block.add(pDisjunction); 1064 parseBNFConjunction(script, rule, *pDisjunction, false, bNoCase, pStepperRE); 1065 if (script.isEqualTo('|')) { 1066 do { 1067 parseBNFConjunction(script, rule, *pDisjunction, false, bNoCase, pStepperRE); 1068 } while (script.isEqualTo('|')); 1069 } else { 1070 pDisjunction->moveCommands(block); 1071 block.removeCommand(pDisjunction); 1072 } 1073 } 1074 parseBNFConjunction(ScpStream & script,BNFClause & rule,GrfBlock & block,bool bContinue,bool bNoCase,BNFStepper * pStepperRE)1075 void DtaBNFScript::parseBNFConjunction(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bContinue, bool bNoCase, BNFStepper* pStepperRE) { 1076 BNFConjunction* pConjunction = new BNFConjunction(this, &block); 1077 if (requiresParsingInformation()) pConjunction->setParsingInformation(getFilenamePtr(), script); 1078 block.add(pConjunction); 1079 parseBNFSequence(script, rule, *pConjunction, bContinue, bNoCase, pStepperRE); 1080 if (pConjunction->getNbCommands() == 1) { 1081 pConjunction->moveCommands(block); 1082 block.removeCommand(pConjunction); 1083 } 1084 } 1085 parseBNFSequence(ScpStream & script,BNFClause & rule,GrfBlock & block,bool bContinue,bool bNoCase,BNFStepper * pStepperRE)1086 void DtaBNFScript::parseBNFSequence(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bContinue, bool bNoCase, BNFStepper* pStepperRE) { 1087 bool bSuccess = parseBNFLitteral(script, rule, block, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE); 1088 if (!bSuccess) { 1089 int iChar = script.readChar(); 1090 std::string sChar; 1091 if (iChar < 0) sChar = "end of file"; 1092 else sChar = std::string("'") + (char) iChar + "'"; 1093 throw UtlException(script, "literal expected, instead of " + sChar); 1094 } 1095 while (parseBNFLitteral(script, rule, block, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1096 } 1097 parseBNFVariableExpression(GrfBlock & block,ScpStream & script)1098 ExprScriptVariable* DtaBNFScript::parseBNFVariableExpression(GrfBlock& block, ScpStream& script) { 1099 ExprScriptVariable* pVariableExpr = NULL; 1100 script.skipEmpty(); 1101 std::string sVariableName; 1102 if (script.readIdentifier(sVariableName)) { 1103 block.addBNFLocalVariable(sVariableName, NODE_EXPRTYPE); 1104 pVariableExpr = new ExprScriptVariable(sVariableName.c_str()); 1105 } 1106 return parseVariableExpression(block, script, pVariableExpr); 1107 } 1108 parseLiteralAssignment(ScpStream & script,GrfBlock & block,std::vector<std::string> & listOfConstants,bool & bConcatVariable,bool bVariableAllowed)1109 ExprScriptVariable* DtaBNFScript::parseLiteralAssignment(ScpStream& script, GrfBlock& block, std::vector<std::string>& listOfConstants, bool& bConcatVariable, bool bVariableAllowed) { 1110 ExprScriptVariable* pVariableExpr = NULL; 1111 script.skipEmpty(); 1112 int iLocation = script.getInputLocation(); 1113 if (script.isEqualTo(':')) { 1114 bool bTryVariable = false; 1115 script.skipEmpty(); 1116 if (script.isEqualTo('\"')) { 1117 script.goBack(); 1118 std::string sConstant; 1119 if (!script.readPythonString(sConstant)) throw UtlException(script, "constant string expected"); 1120 listOfConstants.push_back(sConstant); 1121 bTryVariable = bVariableAllowed; 1122 } else if (script.isEqualTo('\'')) { 1123 script.goBack(); 1124 int iChar; 1125 if (!script.readCharLiteral(iChar)) throw UtlException(script, "char literal expected"); 1126 listOfConstants.push_back(std::string(1, (unsigned char) iChar)); 1127 bTryVariable = bVariableAllowed; 1128 } else if (script.isEqualTo('{')) { 1129 do { 1130 script.skipEmpty(); 1131 std::string sConstant; 1132 if (!script.readStringOrCharLiteral(sConstant)) throw UtlException(script, "constant string expected"); 1133 listOfConstants.push_back(sConstant); 1134 script.skipEmpty(); 1135 } while (script.isEqualTo(',')); 1136 if (!script.isEqualTo('}')) throw UtlException(script, "'}' expected to close a set of constant strings"); 1137 bTryVariable = bVariableAllowed; 1138 } else if (bVariableAllowed) { 1139 bConcatVariable = script.isEqualTo('+'); 1140 if (hasTargetLanguage()) { 1141 pVariableExpr = parseAlienVariableExpression(block, script); 1142 } else { 1143 pVariableExpr = parseBNFVariableExpression(block, script); 1144 } 1145 } else { 1146 script.setInputLocation(iLocation); 1147 } 1148 if (bTryVariable) { 1149 script.skipEmpty(); 1150 if (script.isEqualTo(':')) { 1151 bConcatVariable = script.isEqualTo('+'); 1152 if (hasTargetLanguage()) { 1153 pVariableExpr = parseAlienVariableExpression(block, script); 1154 } else { 1155 pVariableExpr = parseBNFVariableExpression(block, script); 1156 } 1157 } 1158 } 1159 } 1160 return pVariableExpr; 1161 } 1162 parseBNFLitteral(ScpStream & script,BNFClause & rule,GrfBlock & block,bool & bContinue,bool & bNoCase,bool bLiteralOnly,BNFStepper * pStepperRE)1163 bool DtaBNFScript::parseBNFLitteral(ScpStream& script, BNFClause& rule, GrfBlock& block, bool& bContinue, bool& bNoCase, bool bLiteralOnly, BNFStepper* pStepperRE) { 1164 bool bSuccess = true; 1165 script.skipEmpty(); 1166 if (script.isEqualTo('\"')) { 1167 script.goBack(); 1168 std::string sText; 1169 if (!script.readPythonString(sText)) throw UtlException(script, "string literal expected into BNF clause definition"); 1170 BNFString* pString = new BNFString(this, &block, sText, bContinue, bNoCase); 1171 if (requiresParsingInformation()) pString->setParsingInformation(getFilenamePtr(), script); 1172 block.add(pString); 1173 std::vector<std::string> listOfConstants; 1174 bool bConcat; 1175 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1176 pString->setVariableToAssign(pVarToAssign, bConcat, rule); 1177 if (!listOfConstants.empty()) throw UtlException(script, "it has no sense to match a string literal with a constant string"); 1178 } else if (script.isEqualTo('\'')) { 1179 script.goBack(); 1180 int iChar; 1181 if (!script.readCharLiteral(iChar)) throw UtlException(script, "char literal expected (between quotes)"); 1182 script.skipEmpty(); 1183 if (script.isEqualTo("..")) { 1184 script.skipEmpty(); 1185 int iEndChar; 1186 if (!script.readCharLiteral(iEndChar)) throw UtlException(script, "char literal expected (between quotes) after '..'"); 1187 if (iChar > iEndChar) throw UtlException(script, "range expression '..' must be ordered correctly"); 1188 BNFCharBoundaries* pCharBoundaries = new BNFCharBoundaries(this, &block, iChar, iEndChar, bContinue, bNoCase); 1189 if (requiresParsingInformation()) pCharBoundaries->setParsingInformation(getFilenamePtr(), script); 1190 block.add(pCharBoundaries); 1191 std::vector<std::string> listOfConstants; 1192 bool bConcat; 1193 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1194 pCharBoundaries->setVariableToAssign(pVarToAssign, bConcat, rule); 1195 if (!listOfConstants.empty()) pCharBoundaries->setConstantsToMatch(listOfConstants); 1196 } else { 1197 BNFCharLitteral* pCharLitteral = new BNFCharLitteral(this, &block, iChar, bContinue, bNoCase); 1198 if (requiresParsingInformation()) pCharLitteral->setParsingInformation(getFilenamePtr(), script); 1199 block.add(pCharLitteral); 1200 std::vector<std::string> listOfConstants; 1201 bool bConcat; 1202 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1203 pCharLitteral->setVariableToAssign(pVarToAssign, bConcat, rule); 1204 if (!listOfConstants.empty()) throw UtlException(script, "a char literal shouldn't expect a set of constant values"); 1205 } 1206 } else if (script.isEqualTo('~') || script.isEqualTo('^')) { 1207 BNFComplementary* pComplementary = new BNFComplementary(this, &block, bContinue); 1208 if (requiresParsingInformation()) pComplementary->setParsingInformation(getFilenamePtr(), script); 1209 block.add(pComplementary); 1210 bool bNextContinue = false; 1211 bool bNextNoCase = bNoCase; 1212 parseBNFLitteral(script, rule, *pComplementary, bNextContinue, bNextNoCase, true /* if '=>' or ':<variable>' after reading this literal, it doesn't belong to it */, pComplementary); 1213 std::vector<std::string> listOfConstants; 1214 bool bConcat; 1215 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1216 pComplementary->setVariableToAssign(pVarToAssign, bConcat, rule); 1217 if (!listOfConstants.empty()) pComplementary->setConstantsToMatch(listOfConstants); 1218 } else if (script.isEqualTo("->")) { 1219 BNFFindToken* pFindToken = new BNFFindToken(this, &block, bContinue); 1220 if (requiresParsingInformation()) pFindToken->setParsingInformation(getFilenamePtr(), script); 1221 block.add(pFindToken); 1222 bool bConcat; 1223 ExprScriptVariable* pVarToAssign; 1224 BNFMultiplicityBoundaries* pBoundaries = parseMultiplicity(script, block); 1225 if (pBoundaries != NULL) { 1226 pFindToken->setBoundaries(pBoundaries); 1227 script.skipEmpty(); 1228 } 1229 if (script.isEqualTo('(')) { 1230 std::vector<std::string> listOfIntermediateConstants; 1231 pVarToAssign = parseLiteralAssignment(script, block, listOfIntermediateConstants, bConcat, true); 1232 pFindToken->setIntermediateVariableToAssign(pVarToAssign, bConcat, rule); 1233 if (!listOfIntermediateConstants.empty()) pFindToken->setIntermediateConstantsToMatch(listOfIntermediateConstants); 1234 script.skipEmpty(); 1235 if (script.isEqualTo('-')) { 1236 std::vector<std::string> listOfFinalConstants; 1237 pVarToAssign = parseLiteralAssignment(script, block, listOfFinalConstants, bConcat, true); 1238 pFindToken->setFinalVariableToAssign(pVarToAssign, bConcat, rule); 1239 if (!listOfFinalConstants.empty()) pFindToken->setFinalConstantsToMatch(listOfFinalConstants); 1240 script.skipEmpty(); 1241 } 1242 if (!script.isEqualTo(')')) { 1243 parseBNFDisjunction(script, rule, pFindToken->createIntermediateSequence(), bNoCase, pStepperRE); 1244 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected"); 1245 } 1246 } 1247 bool bNextContinue = false; 1248 bool bNextNoCase = bNoCase; 1249 parseBNFLitteral(script, rule, *pFindToken, bNextContinue, bNextNoCase, true /* if '=>' or ':<variable>' after reading this literal, it doesn't belong to it */, pFindToken); 1250 std::vector<std::string> listOfConstants; 1251 pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1252 pFindToken->setVariableToAssign(pVarToAssign, bConcat, rule); 1253 if (!listOfConstants.empty()) pFindToken->setConstantsToMatch(listOfConstants); 1254 } else if (script.isEqualTo('!')) { 1255 BNFNot* pNot = new BNFNot(this, &block, bContinue); 1256 if (requiresParsingInformation()) pNot->setParsingInformation(getFilenamePtr(), script); 1257 block.add(pNot); 1258 bool bNextContinue = false; 1259 bool bNextNoCase = bNoCase; 1260 parseBNFLitteral(script, rule, *pNot, bNextContinue, bNextNoCase, true /* if '=>' or ':<variable>' after reading this literal, it doesn't belong to it */, pStepperRE); 1261 } else if (script.isEqualTo('[')) { 1262 BNFMultiplicity* pMultiplicity = new BNFMultiplicity(this, &block, bContinue); 1263 if (requiresParsingInformation()) pMultiplicity->setParsingInformation(getFilenamePtr(), script); 1264 block.add(pMultiplicity); 1265 parseBNFDisjunction(script, rule, *pMultiplicity, bNoCase, pStepperRE); 1266 if (!script.isEqualTo(']')) throw UtlException(script, "']' expected into BNF clause definition"); 1267 parseMultiplicity(script, block, &pMultiplicity->getBoundaries()); 1268 std::vector<std::string> listOfConstants; 1269 bool bConcat; 1270 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1271 pMultiplicity->setVariableToAssign(pVarToAssign, bConcat, rule); 1272 if (!listOfConstants.empty()) pMultiplicity->setConstantsToMatch(listOfConstants); 1273 } else if (script.isEqualTo('#')) { 1274 int iSharpLocation = script.getInputLocation() - 1; 1275 std::string sIdentifier; 1276 if (!script.readIdentifier(sIdentifier)) { 1277 if (script.isEqualTo('!') && script.readIdentifier(sIdentifier)) { 1278 if (sIdentifier == "ignore") { 1279 BNFIgnore* pIgnore = new BNFIgnore(this, &block, NOT_IGNORE, NULL); 1280 if (requiresParsingInformation()) pIgnore->setParsingInformation(getFilenamePtr(), script); 1281 block.add(pIgnore); 1282 while (parseBNFLitteral(script, rule, *pIgnore, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1283 } else { 1284 throw UtlException(script, "macro instruction '#!" + sIdentifier + "' doesn't exist"); 1285 } 1286 } else { 1287 throw UtlException(script, "macro instruction expected after '#'"); 1288 } 1289 } else if (sIdentifier == "catch") { 1290 script.setInputLocation(iSharpLocation); 1291 return false; 1292 } else if (sIdentifier == "continue") { 1293 bool bNextContinue = true; 1294 script.skipEmpty(); 1295 if (script.isEqualTo('(')) { 1296 script.skipEmpty(); 1297 std::string sVariableName; 1298 if (!script.readIdentifier(sVariableName)) throw UtlException(script, "variable name expected to catch the original syntax error"); 1299 if (block.getVariable(sVariableName) == UNKNOWN_EXPRTYPE) block.addBNFLocalVariable(sVariableName, VALUE_EXPRTYPE); 1300 script.skipEmpty(); 1301 if (!script.isEqualTo(',')) throw UtlException(script, "',' expected"); 1302 std::auto_ptr<ExprScriptExpression> pErrorMessageExpr(parseExpression(block, script)); 1303 script.skipEmpty(); 1304 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected to close the expression of '#continue'"); 1305 BNFContinue* pBNFContinue = new BNFContinue(this, &block, new ExprScriptVariable(sVariableName.c_str()), pErrorMessageExpr.release()); 1306 if (requiresParsingInformation()) pBNFContinue->setParsingInformation(getFilenamePtr(), script); 1307 block.add(pBNFContinue); 1308 while (parseBNFLitteral(script, rule, *pBNFContinue->getTryBlock(), bNextContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1309 } else { 1310 while (parseBNFLitteral(script, rule, block, bNextContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1311 } 1312 } else if (sIdentifier == "noCase") { 1313 bool bNextNoCase = true; 1314 while (parseBNFLitteral(script, rule, block, bContinue, bNextNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1315 } else if (sIdentifier == "ratchet") { 1316 BNFRatchet* pBNFRatchet = new BNFRatchet(this, &block); 1317 if (requiresParsingInformation()) pBNFRatchet->setParsingInformation(getFilenamePtr(), script); 1318 block.add(pBNFRatchet); 1319 while (parseBNFLitteral(script, rule, block, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1320 } else if (sIdentifier == "try") { 1321 BNFTryCatch* pBNFTryCatch = new BNFTryCatch(this, &block); 1322 if (requiresParsingInformation()) pBNFTryCatch->setParsingInformation(getFilenamePtr(), script); 1323 block.add(pBNFTryCatch); 1324 do { 1325 script.skipEmpty(); 1326 if (script.isEqualTo('#')) { 1327 int iLocation = script.getInputLocation(); 1328 script.skipEmpty(); 1329 if (script.isEqualTo("catch")) { 1330 script.skipEmpty(); 1331 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error, directive '#catch' expects a '('"); 1332 script.skipEmpty(); 1333 std::string sVariableName; 1334 if (!script.readIdentifier(sVariableName)) throw UtlException(script, "variable name expected to catch the error message"); 1335 if (block.getVariable(sVariableName) == UNKNOWN_EXPRTYPE) block.addBNFLocalVariable(sVariableName, VALUE_EXPRTYPE); 1336 pBNFTryCatch->setErrorVariable(parseVariableExpression(block, script, new ExprScriptVariable(sVariableName.c_str()))); 1337 script.skipEmpty(); 1338 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error, directive '#catch' expects a ')'"); 1339 break; 1340 } else { 1341 script.setInputLocation(iLocation - 1); 1342 } 1343 } else { 1344 script.goBack(); 1345 } 1346 } while (parseBNFLitteral(script, rule, *pBNFTryCatch->getTryBlock(), bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)); 1347 if (pBNFTryCatch->getErrorVariable() == NULL) throw UtlException(script, "directive '#catch' expected before the end of the sequence"); 1348 } else if (sIdentifier == "parsedFile") { 1349 script.skipEmpty(); 1350 if (!isAParseScript()) throw UtlException(script, "directive '#parsedFile' is available on parsing scripts only"); 1351 GrfParsedFile* pParsedFile = new GrfParsedFile(&block); 1352 if (requiresParsingInformation()) pParsedFile->setParsingInformation(getFilenamePtr(), script); 1353 block.add(pParsedFile); 1354 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#parsedFile'"); 1355 script.skipEmpty(); 1356 pParsedFile->setInputFile(parseExpression(block, script)); 1357 script.skipEmpty(); 1358 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#parsedFile'"); 1359 while (parseBNFLitteral(script, rule, *pParsedFile, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1360 } else if (sIdentifier == "parsedString") { 1361 script.skipEmpty(); 1362 if (!isAParseScript()) throw UtlException(script, "directive '#parsedString' is available on parsing scripts only"); 1363 GrfParsedString* pParsedString = new GrfParsedString(&block); 1364 if (requiresParsingInformation()) pParsedString->setParsingInformation(getFilenamePtr(), script); 1365 block.add(pParsedString); 1366 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#parsedString'"); 1367 script.skipEmpty(); 1368 pParsedString->setInputString(parseExpression(block, script)); 1369 script.skipEmpty(); 1370 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#parsedString'"); 1371 while (parseBNFLitteral(script, rule, *pParsedString, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1372 } else if (sIdentifier == "generatedFile") { 1373 script.skipEmpty(); 1374 if (!isAGenerateScript()) throw UtlException(script, "directive '#generatedFile' is available on pattern scripts only"); 1375 GrfGeneratedFile* pGeneratedFile = new GrfGeneratedFile(this, &block); 1376 if (requiresParsingInformation()) pGeneratedFile->setParsingInformation(getFilenamePtr(), script); 1377 block.add(pGeneratedFile); 1378 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#generatedFile'"); 1379 script.skipEmpty(); 1380 pGeneratedFile->setOutputFile(parseExpression(block, script)); 1381 script.skipEmpty(); 1382 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#generatedFile'"); 1383 while (parseBNFLitteral(script, rule, *pGeneratedFile, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1384 } else if (sIdentifier == "generatedString") { 1385 script.skipEmpty(); 1386 if (!isAGenerateScript()) throw UtlException(script, "directive '#generatedString' is available on pattern scripts only"); 1387 GrfGeneratedString* pGeneratedString = new GrfGeneratedString(this, &block); 1388 if (requiresParsingInformation()) pGeneratedString->setParsingInformation(getFilenamePtr(), script); 1389 block.add(pGeneratedString); 1390 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#generatedString'"); 1391 script.skipEmpty(); 1392 pGeneratedString->setOutputString(parseVariableExpression(block, script)); 1393 script.skipEmpty(); 1394 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#generatedString'"); 1395 while (parseBNFLitteral(script, rule, *pGeneratedString, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1396 } else if (sIdentifier == "appendedFile") { 1397 script.skipEmpty(); 1398 if (!isAGenerateScript()) throw UtlException(script, "statement modifier 'append_file' is available on pattern scripts only"); 1399 GrfAppendedFile* pAppendedFile = new GrfAppendedFile(this, &block); 1400 if (requiresParsingInformation()) pAppendedFile->setParsingInformation(getFilenamePtr(), script); 1401 block.add(pAppendedFile); 1402 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#appendedFile'"); 1403 script.skipEmpty(); 1404 pAppendedFile->setOutputFile(parseExpression(block, script)); 1405 script.skipEmpty(); 1406 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#appendedFile'"); 1407 while (parseBNFLitteral(script, rule, *pAppendedFile, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1408 } else if (sIdentifier == "debug") { 1409 GrfDebugExecution* pDebug = new GrfDebugExecution(&block); 1410 if (requiresParsingInformation()) pDebug->setParsingInformation(getFilenamePtr(), script); 1411 block.add(pDebug); 1412 while (parseBNFLitteral(script, rule, *pDebug, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1413 } else if (sIdentifier == "ignore") { 1414 BNFClause* pIgnoreClause = NULL; 1415 IGNORE_MODE eMode = parseIgnoreMode(script, pIgnoreClause); 1416 BNFIgnore* pIgnore = new BNFIgnore(this, &block, eMode, pIgnoreClause); 1417 if (requiresParsingInformation()) pIgnore->setParsingInformation(getFilenamePtr(), script); 1418 block.add(pIgnore); 1419 while (parseBNFLitteral(script, rule, *pIgnore, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1420 } else if (sIdentifier == "nextStep") { 1421 if (pStepperRE == NULL) throw UtlException(script, "'#nextStep' must be declared into a jump ('->') or repeat ('[...]*') statement"); 1422 BNFNextStep* pNextStep = new BNFNextStep(this, &block, pStepperRE); 1423 if (requiresParsingInformation()) pNextStep->setParsingInformation(getFilenamePtr(), script); 1424 block.add(pNextStep); 1425 } else if (sIdentifier == "break") { 1426 BNFBreak* pBreak = new BNFBreak(&block); 1427 if (requiresParsingInformation()) pBreak->setParsingInformation(getFilenamePtr(), script); 1428 block.add(pBreak); 1429 script.skipEmpty(); 1430 if (script.isEqualTo('(')) { 1431 pBreak->setCondition(parseExpression(block, script)); 1432 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected to close the expression of '#break'"); 1433 } 1434 } else if (sIdentifier == "empty") { 1435 BNFEndOfFile* pEndOfFile = new BNFEndOfFile(this, &block, bContinue); 1436 if (requiresParsingInformation()) pEndOfFile->setParsingInformation(getFilenamePtr(), script); 1437 block.add(pEndOfFile); 1438 } else if (sIdentifier == "pushItem") { 1439 BNFPushItem* pPushItem = new BNFPushItem(this, &block); 1440 if (requiresParsingInformation()) pPushItem->setParsingInformation(getFilenamePtr(), script); 1441 block.add(pPushItem); 1442 script.skipEmpty(); 1443 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected after '#pushItem' to pass the array"); 1444 pPushItem->setVariable(parseVariableExpression(block, script)); 1445 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected after passing the array to '#pushItem'"); 1446 parseBNFSequence(script, rule, *pPushItem, bContinue, bNoCase, pStepperRE); 1447 } else if (sIdentifier == "insert") { 1448 BNFInsert* pInsert = new BNFInsert(this, &block); 1449 if (requiresParsingInformation()) pInsert->setParsingInformation(getFilenamePtr(), script); 1450 block.add(pInsert); 1451 script.skipEmpty(); 1452 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected after '#insert' to pass the array"); 1453 pInsert->setVariable(parseVariableExpression(block, script)); 1454 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected after passing the array to '#insert'"); 1455 parseBNFSequence(script, rule, *pInsert, bContinue, bNoCase, pStepperRE); 1456 } else if (sIdentifier == "EOL") { 1457 BNFEndOfLine* pEndOfLine = new BNFEndOfLine(this, &block, bContinue); 1458 if (requiresParsingInformation()) pEndOfLine->setParsingInformation(getFilenamePtr(), script); 1459 block.add(pEndOfLine); 1460 std::vector<std::string> listOfConstants; 1461 bool bConcat; 1462 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1463 pEndOfLine->setVariableToAssign(pVarToAssign, bConcat, rule); 1464 if (!listOfConstants.empty()) pEndOfLine->setConstantsToMatch(listOfConstants); 1465 } else if (sIdentifier == "readChar") { 1466 BNFReadChar* pReadChar = new BNFReadChar(this, &block, bContinue); 1467 if (requiresParsingInformation()) pReadChar->setParsingInformation(getFilenamePtr(), script); 1468 block.add(pReadChar); 1469 std::vector<std::string> listOfConstants; 1470 bool bConcat; 1471 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1472 pReadChar->setVariableToAssign(pVarToAssign, bConcat, rule); 1473 if (!listOfConstants.empty()) pReadChar->setConstantsToMatch(listOfConstants); 1474 } else if (sIdentifier == "readByte") { 1475 BNFReadByte* pReadByte = new BNFReadByte(this, &block, bContinue); 1476 if (requiresParsingInformation()) pReadByte->setParsingInformation(getFilenamePtr(), script); 1477 block.add(pReadByte); 1478 std::vector<std::string> listOfConstants; 1479 bool bConcat; 1480 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1481 pReadByte->setVariableToAssign(pVarToAssign, bConcat, rule); 1482 if (!listOfConstants.empty()) pReadByte->setConstantsToMatch(listOfConstants); 1483 } else if (sIdentifier == "readAdaString") { 1484 BNFReadAdaString* pReadAdaString = new BNFReadAdaString(this, &block, bContinue, bNoCase); 1485 if (requiresParsingInformation()) pReadAdaString->setParsingInformation(getFilenamePtr(), script); 1486 block.add(pReadAdaString); 1487 std::vector<std::string> listOfConstants; 1488 bool bConcat; 1489 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1490 pReadAdaString->setVariableToAssign(pVarToAssign, bConcat, rule); 1491 if (!listOfConstants.empty()) pReadAdaString->setConstantsToMatch(listOfConstants); 1492 } else if (sIdentifier == "readCString") { 1493 BNFReadCString* pReadCString = new BNFReadCString(this, &block, bContinue, bNoCase); 1494 if (requiresParsingInformation()) pReadCString->setParsingInformation(getFilenamePtr(), script); 1495 block.add(pReadCString); 1496 std::vector<std::string> listOfConstants; 1497 bool bConcat; 1498 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1499 pReadCString->setVariableToAssign(pVarToAssign, bConcat, rule); 1500 if (!listOfConstants.empty()) pReadCString->setConstantsToMatch(listOfConstants); 1501 } else if (sIdentifier == "readCChar") { 1502 BNFReadCChar* pReadCChar = new BNFReadCChar(this, &block, bContinue, bNoCase); 1503 if (requiresParsingInformation()) pReadCChar->setParsingInformation(getFilenamePtr(), script); 1504 block.add(pReadCChar); 1505 std::vector<std::string> listOfConstants; 1506 bool bConcat; 1507 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1508 pReadCChar->setVariableToAssign(pVarToAssign, bConcat, rule); 1509 if (!listOfConstants.empty()) pReadCChar->setConstantsToMatch(listOfConstants); 1510 } else if (sIdentifier == "readPythonString") { 1511 BNFReadPythonString* pReadPythonString = new BNFReadPythonString(this, &block, bContinue, bNoCase); 1512 if (requiresParsingInformation()) pReadPythonString->setParsingInformation(getFilenamePtr(), script); 1513 block.add(pReadPythonString); 1514 std::vector<std::string> listOfConstants; 1515 bool bConcat; 1516 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1517 pReadPythonString->setVariableToAssign(pVarToAssign, bConcat, rule); 1518 if (!listOfConstants.empty()) pReadPythonString->setConstantsToMatch(listOfConstants); 1519 } else if (sIdentifier == "readIdentifier") { 1520 BNFReadIdentifier* pReadIdentifier = new BNFReadIdentifier(this, &block, bContinue, bNoCase); 1521 if (requiresParsingInformation()) pReadIdentifier->setParsingInformation(getFilenamePtr(), script); 1522 block.add(pReadIdentifier); 1523 std::vector<std::string> listOfConstants; 1524 bool bConcat; 1525 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1526 pReadIdentifier->setVariableToAssign(pVarToAssign, bConcat, rule); 1527 if (!listOfConstants.empty()) pReadIdentifier->setConstantsToMatch(listOfConstants); 1528 } else if (sIdentifier == "readCompleteIdentifier") { 1529 BNFReadCompleteIdentifier* pReadCompleteIdentifier = new BNFReadCompleteIdentifier(this, &block, bContinue, bNoCase); 1530 if (requiresParsingInformation()) pReadCompleteIdentifier->setParsingInformation(getFilenamePtr(), script); 1531 block.add(pReadCompleteIdentifier); 1532 std::vector<std::string> listOfConstants; 1533 bool bConcat; 1534 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1535 pReadCompleteIdentifier->setVariableToAssign(pVarToAssign, bConcat, rule); 1536 if (!listOfConstants.empty()) pReadCompleteIdentifier->setConstantsToMatch(listOfConstants); 1537 } else if (sIdentifier == "readInteger") { 1538 BNFReadInteger* pReadInteger = new BNFReadInteger(this, &block, bContinue, bNoCase); 1539 if (requiresParsingInformation()) pReadInteger->setParsingInformation(getFilenamePtr(), script); 1540 block.add(pReadInteger); 1541 std::vector<std::string> listOfConstants; 1542 bool bConcat; 1543 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1544 pReadInteger->setVariableToAssign(pVarToAssign, bConcat, rule); 1545 if (!listOfConstants.empty()) pReadInteger->setConstantsToMatch(listOfConstants); 1546 } else if (sIdentifier == "readNumeric") { 1547 BNFReadNumeric* pReadNumeric = new BNFReadNumeric(this, &block, bContinue, bNoCase); 1548 if (requiresParsingInformation()) pReadNumeric->setParsingInformation(getFilenamePtr(), script); 1549 block.add(pReadNumeric); 1550 std::vector<std::string> listOfConstants; 1551 bool bConcat; 1552 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1553 pReadNumeric->setVariableToAssign(pVarToAssign, bConcat, rule); 1554 if (!listOfConstants.empty()) pReadNumeric->setConstantsToMatch(listOfConstants); 1555 } else if (sIdentifier == "readText") { 1556 BNFReadText* pReadText = new BNFReadText(this, &block, bContinue, bNoCase); 1557 if (requiresParsingInformation()) pReadText->setParsingInformation(getFilenamePtr(), script); 1558 block.add(pReadText); 1559 script.skipEmpty(); 1560 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#readText'"); 1561 pReadText->setText(parseExpression(block, script)); 1562 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#readText'"); 1563 std::vector<std::string> listOfConstants; 1564 bool bConcat; 1565 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1566 pReadText->setVariableToAssign(pVarToAssign, bConcat, rule); 1567 if (!listOfConstants.empty()) pReadText->setConstantsToMatch(listOfConstants); 1568 } else if (sIdentifier == "readBytes") { 1569 BNFReadBytes* pReadBytes = new BNFReadBytes(this, &block, bContinue, bNoCase); 1570 if (requiresParsingInformation()) pReadBytes->setParsingInformation(getFilenamePtr(), script); 1571 block.add(pReadBytes); 1572 script.skipEmpty(); 1573 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#readBytes'"); 1574 pReadBytes->setLength(parseExpression(block, script)); 1575 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#readBytes'"); 1576 std::vector<std::string> listOfConstants; 1577 bool bConcat; 1578 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1579 pReadBytes->setVariableToAssign(pVarToAssign, bConcat, rule); 1580 if (!listOfConstants.empty()) pReadBytes->setConstantsToMatch(listOfConstants); 1581 } else if (sIdentifier == "readChars") { 1582 BNFReadChars* pReadChars = new BNFReadChars(this, &block, bContinue, bNoCase); 1583 if (requiresParsingInformation()) pReadChars->setParsingInformation(getFilenamePtr(), script); 1584 block.add(pReadChars); 1585 script.skipEmpty(); 1586 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by clause '#readChars'"); 1587 pReadChars->setLength(parseExpression(block, script)); 1588 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by clause '#readChars'"); 1589 std::vector<std::string> listOfConstants; 1590 bool bConcat; 1591 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1592 pReadChars->setVariableToAssign(pVarToAssign, bConcat, rule); 1593 if (!listOfConstants.empty()) pReadChars->setConstantsToMatch(listOfConstants); 1594 } else if (sIdentifier == "readUptoIgnore") { 1595 BNFClause* pIgnoreClause = NULL; 1596 IGNORE_MODE eMode; 1597 script.skipEmpty(); 1598 if (script.peekChar() == '(') { 1599 eMode = parseIgnoreMode(script, pIgnoreClause); 1600 } else { 1601 eMode = UNDEFINED_IGNORE; 1602 } 1603 BNFReadUptoIgnore* pReadUptoIgnore = new BNFReadUptoIgnore(this, &block, eMode, pIgnoreClause, bContinue); 1604 if (requiresParsingInformation()) pReadUptoIgnore->setParsingInformation(getFilenamePtr(), script); 1605 block.add(pReadUptoIgnore); 1606 script.skipEmpty(); 1607 std::vector<std::string> listOfConstants; 1608 bool bConcat; 1609 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1610 pReadUptoIgnore->setVariableToAssign(pVarToAssign, bConcat, rule); 1611 if (!listOfConstants.empty()) pReadUptoIgnore->setConstantsToMatch(listOfConstants); 1612 } else if (sIdentifier == "skipIgnore") { 1613 BNFClause* pIgnoreClause = NULL; 1614 IGNORE_MODE eMode; 1615 script.skipEmpty(); 1616 if (script.peekChar() == '(') { 1617 eMode = parseIgnoreMode(script, pIgnoreClause); 1618 } else { 1619 eMode = UNDEFINED_IGNORE; 1620 } 1621 BNFSkipIgnore* pSkipIgnore = new BNFSkipIgnore(this, &block, eMode, pIgnoreClause, bContinue); 1622 if (requiresParsingInformation()) pSkipIgnore->setParsingInformation(getFilenamePtr(), script); 1623 block.add(pSkipIgnore); 1624 std::vector<std::string> listOfConstants; 1625 bool bConcat; 1626 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1627 pSkipIgnore->setVariableToAssign(pVarToAssign, bConcat, rule); 1628 if (!listOfConstants.empty()) pSkipIgnore->setConstantsToMatch(listOfConstants); 1629 } else if (sIdentifier == "moveAhead") { 1630 BNFMoveAhead* pMoveAhead = new BNFMoveAhead(&block, bContinue); 1631 if (requiresParsingInformation()) pMoveAhead->setParsingInformation(getFilenamePtr(), script); 1632 block.add(pMoveAhead); 1633 } else if (sIdentifier == "check") { 1634 BNFCheck* pCheck = new BNFCheck(this, &block, bContinue); 1635 if (requiresParsingInformation()) pCheck->setParsingInformation(getFilenamePtr(), script); 1636 block.add(pCheck); 1637 script.skipEmpty(); 1638 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by directive '#check'"); 1639 pCheck->setCondition(parseExpression(block, script)); 1640 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by directive '#check'"); 1641 } else if (sIdentifier == "foreach") { 1642 BNFForeach* pForeach = new BNFForeach(this, &block, bContinue); 1643 if (requiresParsingInformation()) pForeach->setParsingInformation(getFilenamePtr(), script); 1644 block.add(pForeach); 1645 script.skipEmpty(); 1646 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected by directive '#foreach'"); 1647 parseForeachListDeclaration(block, script, pForeach); 1648 script.skipEmpty(); 1649 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected by directive '#foreach'"); 1650 while (parseBNFLitteral(script, rule, *pForeach, bContinue, bNoCase, false /* if '=>' or ':<variable>' after reading this literal, it belongs to it */, pStepperRE)) ; 1651 } else if (sIdentifier == "super") { 1652 int iSuperClause = 0; 1653 std::string sIdentifier; 1654 for (;;) { 1655 iSuperClause++; 1656 script.skipEmpty(); 1657 if (!script.isEqualTo("::")) throw UtlException(script, "'::' expected by directive '#super'"); 1658 script.skipEmpty(); 1659 if (script.isEqualTo('#')) { 1660 script.skipEmpty(); 1661 if (!script.isEqualToIdentifier("super")) throw UtlException(script, "'::#super' expected"); 1662 } else { 1663 if (!script.readIdentifier(sIdentifier)) throw UtlException(script, "non-terminal call expected by directive '#super'"); 1664 break; 1665 } 1666 } 1667 BNFClauseCall* pClauseCall = parseBNFClauseCall(script, block, sIdentifier, bContinue, bNoCase); 1668 pClauseCall->setSuperCallDepth(iSuperClause); 1669 if (requiresParsingInformation()) pClauseCall->setParsingInformation(getFilenamePtr(), script); 1670 std::vector<std::string> listOfConstants; 1671 bool bConcat; 1672 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1673 pClauseCall->setVariableToAssign(pVarToAssign, bConcat, rule); 1674 if (!listOfConstants.empty()) pClauseCall->setConstantsToMatch(listOfConstants); 1675 } else if ((sIdentifier.size() > 3) && (sIdentifier.substr(sIdentifier.size() - 3) == "AST")) { 1676 ASTCommand* pCommand = NULL; 1677 if (sIdentifier == "thisAST") pCommand = new ASTThisCommand(script); 1678 else if (sIdentifier == "valueAST") pCommand = new ASTValueCommand(script); 1679 else if (sIdentifier == "refAST") pCommand = new ASTRefCommand(script); 1680 else if (sIdentifier == "slideAST") pCommand = new ASTSlideCommand(script); 1681 else { 1682 handleUnknownTokenDirective(sIdentifier, script, rule, block, bContinue, bNoCase, bLiteralOnly, pStepperRE); 1683 } 1684 if (pCommand != NULL) { 1685 int iPos = block.getNbCommands(); 1686 parseBNFLitteral(script, rule, block, bContinue, bNoCase, bLiteralOnly, pStepperRE); 1687 if (iPos == block.getNbCommands()) { 1688 throw UtlException(script, "non-terminal call expected after an AST directive (#" + sIdentifier + " here)"); 1689 } 1690 BNFClauseCall* pNonTerminal = dynamic_cast<BNFClauseCall*>(block.getCommand(iPos)); 1691 if (pNonTerminal == NULL) { 1692 throw UtlException(script, "non-terminal call expected after an AST directive (#" + sIdentifier + " here)"); 1693 } 1694 pNonTerminal->addASTCommand(pCommand); 1695 } 1696 } else { 1697 handleUnknownTokenDirective(sIdentifier, script, rule, block, bContinue, bNoCase, bLiteralOnly, pStepperRE); 1698 } 1699 } else if (script.isEqualTo("=>")) { 1700 _bBNFMode = false; 1701 script.skipEmpty(); 1702 if (script.isEqualTo('{')) { 1703 script.goBack(); 1704 GrfBlock* pBlock = new GrfBlock(&block); 1705 if (requiresParsingInformation()) pBlock->setParsingInformation(getFilenamePtr(), script); 1706 block.add(pBlock); 1707 if (hasTargetLanguage()) { 1708 parseAlienBlock(script, *pBlock); 1709 } else { 1710 parseBlock(script, *pBlock); 1711 } 1712 } else { 1713 if (hasTargetLanguage()) { 1714 parseAlienInstruction(script, block); 1715 } else { 1716 parseInstruction(script, block); 1717 } 1718 } 1719 _bBNFMode = true; 1720 } else { 1721 std::string sIdentifier; 1722 if (script.readIdentifier(sIdentifier)) { 1723 BNFClauseCall* pClauseCall = parseBNFClauseCall(script, block, sIdentifier, bContinue, bNoCase); 1724 if (requiresParsingInformation()) pClauseCall->setParsingInformation(getFilenamePtr(), script); 1725 std::vector<std::string> listOfConstants; 1726 bool bConcat; 1727 ExprScriptVariable* pVarToAssign = parseLiteralAssignment(script, block, listOfConstants, bConcat, !bLiteralOnly); 1728 pClauseCall->setVariableToAssign(pVarToAssign, bConcat, rule); 1729 if (!listOfConstants.empty()) pClauseCall->setConstantsToMatch(listOfConstants); 1730 } else { 1731 bSuccess = false; 1732 } 1733 } 1734 if (bSuccess && !bLiteralOnly) { 1735 // binary BNF operators 1736 script.skipEmpty(); 1737 if (script.isEqualTo("|>")) { 1738 BNFScanWindow* pScanWindow = new BNFScanWindow(this, &block, bContinue); 1739 if (requiresParsingInformation()) pScanWindow->setParsingInformation(getFilenamePtr(), script); 1740 int iIndex = block.getNbCommands() - 1; 1741 GrfCommand* pLeftMember = block.getCommand(iIndex); 1742 block.setCommand(iIndex, pScanWindow); 1743 pScanWindow->setWindow(pLeftMember); 1744 bool bNextContinue = false; 1745 bool bNextNoCase = bNoCase; 1746 parseBNFLitteral(script, rule, *pScanWindow, bNextContinue, bNextNoCase, true /* if '=>' or ':<variable>' after reading this literal, it doesn't belong to it */, NULL); 1747 } else if (script.isEqualTo("&|")) { 1748 BNFAndOrJunction* pAndOrJunction = new BNFAndOrJunction(this, &block, bContinue); 1749 if (requiresParsingInformation()) pAndOrJunction->setParsingInformation(getFilenamePtr(), script); 1750 int iIndex = block.getNbCommands() - 1; 1751 GrfCommand* pLeftMember = block.getCommand(iIndex); 1752 block.setCommand(iIndex, pAndOrJunction); 1753 pAndOrJunction->setLeftMember(pLeftMember); 1754 bool bNextContinue = false; 1755 bool bNextNoCase = bNoCase; 1756 parseBNFLitteral(script, rule, *pAndOrJunction, bNextContinue, bNextNoCase, true /* if '=>' or ':<variable>' after reading this literal, it doesn't belong to it */, NULL); 1757 } 1758 } 1759 return bSuccess; 1760 } 1761 parseBNFClauseCall(ScpStream & script,GrfBlock & block,const std::string & sClauseCallName,bool bContinue,bool bNoCase)1762 BNFClauseCall* DtaBNFScript::parseBNFClauseCall(ScpStream& script, GrfBlock& block, const std::string& sClauseCallName, bool bContinue, bool bNoCase) { 1763 BNFClauseCall* pClauseCall = new BNFClauseCall(this, &block, bContinue, bNoCase); 1764 if (requiresParsingInformation()) pClauseCall->setParsingInformation(getFilenamePtr(), script); 1765 block.add(pClauseCall); 1766 script.skipEmpty(); 1767 if (script.isEqualTo('<')) { 1768 ExprScriptExpression* pTemplateExpression = DtaScript::parseKeyTemplateExpression(block, script); 1769 pClauseCall->setTemplateExpression(pTemplateExpression); 1770 script.skipEmpty(); 1771 if (!script.isEqualTo('>')) throw UtlException(script, "'>' expected to end the template expression of clause call '" + sClauseCallName + "'"); 1772 script.skipEmpty(); 1773 } 1774 if (script.isEqualTo('(')) { 1775 do { 1776 ExprScriptExpression* pParameterExpr = DtaScript::parseExpression(block, script); 1777 pClauseCall->addParameter(pParameterExpr); 1778 script.skipEmpty(); 1779 } while (script.isEqualTo(',')); 1780 if (!script.isEqualTo(')')) throw UtlException(script, "')' expected"); 1781 } 1782 BNFClause& myClause = buildClause(script, block, sClauseCallName, pClauseCall->getParameters().size()); 1783 pClauseCall->setClause(&myClause); 1784 return pClauseCall; 1785 } 1786 parseMultiplicity(ScpStream & script,GrfBlock & block,BNFMultiplicityBoundaries * boundaries)1787 BNFMultiplicityBoundaries* DtaBNFScript::parseMultiplicity(ScpStream& script, GrfBlock& block, BNFMultiplicityBoundaries* boundaries) { 1788 BNFMultiplicityBoundaries* pResult = NULL; 1789 script.skipEmpty(); 1790 if (script.isEqualTo('*')) { 1791 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1792 pResult = boundaries; 1793 boundaries->setMultiplicity(0, -1); 1794 } else if (script.isEqualTo('+')) { 1795 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1796 pResult = boundaries; 1797 boundaries->setMultiplicity(1, -1); 1798 } else if (script.isEqualTo('?')) { 1799 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1800 pResult = boundaries; 1801 boundaries->setMultiplicity(0, 1); 1802 } else if (script.isEqualTo("#repeat")) { 1803 script.skipEmpty(); 1804 if (!script.isEqualTo('(')) throw UtlException(script, "'(' expected after '#repeat'"); 1805 script.skipEmpty(); 1806 std::auto_ptr<ExprScriptExpression> pBegin(parseExpression(block, script)); 1807 script.skipEmpty(); 1808 if (script.isEqualTo(',')) { 1809 script.skipEmpty(); 1810 std::auto_ptr<ExprScriptExpression> pEnd(parseExpression(block, script)); 1811 script.skipEmpty(); 1812 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1813 boundaries->setMultiplicity(pBegin.release(), pEnd.release()); 1814 } else { 1815 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1816 boundaries->setMultiplicity(pBegin.release(), NULL); 1817 } 1818 if (!script.isEqualTo(')')) { 1819 if (pResult == NULL) delete boundaries; 1820 throw UtlException(script, "')' expected to close '#repeat'"); 1821 } 1822 pResult = boundaries; 1823 } else { 1824 int iBegin; 1825 int iEnd; 1826 if (script.readInt(iBegin)) { 1827 if (iBegin < 0) throw UtlException(script, "multiplicity 'm..n' or 'm' doesn't allow negative boundaries"); 1828 script.skipEmpty(); 1829 if (script.isEqualTo("..")) { 1830 script.skipEmpty(); 1831 if (script.isEqualTo('*') || script.isEqualTo('n')) iEnd = -1; 1832 else { 1833 if (!script.readInt(iEnd)) throw UtlException(script, "multiplicity expected as 'm..n' format"); 1834 if (iEnd < iBegin) throw UtlException(script, "multiplicity 'm..n' doesn't allow 'm' being greater than 'n'"); 1835 } 1836 } else { 1837 iEnd = iBegin; 1838 } 1839 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1840 pResult = boundaries; 1841 } else { 1842 iBegin = 1; 1843 iEnd = 1; 1844 if (boundaries == NULL) boundaries = new BNFMultiplicityBoundaries; 1845 } 1846 boundaries->setMultiplicity(iBegin, iEnd); 1847 } 1848 return pResult; 1849 } 1850 betweenCommands(ScpStream & script,GrfBlock & block)1851 bool DtaBNFScript::betweenCommands(ScpStream& script, GrfBlock& block) { 1852 return DtaScript::betweenCommands(script, block); 1853 } 1854 handleUnknownCommand(const std::string & sCommand,ScpStream & script,GrfBlock & block)1855 void DtaBNFScript::handleUnknownCommand(const std::string& sCommand, ScpStream& script, GrfBlock& block) { 1856 DtaScript::handleUnknownCommand(sCommand, script, block); 1857 } 1858 handleNotAWordCommand(ScpStream & script,GrfBlock & block)1859 void DtaBNFScript::handleNotAWordCommand(ScpStream& script, GrfBlock& block) { 1860 DtaScript::handleNotAWordCommand(script, block); 1861 } 1862 handleUnknownTokenDirective(const std::string & sDirective,ScpStream & script,BNFClause & rule,GrfBlock & block,bool & bContinue,bool & bNoCase,bool bLiteralOnly,BNFStepper * pStepper)1863 void DtaBNFScript::handleUnknownTokenDirective(const std::string& sDirective, ScpStream& script, BNFClause& rule, GrfBlock& block, bool& bContinue, bool& bNoCase, bool bLiteralOnly, BNFStepper* pStepper) { 1864 throw UtlException(script, "unknown macro instruction '#" + sDirective + "' encountered"); 1865 } 1866 compileCppHeaderIncludes(CppCompilerEnvironment & theCompilerEnvironment) const1867 void DtaBNFScript::compileCppHeaderIncludes(CppCompilerEnvironment& theCompilerEnvironment) const { 1868 theCompilerEnvironment.getHeader() << "namespace CodeWorker {"; 1869 theCompilerEnvironment.getHeader().endl(); 1870 theCompilerEnvironment.getHeader() << "\tclass CGBNFRuntimeEnvironment;"; 1871 theCompilerEnvironment.getHeader().endl(); 1872 theCompilerEnvironment.getHeader() << "}"; 1873 theCompilerEnvironment.getHeader().endl(); 1874 DtaScript::compileCppHeaderIncludes(theCompilerEnvironment); 1875 } 1876 compileCppFunctions(CppCompilerEnvironment & theCompilerEnvironment) const1877 void DtaBNFScript::compileCppFunctions(CppCompilerEnvironment& theCompilerEnvironment) const { 1878 DtaScript::compileCppFunctions(theCompilerEnvironment); 1879 for (std::map<std::string, std::list<BNFClause*> >::const_iterator i = _listOfClauses.begin(); i != _listOfClauses.end(); i++) { 1880 for (std::list<BNFClause*>::const_iterator j = i->second.begin(); j != i->second.end(); j++) { 1881 (*j)->compileCppFunction(theCompilerEnvironment); 1882 } 1883 } 1884 } 1885 compileCppBNFAssignment(CppCompilerEnvironment & theCompilerEnvironment,int iClauseReturnType,ExprScriptVariable & variableToAssign,bool bConcatVariable,const char * tcText)1886 void DtaBNFScript::compileCppBNFAssignment(CppCompilerEnvironment& theCompilerEnvironment, int iClauseReturnType, ExprScriptVariable& variableToAssign, bool bConcatVariable, const char* tcText) { 1887 CW_BODY_INDENT; 1888 variableToAssign.compileCppForBNFSet(theCompilerEnvironment); 1889 if (iClauseReturnType == BNFClause::LIST_RETURN_TYPE) { 1890 CW_BODY_STREAM << ".pushItem(" << tcText << ");"; 1891 } else if (hasTargetLanguage()) { 1892 if (bConcatVariable) { 1893 CW_BODY_STREAM << " += " << tcText << ";"; 1894 } else { 1895 CW_BODY_STREAM << " = " << tcText << ";"; 1896 } 1897 } else { 1898 if (bConcatVariable) { 1899 CW_BODY_STREAM << ".concatenateValue(" << tcText << ");"; 1900 } else { 1901 CW_BODY_STREAM << ".setValue(" << tcText << ");"; 1902 } 1903 } 1904 CW_BODY_ENDL; 1905 } 1906 assignmentToString(ExprScriptVariable * pVariableToAssign,bool bConcatenateVariable)1907 std::string DtaBNFScript::assignmentToString(ExprScriptVariable* pVariableToAssign, bool bConcatenateVariable) { 1908 if (pVariableToAssign != NULL) return ((bConcatenateVariable) ? ":+" : ":") + pVariableToAssign->toString(); 1909 return ""; 1910 } 1911 constantsToString(const std::vector<std::string> & listOfConstants)1912 std::string DtaBNFScript::constantsToString(const std::vector<std::string>& listOfConstants) { 1913 std::string sText; 1914 if (listOfConstants.size() == 1) { 1915 sText = ":\"" + CGRuntime::composeCLikeString(listOfConstants[0]) + "\""; 1916 } else if (!listOfConstants.empty()) { 1917 sText = ":{"; 1918 for (std::vector<std::string>::const_iterator i = listOfConstants.begin(); i != listOfConstants.end(); ++i) { 1919 if (i != listOfConstants.begin()) sText += ", "; 1920 sText += "\"" + CGRuntime::composeCLikeString(*i) + "\""; 1921 } 1922 sText += "}"; 1923 } 1924 return sText; 1925 } 1926 parseIgnoreMode(ScpStream & script,BNFClause * & pPreprocessingIgnoreClause)1927 IGNORE_MODE DtaBNFScript::parseIgnoreMode(ScpStream& script, BNFClause*& pPreprocessingIgnoreClause) { 1928 IGNORE_MODE eMode; 1929 pPreprocessingIgnoreClause = NULL; 1930 script.skipEmpty(); 1931 if (script.isEqualTo('(')) { 1932 script.skipEmpty(); 1933 if (script.isEqualTo("C++/Doxygen")) eMode = IGNORE_CPP_EXCEPT_DOXYGEN; 1934 else if (script.isEqualTo("C++")) eMode = IGNORE_CPP; 1935 else if (script.isEqualTo("JAVA")) eMode = IGNORE_JAVA; 1936 else if (script.isEqualTo("HTML") || script.isEqualTo("XML")) eMode = IGNORE_HTML; 1937 else if (script.isEqualTo("blanks")) eMode = IGNORE_BLANKS; 1938 else if (script.isEqualTo("spaces")) eMode = IGNORE_SPACES; 1939 else if (script.isEqualTo("Ada")) eMode = IGNORE_ADA; 1940 else if (script.isEqualTo("LaTeX")) eMode = IGNORE_LATEX; 1941 else { 1942 eMode = IGNORE_CLAUSE; 1943 std::string sKey; 1944 script.readPythonString(sKey); 1945 if (sKey.empty()) sKey = "#empty"; 1946 else sKey = "#ignore[" + sKey + "]"; 1947 if (_mapOfIgnoreClauses.find(sKey) == _mapOfIgnoreClauses.end()) { 1948 throw UtlException(script, "the ignore clause '" + sKey + "' doesn't exist"); 1949 } 1950 pPreprocessingIgnoreClause = _mapOfIgnoreClauses[sKey]; 1951 } 1952 script.skipEmpty(); 1953 if (!script.isEqualTo(')')) throw UtlException(script, "')' or correct mode expected by clause '#ignore'"); 1954 } else { 1955 eMode = IGNORE_CLAUSE; 1956 if (_mapOfIgnoreClauses.find("#ignore") == _mapOfIgnoreClauses.end()) { 1957 throw UtlException(script, "the ignore clause '#ignore' doesn't exist"); 1958 } 1959 pPreprocessingIgnoreClause = _mapOfIgnoreClauses["#ignore"]; 1960 } 1961 return eMode; 1962 } 1963 1964 //##markup##"parsing" 1965 //##begin##"parsing" parseAttachInputToSocket(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)1966 void DtaBNFScript::parseAttachInputToSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 1967 GrfAttachInputToSocket* pAttachInputToSocket = new GrfAttachInputToSocket; 1968 if (requiresParsingInformation()) pAttachInputToSocket->setParsingInformation(getFilenamePtr(), script); 1969 block.add(pAttachInputToSocket); 1970 script.skipEmpty(); 1971 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 1972 script.skipEmpty(); 1973 if (pMethodCaller == NULL) pAttachInputToSocket->setSocket(parseExpression(block, script)); 1974 else pAttachInputToSocket->setSocket(pMethodCaller); 1975 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 1976 script.skipEmpty(); 1977 if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected"); 1978 } 1979 parseDetachInputFromSocket(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)1980 void DtaBNFScript::parseDetachInputFromSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 1981 GrfDetachInputFromSocket* pDetachInputFromSocket = new GrfDetachInputFromSocket; 1982 if (requiresParsingInformation()) pDetachInputFromSocket->setParsingInformation(getFilenamePtr(), script); 1983 block.add(pDetachInputFromSocket); 1984 script.skipEmpty(); 1985 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 1986 script.skipEmpty(); 1987 if (pMethodCaller == NULL) pDetachInputFromSocket->setSocket(parseExpression(block, script)); 1988 else pDetachInputFromSocket->setSocket(pMethodCaller); 1989 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 1990 script.skipEmpty(); 1991 if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected"); 1992 } 1993 parseGoBack(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)1994 void DtaBNFScript::parseGoBack(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 1995 GrfGoBack* pGoBack = new GrfGoBack; 1996 if (requiresParsingInformation()) pGoBack->setParsingInformation(getFilenamePtr(), script); 1997 block.add(pGoBack); 1998 script.skipEmpty(); 1999 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 2000 script.skipEmpty(); 2001 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 2002 script.skipEmpty(); 2003 if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected"); 2004 } 2005 parseSetInputLocation(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2006 void DtaBNFScript::parseSetInputLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2007 GrfSetInputLocation* pSetInputLocation = new GrfSetInputLocation; 2008 if (requiresParsingInformation()) pSetInputLocation->setParsingInformation(getFilenamePtr(), script); 2009 block.add(pSetInputLocation); 2010 script.skipEmpty(); 2011 if (!script.isEqualTo('(')) throw UtlException(script, "syntax error: '(' expected"); 2012 script.skipEmpty(); 2013 if (pMethodCaller == NULL) pSetInputLocation->setLocation(parseExpression(block, script)); 2014 else pSetInputLocation->setLocation(pMethodCaller); 2015 if (!script.isEqualTo(')')) throw UtlException(script, "syntax error: ')' expected"); 2016 script.skipEmpty(); 2017 if (!script.isEqualTo(';')) throw UtlException(script, "syntax error: ';' expected"); 2018 } 2019 parseAllFloatingLocations(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2020 void DtaBNFScript::parseAllFloatingLocations(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2021 DtaScript::parseAllFloatingLocations(block, script, pMethodCaller); 2022 } 2023 parseAttachOutputToSocket(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2024 void DtaBNFScript::parseAttachOutputToSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2025 DtaScript::parseAttachOutputToSocket(block, script, pMethodCaller); 2026 } 2027 parseDetachOutputFromSocket(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2028 void DtaBNFScript::parseDetachOutputFromSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2029 DtaScript::parseDetachOutputFromSocket(block, script, pMethodCaller); 2030 } 2031 parseIncrementIndentLevel(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2032 void DtaBNFScript::parseIncrementIndentLevel(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2033 DtaScript::parseIncrementIndentLevel(block, script, pMethodCaller); 2034 } 2035 parseInsertText(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2036 void DtaBNFScript::parseInsertText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2037 DtaScript::parseInsertText(block, script, pMethodCaller); 2038 } 2039 parseInsertTextOnce(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2040 void DtaBNFScript::parseInsertTextOnce(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2041 DtaScript::parseInsertTextOnce(block, script, pMethodCaller); 2042 } 2043 parseInsertTextToFloatingLocation(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2044 void DtaBNFScript::parseInsertTextToFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2045 DtaScript::parseInsertTextToFloatingLocation(block, script, pMethodCaller); 2046 } 2047 parseInsertTextOnceToFloatingLocation(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2048 void DtaBNFScript::parseInsertTextOnceToFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2049 DtaScript::parseInsertTextOnceToFloatingLocation(block, script, pMethodCaller); 2050 } 2051 parseOverwritePortion(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2052 void DtaBNFScript::parseOverwritePortion(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2053 DtaScript::parseOverwritePortion(block, script, pMethodCaller); 2054 } 2055 parsePopulateProtectedArea(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2056 void DtaBNFScript::parsePopulateProtectedArea(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2057 DtaScript::parsePopulateProtectedArea(block, script, pMethodCaller); 2058 } 2059 parseResizeOutputStream(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2060 void DtaBNFScript::parseResizeOutputStream(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2061 DtaScript::parseResizeOutputStream(block, script, pMethodCaller); 2062 } 2063 parseSetFloatingLocation(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2064 void DtaBNFScript::parseSetFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2065 DtaScript::parseSetFloatingLocation(block, script, pMethodCaller); 2066 } 2067 parseSetOutputLocation(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2068 void DtaBNFScript::parseSetOutputLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2069 DtaScript::parseSetOutputLocation(block, script, pMethodCaller); 2070 } 2071 parseSetProtectedArea(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2072 void DtaBNFScript::parseSetProtectedArea(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2073 DtaScript::parseSetProtectedArea(block, script, pMethodCaller); 2074 } 2075 parseWriteBytes(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2076 void DtaBNFScript::parseWriteBytes(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2077 DtaScript::parseWriteBytes(block, script, pMethodCaller); 2078 } 2079 parseWriteText(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2080 void DtaBNFScript::parseWriteText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2081 DtaScript::parseWriteText(block, script, pMethodCaller); 2082 } 2083 parseWriteTextOnce(GrfBlock & block,ScpStream & script,ExprScriptVariable * pMethodCaller)2084 void DtaBNFScript::parseWriteTextOnce(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller) { 2085 DtaScript::parseWriteTextOnce(block, script, pMethodCaller); 2086 } 2087 2088 //##end##"parsing" 2089 } 2090