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 #ifndef _DtaScript_h_ 23 #define _DtaScript_h_ 24 25 #pragma warning(disable : 4786) 26 27 #include <string> 28 #include <vector> 29 #include <set> 30 #include <map> 31 #include <fstream> 32 33 #include "DtaScriptFactory.h" 34 #include "GrfBlock.h" 35 36 namespace CodeWorker { 37 class ScpStream; 38 39 class DtaScriptVariable; 40 class ExprScriptVariable; 41 class ExprScriptFunction; 42 class ExprScriptExpression; 43 class ExprScriptMotif; 44 class ExprScriptMotifStep; 45 class ExprScriptMotifPath; 46 class ExprScriptScriptFile; 47 48 class EXECUTE_FUNCTION; 49 50 class DtaBNFScript; 51 class GrfForeach; 52 53 54 class GrfScriptBlock : public GrfBlock { 55 public: GrfScriptBlock(GrfBlock * pParentBlock)56 GrfScriptBlock(GrfBlock* pParentBlock) : GrfBlock(pParentBlock) {} 57 58 protected: 59 virtual SEQUENCE_INTERRUPTION_LIST executeInternal(DtaScriptVariable& visibility); 60 }; 61 62 class DtaScript { 63 private: 64 static bool _bParseWithSymbols; 65 static std::vector<const char*> _listOfAllFilesAlreadyParsed; 66 67 DtaScript* _pPreviousScript; 68 std::string _sPreviousVersion; 69 std::string _sPreviousMarkupKey; 70 std::string _sPreviousMarkupValue; 71 const char* _tcFilePtr; 72 std::list<GrfBlock*> _stackOfParsedBlocks; 73 bool _bNumericalExpression; 74 std::set<std::string> _setOfIncludedFiles; 75 76 77 protected: 78 std::string _sCurrentFunctionBody; 79 std::string _sCurrentFunctionTemplateBody; 80 bool _bCurrentFunctionGenericTemplateKey; 81 std::string _sTargetLanguage; 82 83 protected: 84 static std::map<std::string, EXECUTE_FUNCTION*> _mapOfScriptFunctions; 85 static std::map<std::string, std::string> _mapOfSyntaxModes; 86 static std::map<std::string, int> _mapOfReferenceMagicNumbers; 87 88 std::map<int, int> _mapOfAttachedAreas; 89 90 GrfScriptBlock _graph; 91 // DtaScriptVariable* _pVisibility; 92 93 public: 94 DtaScript(/*DtaScriptVariable* pVisibility, */GrfBlock* pParentBlock = NULL, const char* sFilename = NULL); 95 virtual ~DtaScript(); 96 97 static std::fstream* openOutputFile(const char* sFileName, bool bThrowOnError); 98 static void registerScript(const char* sRegistration, EXECUTE_FUNCTION* executeFunction); 99 static EXECUTE_FUNCTION* getRegisteredScript(const char* sRegistration); 100 requiresParsingInformation()101 static inline bool requiresParsingInformation() { return _bParseWithSymbols; } requiresParsingInformation(bool bParseWithSymbols)102 static inline void requiresParsingInformation(bool bParseWithSymbols) { _bParseWithSymbols = bParseWithSymbols; } 103 getBlock()104 inline GrfBlock& getBlock() { return _graph; } 105 void setFilename(const char* sFilename); setFilenamePtr(const char * tcFilePtr)106 inline void setFilenamePtr(const char* tcFilePtr) { _tcFilePtr = tcFilePtr; } getFilenamePtr()107 inline const char* getFilenamePtr() const { return _tcFilePtr; } 108 virtual DtaScriptFactory::SCRIPT_TYPE getType() const; 109 virtual bool isAParseScript() const; 110 virtual bool isAGenerateScript() const; 111 112 virtual void traceEngine() const; 113 114 void parseFile(const char* sScriptFileName, GrfBlock* pIncluded = NULL, bool bDebugMode = false, const std::string& sQuantifyFile = ""); 115 void parseFile(const char* sScriptName, const std::string& sCurrentDirectoryAtCompileTime); 116 void parseStream(ScpStream& myStream, bool bDebugMode = false, const std::string& sQuantifyFile = ""); 117 void parseBlock(ScpStream& script, GrfBlock& block); 118 virtual SEQUENCE_INTERRUPTION_LIST execute(DtaScriptVariable& thisContext); 119 120 ExprScriptVariable* parseVariableExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pParentExpr = NULL); 121 ExprScriptExpression* parseExpression(GrfBlock& block, ScpStream& script); 122 ExprScriptScriptFile* parseScriptFileExpression(GrfBlock& block, ScpStream& script, DtaScriptFactory::SCRIPT_TYPE eScriptType); 123 124 virtual void compileCpp(CppCompilerEnvironment& theCompilerEnvironment, const std::string& sScriptFilename) const; 125 virtual void compileCppHeaderIncludes(CppCompilerEnvironment& theCompilerEnvironment) const; 126 virtual void compileCppFunctions(CppCompilerEnvironment& theCompilerEnvironment) const; 127 128 static std::string convertFilenameAsIdentifier(const std::string& sFilename); 129 static bool equalsIgnoringGenerationHeader(ScpStream& theInputStream, ScpStream& theOutputStream, int& iPosition); 130 131 protected: 132 void allocateLocalParameters(); 133 void freeLocalParameters(); 134 135 virtual void traceInternalEngine() const; 136 137 virtual std::map<std::string, int>& getParsingFunctionRegister(); 138 139 void parseScript(ScpStream& script, GrfBlock& block); 140 virtual void parseInstruction(ScpStream& script, GrfBlock& block); 141 142 virtual void beforeParsingABlock(ScpStream& /*script*/, GrfBlock& /*block*/); 143 virtual void afterParsingABlock(ScpStream& /*script*/, GrfBlock& /*block*/); 144 bool parseKeyword(const std::string& sCommand, ScpStream& script, GrfBlock& block, ExprScriptVariable* pMethodCaller = NULL); 145 146 virtual bool betweenCommands(ScpStream& /*script*/, GrfBlock& /*block*/); 147 virtual void handleNotAWordCommand(ScpStream& script, GrfBlock& block); 148 virtual void parsePreprocessorDirective(const std::string& sDirective, ScpStream& script, GrfBlock& block); 149 virtual void handleUnknownCommand(const std::string& sCommand, ScpStream& script, GrfBlock& block); 150 //##markup##"special procedures" 151 //##begin##"special procedures" 152 virtual void parseAttachInputToSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 153 virtual void parseDetachInputFromSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 154 virtual void parseGoBack(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 155 virtual void parseSetInputLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 156 virtual void parseAllFloatingLocations(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 157 virtual void parseAttachOutputToSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 158 virtual void parseDetachOutputFromSocket(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 159 virtual void parseIncrementIndentLevel(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 160 virtual void parseInsertText(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 161 virtual void parseInsertTextOnce(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 162 virtual void parseInsertTextToFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 163 virtual void parseInsertTextOnceToFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 164 virtual void parseOverwritePortion(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 165 virtual void parsePopulateProtectedArea(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 166 virtual void parseResizeOutputStream(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 167 virtual void parseSetFloatingLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 168 virtual void parseSetOutputLocation(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 169 virtual void parseSetProtectedArea(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 170 virtual void parseWriteBytes(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 171 virtual void parseWriteText(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 172 virtual void parseWriteTextOnce(GrfBlock& /*block*/, ScpStream& script, ExprScriptVariable* /*pMethodCaller*/); 173 //##end##"special procedures" 174 virtual void parseGeneratedFile(GrfBlock& /*block*/, ScpStream& script); 175 virtual void parseGeneratedString(GrfBlock& /*block*/, ScpStream& script); 176 virtual void parseAppendedFile(GrfBlock& /*block*/, ScpStream& script); 177 178 static int computeReferenceMagicNumber(ScpStream& script, const char* tcFilename, const std::string& sKey); 179 static int computeReferenceMagicNumber(ScpStream& theStream, const std::string& sKey); 180 static bool extractReferenceMagicNumber(const std::string& sReferenceFile, const std::string& sKey, int& iMagicNumber); 181 hasTargetLanguage()182 inline bool hasTargetLanguage() const { return !_sTargetLanguage.empty(); } getTargetLanguage()183 inline const std::string& getTargetLanguage() const { return _sTargetLanguage; } 184 virtual DtaBNFScript& getAlienParser() const; 185 void parseAlienInstructions(DtaScriptVariable& parseTree, ScpStream& script, GrfBlock& block); 186 void parseAlienScript(ScpStream& script, GrfBlock& block); 187 void parseAlienBlock(ScpStream& script, GrfBlock& block); 188 void parseAlienInstruction(ScpStream& script, GrfBlock& block); 189 ExprScriptVariable* parseAlienVariableExpression(GrfBlock& block, ScpStream& script); 190 ExprScriptExpression* parseAlienExpression(GrfBlock& block, ScpStream& script); 191 ExprScriptExpression* parseAlienExpression(DtaScriptVariable& parseTree, ScpStream& script, GrfBlock& block); 192 193 protected: 194 void parseEmbeddedScript(ScpStream& script); 195 ExprScriptExpression* parseConstantNodeExpression(GrfBlock& block, ScpStream& script); 196 ExprScriptExpression* parseAssignmentExpression(GrfBlock& block, ScpStream& script); 197 198 ExprScriptExpression* parseConcatenationExpression(GrfBlock& block, ScpStream& script); 199 ExprScriptExpression* parseKeyTemplateExpression(GrfBlock& block, ScpStream& script); 200 void parseDeclare(GrfBlock& block, ScpStream& script); 201 void parseExternal(GrfBlock& block, ScpStream& script); 202 EXPRESSION_TYPE parseVariableType(GrfBlock& block, ScpStream& script); 203 GrfFunction* parseFunction(GrfBlock& block, ScpStream& script, bool bPrototypeOnly = false); 204 void parseReadonlyHook(GrfBlock& block, ScpStream& script); 205 void parseWritefileHook(GrfBlock& block, ScpStream& script); 206 EXPRESSION_TYPE parseClassType(GrfBlock& block, ScpStream& script, EXPRESSION_TYPE exprType); 207 void parseForeachListDeclaration(GrfBlock& block, ScpStream& script, GrfForeach* pForeach); 208 209 private: 210 void parseForeach(GrfBlock& block, ScpStream& script); 211 void parseForfile(GrfBlock& block, ScpStream& script); 212 void parseSelect(GrfBlock& block, ScpStream& script); 213 void parseDo(GrfBlock& block, ScpStream& script); 214 void parseWhile(GrfBlock& block, ScpStream& script); 215 void parseSwitch(GrfBlock& block, ScpStream& script); 216 void parseIfThenElse(GrfBlock& block, ScpStream& script); 217 void parseTryCatch(GrfBlock& block, ScpStream& script); 218 void parseContinue(GrfBlock& block, ScpStream& script); 219 void parseBreak(GrfBlock& block, ScpStream& script); 220 void parseFinally(GrfBlock& block, ScpStream& script); 221 void parseReturn(GrfBlock& block, ScpStream& script); 222 void parseExit(GrfBlock& block, ScpStream& script); 223 void parseDelay(GrfBlock& block, ScpStream& script); 224 void parseNewProject(GrfBlock& block, ScpStream& script); 225 void parseDebug(GrfBlock& block, ScpStream& script); 226 void parseQuantify(GrfBlock& block, ScpStream& script); 227 void parseQuiet(GrfBlock& block, ScpStream& script); 228 void parseFileAsStandardInput(GrfBlock& block, ScpStream& script); 229 void parseStringAsStandardInput(GrfBlock& block, ScpStream& script); 230 void parseNop(GrfBlock& block, ScpStream& script); 231 void parseLocalVariable(GrfBlock& block, ScpStream& script); 232 void parseLocalReference(GrfBlock& block, ScpStream& script); 233 void parseGlobalVariable(GrfBlock& block, ScpStream& script); 234 void parseSetAssignment(GrfBlock& block, ScpStream& script); 235 void parseInsertAssignment(GrfBlock& block, ScpStream& script); 236 void parseSetAll(GrfBlock& block, ScpStream& script); 237 void parseMerge(GrfBlock& block, ScpStream& script); 238 void parseReference(GrfBlock& block, ScpStream& script); 239 void parsePushItem(GrfBlock& block, ScpStream& script); 240 void parseSyntax(GrfBlock& block, ScpStream& script); 241 DtaClass* parseClass(GrfBlock& block, ScpStream& script); 242 void checkIfAllowedFunction(ScpStream& script, ExprScriptFunction& theFunction); 243 //##markup##"common procedures" 244 //##begin##"common procedures" 245 void parseAppendFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 246 void parseAutoexpand(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 247 void parseClearVariable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 248 void parseCompileToCpp(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 249 void parseCopyFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 250 void parseCopyGenerableFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 251 void parseCopySmartDirectory(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 252 void parseCutString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 253 void parseEnvironTable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 254 void parseError(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 255 void parseExecuteString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 256 void parseExpand(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 257 void parseExtendExecutedScript(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 258 void parseGenerate(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 259 void parseGenerateString(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 260 void parseInsertElementAt(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 261 void parseInvertArray(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 262 void parseListAllGeneratedFiles(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 263 void parseLoadProject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 264 void parseOpenLogFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 265 void parseParseAsBNF(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 266 void parseParseStringAsBNF(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 267 void parseParseFree(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 268 void parseProduceHTML(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 269 void parsePutEnv(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 270 void parseRandomSeed(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 271 void parseRemoveAllElements(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 272 void parseRemoveElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 273 void parseRemoveFirstElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 274 void parseRemoveLastElement(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 275 void parseRemoveRecursive(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 276 void parseRemoveVariable(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 277 void parseSaveBinaryToFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 278 void parseSaveProject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 279 void parseSaveProjectTypes(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 280 void parseSaveToFile(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 281 void parseSetCommentBegin(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 282 void parseSetCommentEnd(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 283 void parseSetGenerationHeader(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 284 void parseSetIncludePath(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 285 void parseSetNow(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 286 void parseSetProperty(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 287 void parseSetTextMode(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 288 void parseSetVersion(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 289 void parseSetWriteMode(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 290 void parseSetWorkingPath(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 291 void parseSleep(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 292 void parseSlideNodeContent(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 293 void parseSortArray(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 294 void parseTraceEngine(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 295 void parseTraceLine(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 296 void parseTraceObject(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 297 void parseTraceStack(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 298 void parseTraceText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 299 void parseTranslate(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 300 void parseCloseSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 301 //##end##"common procedures" 302 void parseParsedFile(GrfBlock& block, ScpStream& script); 303 void parseParsedString(GrfBlock& block, ScpStream& script); 304 305 ExprScriptExpression* parsePreprocessorExpression(GrfBlock& block, ScpStream& script); 306 ExprScriptExpression* parseConstantLiteral(GrfBlock& block, ScpStream& script); 307 ExprScriptExpression* parseLiteralUnsignedExpression(GrfBlock& block, ScpStream& script); 308 ExprScriptExpression* parseLiteralExpression(GrfBlock& block, ScpStream& script); 309 ExprScriptExpression* parseFactorExpression(GrfBlock& block, ScpStream& script); 310 ExprScriptExpression* parseShiftExpression(GrfBlock& block, ScpStream& script); 311 ExprScriptExpression* parseArithmeticExpression(GrfBlock& block, ScpStream& script); 312 ExprScriptExpression* parseComparisonExpression(GrfBlock& block, ScpStream& script); 313 ExprScriptExpression* parseTernaryExpression(GrfBlock& block, ScpStream& script); 314 ExprScriptExpression* parseBooleanExpression(GrfBlock& block, ScpStream& script); 315 ExprScriptVariable* parseIndexExpression(GrfBlock& /*block*/, ScpStream& script); 316 ExprScriptVariable* parseReferenceExpression(GrfBlock& /*block*/, ScpStream& script); 317 ExprScriptFunction* parseFunctionExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller, ExprScriptFunction* pFunction, ExprScriptExpression* pTemplate, bool bBracket); 318 ExprScriptVariable* parseVariableExpression(GrfBlock& block, ScpStream& script, ExprScriptVariable* pParentExpr, ExprScriptExpression*& pMethodExpr, GrfCommand*& pMethodProc); 319 320 ExprScriptMotifStep* parseMotifStepExpression(GrfBlock& block, ScpStream& script, ExprScriptMotifPath*& pPathExpr); 321 ExprScriptMotifPath* parseMotifPathExpression(GrfBlock& block, ScpStream& script); 322 ExprScriptMotif* parseMotifConcatExpression(GrfBlock& block, ScpStream& script); 323 ExprScriptMotif* parseMotifAndExpression(GrfBlock& block, ScpStream& script); 324 ExprScriptMotif* parseMotifExpression(GrfBlock& block, ScpStream& script); 325 }; 326 } 327 328 #endif 329