1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2006 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 "UtlException.h" 27 28 #ifndef WIN32 29 # include "UtlString.h" // for Debian/gcc 2.95.4 30 #endif 31 32 #include "ScpStream.h" 33 #include "CppCompilerEnvironment.h" 34 #include "CGRuntime.h" 35 36 #include "DtaScriptVariable.h" 37 #include "ExprScriptVariable.h" 38 #include "DtaBNFScript.h" 39 #include "BNFClause.h" 40 #include "DtaVisitor.h" 41 #include "BNFReadPythonString.h" 42 43 namespace CodeWorker { BNFReadPythonString(DtaBNFScript * pBNFScript,GrfBlock * pParent,bool bContinue,bool bNoCase)44 BNFReadPythonString::BNFReadPythonString(DtaBNFScript* pBNFScript, GrfBlock* pParent, bool bContinue, bool bNoCase) : _pBNFScript(pBNFScript), GrfCommand(pParent), _pVariableToAssign(NULL), _bContinue(bContinue), _iClauseReturnType(BNFClause::NO_RETURN_TYPE), _bNoCase(bNoCase) {} 45 ~BNFReadPythonString()46 BNFReadPythonString::~BNFReadPythonString() { 47 delete _pVariableToAssign; 48 } 49 accept(DtaVisitor & visitor,DtaVisitorEnvironment & env)50 void BNFReadPythonString::accept(DtaVisitor& visitor, DtaVisitorEnvironment& env) { 51 visitor.visitBNFReadPythonString(*this, env); 52 } 53 isABNFCommand() const54 bool BNFReadPythonString::isABNFCommand() const { return true; } 55 setVariableToAssign(ExprScriptVariable * pVariableToAssign,bool bConcat,BNFClause & theClause)56 void BNFReadPythonString::setVariableToAssign(ExprScriptVariable* pVariableToAssign, bool bConcat, BNFClause& theClause) { 57 if (pVariableToAssign != NULL) { 58 _pVariableToAssign = pVariableToAssign; 59 std::string sVariableName = _pVariableToAssign->toString(); 60 if (sVariableName == theClause.getName()) _iClauseReturnType = theClause.getReturnType(); 61 _bConcatVariable = bConcat; 62 } 63 } 64 executeInternal(DtaScriptVariable & visibility)65 SEQUENCE_INTERRUPTION_LIST BNFReadPythonString::executeInternal(DtaScriptVariable& visibility) { 66 bool bSuccess; 67 int iLocation = CGRuntime::getInputLocation(); 68 int iImplicitCopyPosition = _pBNFScript->skipEmptyChars(visibility); 69 int iNotEmptyLocation = CGRuntime::getInputLocation(); 70 std::string sValue; 71 bSuccess = CGRuntime::readPythonString(sValue); 72 if (!bSuccess) { 73 BNF_SYMBOL_HAS_FAILED 74 } 75 if (!_listOfConstants.empty()) { 76 bool bMatch = false; 77 for (std::vector<std::string>::const_iterator i = _listOfConstants.begin(); i != _listOfConstants.end(); i++) { 78 if (_bNoCase) bMatch = (stricmp(i->c_str(), sValue.c_str()) == 0); 79 else bMatch = (*i == sValue); 80 if (bMatch) break; 81 } 82 if (!bMatch) { 83 BNF_SYMBOL_HAS_FAILED 84 } 85 } 86 if (_pVariableToAssign != NULL) { 87 DtaScriptVariable* pVariable = visibility.getVariable(*_pVariableToAssign); 88 if (_iClauseReturnType == BNFClause::LIST_RETURN_TYPE) { 89 pVariable->pushItem(sValue); 90 } else { 91 if (_bConcatVariable) pVariable->concatValue(sValue.c_str()); 92 else pVariable->setValue(sValue.c_str()); 93 } 94 } 95 if (iImplicitCopyPosition >= 0) { 96 std::string sText = CGRuntime::getLastReadChars(CGRuntime::getInputLocation() - iNotEmptyLocation); 97 _pBNFScript->writeBinaryData(sText.c_str(), sText.size()); 98 } 99 return NO_INTERRUPTION; 100 } 101 compileCpp(CppCompilerEnvironment & theCompilerEnvironment) const102 void BNFReadPythonString::compileCpp(CppCompilerEnvironment& theCompilerEnvironment) const { 103 CW_BODY_INDENT << "// " << toString(); 104 CW_BODY_ENDL; 105 int iCursor = theCompilerEnvironment.newCursor(); 106 CW_BODY_INDENT << "int _compilerClauseLocation_" << iCursor << " = CGRuntime::getInputLocation();"; 107 CW_BODY_ENDL; 108 CW_BODY_INDENT << "int _compilerClauseImplicitCopy_" << iCursor << " = theEnvironment.skipEmptyChars();"; 109 CW_BODY_ENDL; 110 CW_BODY_INDENT << "std::string _compilerClauseText_" << iCursor << ";"; 111 CW_BODY_ENDL; 112 CW_BODY_INDENT << "_compilerClauseSuccess = CGRuntime::readPythonString(_compilerClauseText_" << iCursor << ");"; 113 CW_BODY_ENDL; 114 if (!_listOfConstants.empty()) { 115 CW_BODY_INDENT << "if (_compilerClauseSuccess) {"; 116 CW_BODY_ENDL; 117 CW_BODY_INDENT << "\t_compilerClauseSuccess = "; 118 for (std::vector<std::string>::const_iterator i = _listOfConstants.begin(); i != _listOfConstants.end(); i++) { 119 if (i != _listOfConstants.begin()) CW_BODY_STREAM << " || "; 120 CW_BODY_STREAM << "("; 121 if (_bNoCase) { 122 CW_BODY_STREAM << "stricmp(_compilerClauseText_" << iCursor << ".c_str(), "; 123 CW_BODY_STREAM.writeString(*i); 124 CW_BODY_STREAM << ") == 0"; 125 } else { 126 CW_BODY_STREAM << "_compilerClauseText_" << iCursor << " == "; 127 CW_BODY_STREAM.writeString(*i); 128 } 129 CW_BODY_STREAM << ")"; 130 } 131 CW_BODY_STREAM << ";"; 132 CW_BODY_ENDL; 133 CW_BODY_INDENT << "}"; 134 CW_BODY_ENDL; 135 } 136 if (_pVariableToAssign != NULL) { 137 CW_BODY_INDENT << "if (_compilerClauseSuccess) {";CW_BODY_ENDL; 138 theCompilerEnvironment.incrementIndentation(); 139 char tcText[32]; 140 sprintf(tcText, "_compilerClauseText_%d", iCursor); 141 _pBNFScript->compileCppBNFAssignment(theCompilerEnvironment, _iClauseReturnType, *_pVariableToAssign, _bConcatVariable, tcText); 142 theCompilerEnvironment.decrementIndentation(); 143 CW_BODY_INDENT << "}";CW_BODY_ENDL; 144 } 145 CW_BODY_INDENT << "if (!_compilerClauseSuccess) {"; 146 CW_BODY_ENDL; 147 if (_bContinue) { 148 CW_BODY_INDENT << "\tCGRuntime::throwBNFExecutionError("; 149 CW_BODY_STREAM.writeString(toString()); 150 CW_BODY_STREAM << ");"; 151 } else { 152 CW_BODY_INDENT << "\tCGRuntime::setInputLocation(_compilerClauseLocation_" << iCursor << ");"; 153 CW_BODY_ENDL; 154 CW_BODY_INDENT << "\tif (_compilerClauseImplicitCopy_" << iCursor << " >= 0) CGRuntime::resizeOutputStream(_compilerClauseImplicitCopy_" << iCursor << ");"; 155 } 156 CW_BODY_ENDL; 157 CW_BODY_INDENT << "} else if (_compilerClauseImplicitCopy_" << iCursor << " >= 0) CGRuntime::writeBinaryData(_compilerClauseText_" << iCursor << ".c_str(), _compilerClauseText_" << iCursor << ".size());"; 158 CW_BODY_ENDL; 159 } 160 toString() const161 std::string BNFReadPythonString::toString() const { 162 std::string sText = "#readPythonString" + DtaBNFScript::constantsToString(_listOfConstants) + DtaBNFScript::assignmentToString(_pVariableToAssign, _bConcatVariable); 163 if (_bContinue) sText = "#continue " + sText; 164 return sText; 165 } 166 } 167