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