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 _DtaBNFScript_h_ 23 #define _DtaBNFScript_h_ 24 25 #include <list> 26 #include <map> 27 28 #include "ExprScriptFunction.h" 29 #include "DtaPatternScript.h" 30 #include "BNFIgnore.h" // for the enum 'IGNORE_MODE' 31 32 33 #define BNF_SYMBOL_HAS_FAILED \ 34 if (_bContinue) CGRuntime::throwBNFExecutionError(toString());\ 35 CGRuntime::setInputLocation(iLocation);\ 36 if (iImplicitCopyPosition >= 0) CGRuntime::resizeOutputStream(iImplicitCopyPosition);\ 37 return BREAK_INTERRUPTION; 38 39 40 #define CPP_COMPILER_BNF_SYMBOL_BEGIN \ 41 int iCursor = theCompilerEnvironment.newCursor();\ 42 char tcLocation[64];\ 43 sprintf(tcLocation, "_compilerClauseLocation_%d", iCursor);\ 44 char tcImplicitCopy[64];\ 45 sprintf(tcImplicitCopy, "_compilerClauseImplicitCopy_%d", iCursor);\ 46 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "// " << toString();\ 47 theCompilerEnvironment.getBody().endl();\ 48 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "int " << tcLocation << " = CGRuntime::getInputLocation();";\ 49 theCompilerEnvironment.getBody().endl();\ 50 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "int " << tcImplicitCopy << " = theEnvironment.skipEmptyChars();";\ 51 theCompilerEnvironment.getBody().endl() 52 53 #define CPP_COMPILER_BNF_SYMBOL_HAS_FAILED \ 54 if (_bContinue) {\ 55 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "\tCGRuntime::throwBNFExecutionError(";\ 56 theCompilerEnvironment.getBody().writeString(toString());\ 57 theCompilerEnvironment.getBody() << ");";\ 58 } else {\ 59 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "\tCGRuntime::setInputLocation(" << tcLocation << ");";\ 60 theCompilerEnvironment.getBody().endl();\ 61 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "\tif (" << tcImplicitCopy << " >= 0) CGRuntime::resizeOutputStream(" << tcImplicitCopy << ");";\ 62 theCompilerEnvironment.getBody().endl();\ 63 theCompilerEnvironment.getBody() << theCompilerEnvironment.getIndentation() << "\t_compilerClauseSuccess = false;";\ 64 }\ 65 theCompilerEnvironment.getBody().endl() 66 67 68 69 namespace CodeWorker { 70 class ExprScriptVariable; 71 class DtaScriptVariable; 72 class BNFClause; 73 class BNFClauseCall; 74 class BNFStepper; 75 class BNFStepintoHook; 76 class BNFStepoutHook; 77 78 class BNFTransformRules; // defined in "DtaBNFScript.cpp" 79 struct TemporaryMatchingStorage; // defined in "DtaBNFScript.cpp" 80 81 struct BNFClauseMatchingArea; 82 struct BNFMultiplicityBoundaries; 83 84 85 class DtaBNFScript : public DtaPatternScript { 86 private: 87 bool _bBNFMode; 88 std::string _sParsedFileOrContent; // just for passing the parameters to 'execute()' 89 bool _bParsedFile; 90 ScpStream* _pStream; 91 std::map<std::string, std::list<BNFClause*> > _listOfClauses; 92 std::list<BNFTransformRules*> _listOfTransformRules; 93 IGNORE_MODE _eIgnoreMode; 94 BNFClause* _pIgnoreClause; 95 std::map<std::string, BNFClause*> _mapOfIgnoreClauses; 96 bool _bNoCase; 97 int _iRatchetPosition; 98 99 BNFStepintoHook* _pStepintoHook; 100 BNFStepoutHook* _pStepoutHook; 101 bool _bTrace; 102 std::string _sTraceIndentation; 103 104 ExprScriptVariable* _pMatchingAreasContainer; 105 ExprScriptVariable* _pASTContainer; 106 BNFClauseMatchingArea* _pParentClauseMatching; 107 108 protected: 109 bool _bImplicitCopy; 110 ExprScriptFunction* _pImplicitCopyFunction; 111 112 public: 113 DtaBNFScript(); 114 DtaBNFScript(/*DtaScriptVariable* pVisibility, */GrfBlock* pParentBlock); 115 DtaBNFScript(EXECUTE_FUNCTION* executeFunction); 116 virtual ~DtaBNFScript(); 117 getClauses()118 inline const std::map<std::string, std::list<BNFClause*> >& getClauses() const { return _listOfClauses; } 119 setBNFMode(bool bBNFMode)120 inline void setBNFMode(bool bBNFMode) { _bBNFMode = bBNFMode; } getIgnoreMode()121 inline IGNORE_MODE getIgnoreMode() const { return _eIgnoreMode; } setIgnoreMode(IGNORE_MODE eMode)122 inline void setIgnoreMode(IGNORE_MODE eMode) { _eIgnoreMode = eMode; } getIgnoreClause()123 inline BNFClause* getIgnoreClause() const { return _pIgnoreClause; } setIgnoreClause(BNFClause * pIgnoreClause)124 inline void setIgnoreClause(BNFClause* pIgnoreClause) { 125 _pIgnoreClause = pIgnoreClause; 126 } implicitCopy()127 inline bool implicitCopy() const { return _bImplicitCopy; } implicitCopy(bool bImplicitCopy)128 inline void implicitCopy(bool bImplicitCopy) { _bImplicitCopy = bImplicitCopy; } getImplicitCopyFunction()129 inline ExprScriptFunction* getImplicitCopyFunction() const { return _pImplicitCopyFunction; } setImplicitCopyFunction(ExprScriptFunction * pFunction)130 inline void setImplicitCopyFunction(ExprScriptFunction* pFunction) { _pImplicitCopyFunction = pFunction; } getRatchetPosition()131 inline int getRatchetPosition() const { return _iRatchetPosition; } setRatchetPosition(int iPosition)132 inline void setRatchetPosition(int iPosition) { _iRatchetPosition = iPosition; } trace()133 inline bool trace() const { return _bTrace; } incrementTraceIndentation()134 inline void incrementTraceIndentation() { _sTraceIndentation += " "; } decrementTraceIndentation()135 inline void decrementTraceIndentation() { _sTraceIndentation = _sTraceIndentation.substr(1); } traceIndentation()136 inline const std::string& traceIndentation() const { return _sTraceIndentation; } getStepintoHook()137 inline BNFStepintoHook* getStepintoHook() const { return _pStepintoHook; } setStepintoHook(BNFStepintoHook * pHook)138 inline void setStepintoHook(BNFStepintoHook* pHook) { _pStepintoHook = pHook; } getStepoutHook()139 inline BNFStepoutHook* getStepoutHook() const { return _pStepoutHook; } setStepoutHook(BNFStepoutHook * pHook)140 inline void setStepoutHook(BNFStepoutHook* pHook) { _pStepoutHook = pHook; } 141 getMatchingAreasContainer()142 inline ExprScriptVariable* getMatchingAreasContainer() const { return _pMatchingAreasContainer; } getASTContainer()143 inline ExprScriptVariable* getASTContainer() const { return _pASTContainer; } hasCoverageRecording()144 inline bool hasCoverageRecording() const { return (_pMatchingAreasContainer != NULL) || (_pASTContainer != NULL); } getParentClauseMatching()145 inline BNFClauseMatchingArea* getParentClauseMatching() const { return _pParentClauseMatching; } setParentClauseMatching(BNFClauseMatchingArea * pParentClauseMatching)146 inline void setParentClauseMatching(BNFClauseMatchingArea* pParentClauseMatching) { _pParentClauseMatching = pParentClauseMatching; } 147 void storeMatchingAreas(DtaScriptVariable& thisContext, DtaScriptVariable* pStorage = NULL); 148 void storeAST(DtaScriptVariable& thisContext, ScpStream& inputStream); 149 150 virtual DtaScriptFactory::SCRIPT_TYPE getType() const; 151 virtual bool isAParseScript() const; 152 virtual bool isAGenerateScript() const; 153 154 virtual void traceEngine() const; 155 156 int skipEmptyChars(DtaScriptVariable& visibility); 157 void writeBinaryData(const char* tcText, int iLength); 158 159 virtual SEQUENCE_INTERRUPTION_LIST generate(const char* sFile, DtaScriptVariable& thisContext); 160 virtual SEQUENCE_INTERRUPTION_LIST generate(ScpStream& stream, DtaScriptVariable& thisContext); 161 virtual SEQUENCE_INTERRUPTION_LIST generateString(std::string& sContent, DtaScriptVariable& thisContext); 162 virtual SEQUENCE_INTERRUPTION_LIST execute(DtaScriptVariable& thisContext); 163 164 virtual void compileCppHeaderIncludes(CppCompilerEnvironment& theCompilerEnvironment) const; 165 virtual void compileCppFunctions(CppCompilerEnvironment& theCompilerEnvironment) const; 166 virtual void compileCppBNFAssignment(CppCompilerEnvironment& theCompilerEnvironment, int iClauseReturnType, ExprScriptVariable& variableToAssign, bool bConcatVariable, const char* tcText); 167 168 static std::string assignmentToString(ExprScriptVariable* pVariableToAssign, bool bConcatenateVariable); 169 static std::string constantsToString(const std::vector<std::string>& listOfConstants); 170 171 static std::string IGNORE_MODEtoString(IGNORE_MODE eMode); 172 protected: 173 virtual bool betweenCommands(ScpStream& script, GrfBlock& block); 174 virtual void handleUnknownCommand(const std::string& sCommand, ScpStream& script, GrfBlock& block); 175 virtual void handleNotAWordCommand(ScpStream& script, GrfBlock& block); 176 virtual void parseBNFPreprocessorDirective(int iStatementBeginning, const std::string& sDirective, ScpStream& script, GrfBlock& block); 177 virtual void handleUnknownTokenDirective(const std::string& sDirective, ScpStream& script, BNFClause& rule, GrfBlock& block, bool& bContinue, bool& bNoCase, bool bLiteralOnly, BNFStepper* pStepper); 178 179 virtual void traceInternalEngine() const; 180 181 virtual void parsePreprocessorDirective(const std::string& sDirective, ScpStream& script, GrfBlock& block); 182 BNFClause& parseBNFClause(ScpStream& script, GrfBlock& block, int iStatementBeginning, const std::string& sClauseName, bool bOverload); 183 virtual void parseInstruction(ScpStream& script, GrfBlock& block); 184 void parseStepintoHook(GrfBlock& block, ScpStream& script); 185 void parseStepoutHook(GrfBlock& block, ScpStream& script); 186 187 bool parseBNFLitteral(ScpStream& script, BNFClause& rule, GrfBlock& block, bool& bContinue, bool& bNoCase, bool bLiteralOnly, BNFStepper* pStepperRE); 188 //##markup##"parsing" 189 //##begin##"parsing" 190 virtual void parseAttachInputToSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 191 virtual void parseDetachInputFromSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 192 virtual void parseGoBack(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 193 virtual void parseSetInputLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 194 virtual void parseAllFloatingLocations(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 195 virtual void parseAttachOutputToSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 196 virtual void parseDetachOutputFromSocket(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 197 virtual void parseIncrementIndentLevel(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 198 virtual void parseInsertText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 199 virtual void parseInsertTextOnce(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 200 virtual void parseInsertTextToFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 201 virtual void parseInsertTextOnceToFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 202 virtual void parseOverwritePortion(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 203 virtual void parsePopulateProtectedArea(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 204 virtual void parseResizeOutputStream(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 205 virtual void parseSetFloatingLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 206 virtual void parseSetOutputLocation(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 207 virtual void parseSetProtectedArea(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 208 virtual void parseWriteBytes(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 209 virtual void parseWriteText(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 210 virtual void parseWriteTextOnce(GrfBlock& block, ScpStream& script, ExprScriptVariable* pMethodCaller); 211 //##end##"parsing" 212 213 virtual DtaBNFScript& getAlienParser() const; 214 215 private: 216 void storeClauseMatching(DtaScriptVariable& ruleNames, std::map<int, std::map<int, std::list<TemporaryMatchingStorage*> > >& mapOfAreas, BNFClauseMatchingArea* pClauseMatching); 217 218 BNFClause& 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); 219 BNFClause& buildClause(ScpStream& script, GrfBlock& parent, const std::string& sName, unsigned int iArity); 220 221 void parseBNFDisjunction(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bNoCase, BNFStepper* pStepperRE); 222 void parseBNFConjunction(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bContinue, bool bNoCase, BNFStepper* pStepperRE); 223 void parseBNFSequence(ScpStream& script, BNFClause& rule, GrfBlock& block, bool bContinue, bool bNoCase, BNFStepper* pStepperRE); 224 ExprScriptVariable* parseBNFVariableExpression(GrfBlock& block, ScpStream& script); 225 ExprScriptVariable* parseLiteralAssignment(ScpStream& script, GrfBlock& block, std::vector<std::string>& listOfConstants, bool& bConcatVariable, bool bVariableAllowed); 226 BNFClauseCall* parseBNFClauseCall(ScpStream& script, GrfBlock& block, const std::string& sClauseCallName, bool bContinue, bool bNoCase); 227 BNFMultiplicityBoundaries* parseMultiplicity(ScpStream& script, GrfBlock& block, BNFMultiplicityBoundaries* boundaries = NULL); 228 void parseAndPropagateParameters(ScpStream& script, GrfBlock& block); 229 void parseTransformRules(ScpStream& script, GrfBlock& block); 230 231 IGNORE_MODE parseIgnoreMode(ScpStream& script, BNFClause*& pPreprocessingIgnoreClause); 232 }; 233 } 234 235 #endif 236