bool Parser::isNegativeNumber(const char *cStr) { operator_s op0 = findOperator(cStr, 0); if (op0.op[0] == '-' && op0.pos == 0) { operator_s op1 = findOperator(cStr, op0.len); if (op1.len == 0) { return true; } } return false; }
char* Parser::regularExpression(char *expression) { trimBothParanthesis(expression); //If there is no operators return expression(end condition). operator_s op0 = findOperator(expression, 0); if (op0.pos == -1) { Alias_s a; //Is it a stack call? a = parseKeywords(expression); if (strlen(a.value) == 0) { memcpy(a.value, expression, a.len); } return a.value; } int len = strlen(expression); operator_s op1 = findOperator(expression, op0.pos + op0.len); if (op1.pos != -1) { //Negative number. if (op0.pos != -1 && op1.op[0] == '-' && op1.pos == op0.pos +1) { int len = strlen(expression); } else { //If there is a second operator set len = operator. len = op1.pos; } } memcpy(tmpLhs, expression, len); tmpLhs[len] = '\0'; int rhsLen = strlen(expression) - len; memcpy(tmpRhs, expression + len, rhsLen); tmpRhs[rhsLen] = '\0'; char *res = calculateResult(tmpLhs); len = strlen(res); memcpy(tmpStr, res, len); tmpStr[len] = '\0'; strcat(tmpStr, tmpRhs); tmpStr[len + strlen(tmpRhs)] = '\0'; //Negative number. if (isNegativeNumber(tmpStr)) { return tmpStr; } //recursion. regularExpression(tmpStr); return tmpStr; }
// ----------------------------------------------------------------------- bool TProcessor::processFile(const QString &Input_, const QString &Output_) { QFile InputFile(Input_); if(!InputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { std::cerr << "Can't open file: '" << (const char*)Input_.toLocal8Bit() << "'."; return false; } // QFile OutputFile(Output_); if(!OutputFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { std::cerr << "Can't open output file: '" << (const char*)Output_.toLocal8Bit() << "'."; return false; } // while(true) { TResult Result = findOperator(InputFile, OutputFile, true); if(Result == ResultSyntaxError) { // The error message was provided by the callee. return false; } else if(Result == ResultReadError) { std::cerr << "Can't read file: '" << (const char*)Input_.toLocal8Bit() << "'. Possible it is not in UTF-8 encoding."; return false; } else if(Result == ResultWriteError) { std::cerr << "Can't write data to file: '" << (const char*)Output_.toLocal8Bit() << "'."; return false; } else { assert(Result == ResultOK || Result == ResultEOF); return true; } } }
eIOperator * eDemoData::_loadOperator(eDemoScript &script, eU32 opTypeHashIdIndex) { eIOperator *op = SCRIPT_OP_CREATOR::createOp(opTypeHashIdIndex - ESCRIPT_CMDS_COUNT); op->m_id = global_ops.size()+1; global_ops.append(op); // load inputs while (eTRUE) { ESCRIPT_CMD_TYPE command; script >> command; if (command == ESCRIPT_CMD__INPUTS_DONE) { break; } else if (command == ESCRIPT_CMD__OP_DONE) { eU16 id; script >> id; eIOperator *inputOp = findOperator(id); eASSERT(inputOp != eNULL); op->m_inputOps.append(inputOp); inputOp->m_outputOps.append(op); } else {
// ----------------------------------------------------------------------- TProcessor::TResult TProcessor::findOperator(QFile &Input_, QFile &Output_, bool Enabled_) { QString Line; while(true) { TResult Result = nextLine(Input_, Line); if(Result != ResultOK) return Result; // Result = findRegExp(Line, m_OperatorStartRegExp, &m_OperatorEndRegExp); if(Result == ResultSyntaxError) { std::cerr << "Unexpected operator #" << (const char*)m_OperatorEndRegExp.cap(1).toLocal8Bit() << " in file '" << (const char*)QDir::toNativeSeparators(Input_.fileName()).toLocal8Bit() << "'."; return ResultSyntaxError; } else if(Result == ResultNoOperator && Enabled_) { QByteArray OutString = Line.toUtf8(); if(Output_.write(OutString) != OutString.size()) return ResultWriteError; } else { assert(Result == ResultOK); break; } } // QString Operator = m_OperatorStartRegExp.cap(1); QString Variable = m_OperatorStartRegExp.cap(2); // Check if we allow copying string from source to destination bool LocalEnabled = m_Variables.contains(Variable); if(Operator == QLatin1String("ifndef")) LocalEnabled = !LocalEnabled; // Searching for #else/#endif while(true) { TResult Result = nextLine(Input_, Line); if(Result == ResultReadError) return Result; else if(Result == ResultEOF) return ResultSyntaxError; // assert(Result == ResultOK); Result = findRegExp(Line, m_OperatorStartRegExp); if(Result == ResultOK) { Result = findOperator(Input_, Output_, Enabled_ && LocalEnabled); if(Result != ResultOK) return Result; } // Result = findRegExp(Line, m_OperatorEndRegExp); if(Result == ResultOK) { Operator = m_OperatorEndRegExp.cap(1); if(Operator == QLatin1String("endif")) return ResultOK; assert(Operator == QLatin1String("else")); break; } else if(Result == ResultNoOperator) { if(Enabled_ && LocalEnabled) { QByteArray OutString = Line.toUtf8(); if(Output_.write(OutString) != OutString.size()) return ResultWriteError; } } else { // Error return Result; } } // Looking for #endif while(true) { TResult Result = nextLine(Input_, Line); if(Result == ResultReadError) return Result; else if(Result == ResultEOF) return ResultSyntaxError; // assert(Result == ResultOK); Result = findRegExp(Line, m_OperatorStartRegExp); if(Result == ResultOK) { Result = findOperator(Input_, Output_, Enabled_ && !LocalEnabled); if(Result != ResultOK) return Result; } // Result = findRegExp(Line, m_OperatorEndRegExp); if(Result == ResultOK) { Operator = m_OperatorEndRegExp.cap(1); if(Operator == QLatin1String("endif")) return ResultOK; return ResultSyntaxError; } else if(Result == ResultNoOperator) { if(Enabled_ && !LocalEnabled) { QByteArray OutString = Line.toUtf8(); if(Output_.write(OutString) != OutString.size()) return ResultWriteError; } } else { // Error return Result; } } }
char* Parser::calculateResult(char *exp) { tmpStr[0] = '\0'; //reseting... operator_s op0 = findOperator(exp, 0); char lhs[INSTRUCTIONSIZE]; char rhs[INSTRUCTIONSIZE]; memcpy(lhs, exp, op0.pos); lhs[op0.pos] = '\0'; int rhsLen = strlen(exp) - op0.pos; memcpy(rhs, exp + op0.pos + op0.len, rhsLen); rhs[rhsLen] = '\0'; Alias_s aliasLhs = parseKeywords(lhs); Alias_s aliasRhs = parseKeywords(rhs); if (strCmp(aliasLhs.value, "")) { //alias need to be set to an default value, DO CRASH!!! } else if (strCmp(aliasRhs.value, "")) { //alias need to be set to an default value, DO CRASH!!! } //do calculation //Both are digits if (strCmp(aliasLhs.type, "int") && strCmp(aliasRhs.type, "int")) { if (strCmp(op0.op, "+")) { sprintf(tmpStr, "%d", atoi(aliasLhs.value) + atoi(aliasRhs.value)); } else if (strCmp(op0.op, "-")) { sprintf(tmpStr, "%d", atoi(aliasLhs.value) - atoi(aliasRhs.value)); } else if (strCmp(op0.op, "*")) { sprintf(tmpStr, "%d", atoi(aliasLhs.value) * atoi(aliasRhs.value)); } else if (strCmp(op0.op, "/")) { sprintf(tmpStr, "%d", atoi(aliasLhs.value) / atoi(aliasRhs.value)); int v = atoi(tmpStr); if (v < 0) { tmpStr[0] = '0'; tmpStr[1] = '\0'; } } else if (strCmp(op0.op, "==")) { if (strCmp(aliasLhs.value, aliasRhs.value)) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, "!=")) { if (strCmp(aliasLhs.value, aliasRhs.value)) { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } else { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } } else if (strCmp(op0.op, "<")) { int l = atoi(aliasLhs.value); int r = atoi(aliasRhs.value); if (l < r) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, ">")) { int l = atoi(aliasLhs.value); int r = atoi(aliasRhs.value); if (l < r) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, "=")) { memcpy(&aliasLhs.value, &aliasRhs.value, aliasRhs.len); aliasLhs.value[aliasRhs.len] = '\0'; aliasLhs.len = aliasRhs.len; int a = heap.getAddress(aliasLhs.name); heap.insertAliasAt(a, aliasLhs); } else { //Wrong syntax do CRASH!!! } } //Both are text strings. else if (strCmp(aliasLhs.type, "string") && strCmp(aliasRhs.type, "string")) { if (strCmp(op0.op, "+")) { return strcat(aliasLhs.value, aliasRhs.value); } else if (strCmp(op0.op, "-")) { //Wrong syntax do CRASH!!! } else if (strCmp(op0.op, "*")) { //Wrong syntax do CRASH!!! } else if (strCmp(op0.op, "/")) { //Wrong syntax do CRASH!!! } else if (strCmp(op0.op, "==")) { if (strCmp(aliasLhs.value, aliasRhs.value)) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, "!=")) { if (strCmp(aliasLhs.value, aliasRhs.value)) { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } else { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } } else if (strCmp(op0.op, "<")) { if (aliasLhs.len < aliasRhs.len) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, ">")) { if (aliasLhs.len > aliasRhs.len) { memcpy(tmpStr, "true", 4); tmpStr[4] = '\0'; } else { memcpy(tmpStr, "false", 5); tmpStr[5] = '\0'; } } else if (strCmp(op0.op, "=")) { memcpy(aliasLhs.value, aliasRhs.value, strlen(aliasLhs.value)); aliasLhs.len == aliasRhs.len; int a = heap.getAddress(aliasLhs.name); heap.insertAliasAt(a, aliasLhs); } else { //Wrong syntax do CRASH! } } else { //Cannot compare digits and strings. } return tmpStr; }
eBool eDemoData::existsOperator(eID opId) { return (findOperator(opId) != eNULL); }
void eDemoData::_storeOperator(eDemoScript &script, const eIOperator *op, eID &idCounter, eArray<const eIOperator*>& ops) { eASSERT(idCounter != eNOID); eASSERT(op->getType() != "Misc : Nop"); eASSERT(op->getType() != "Misc : Load"); eASSERT(op->getType() != "Misc : Store"); opIdHm[op] = idCounter; opStoredHm[op] = eTRUE; eU32 statIdx = opTypeHashIDs.exists(eOpFactory::get().toHashID(op->getType())); stats[statIdx].cnt++; ops.append(op); // inputs for (eU32 i=0; i<op->getInputCount(); i++) { const eIOperator *inputOp = opEquivalentOp[_resolveOperator(op->getInputOperator(i))]; if (opStoredHm.exists(inputOp)) { script << (ESCRIPT_CMD_TYPE)ESCRIPT_CMD__OP_DONE; eASSERT(opIdHm.exists(inputOp) == eTRUE); eID id = opIdHm[inputOp]; script << (eU16)id; stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE) + sizeof(eU16); } else { eU32 opTypeHashID = eOpFactory::get().toHashID(inputOp->getType()); script << (ESCRIPT_CMD_TYPE)(opTypeHashIDs.exists(opTypeHashID) + ESCRIPT_CMDS_COUNT); _storeOperator(script, inputOp, ++idCounter, ops); stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE); } } script << (ESCRIPT_CMD_TYPE)ESCRIPT_CMD__INPUTS_DONE; stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE); // linked ops for (eU32 i=0; i<op->getParameterCount(); i++) { if (op->getParameter(i).getType() == eParameter::TYPE_LINK) { const eIOperator *linkOpRaw = findOperator(op->getParameter(i).getValue().linkedOpId); if (linkOpRaw) { const eIOperator *linkOp = opEquivalentOp[_resolveOperator(linkOpRaw)]; eASSERT(linkOp != eNULL); if (opStoredHm.exists(linkOp)) { eASSERT(opIdHm.exists(linkOp) == eTRUE); script << (ESCRIPT_CMD_TYPE)ESCRIPT_CMD__OP_DONE; eID id = opIdHm[linkOp]; script << (eU16)id; stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE) + sizeof(eU16); } else { eU32 opTypeHashID = eOpFactory::get().toHashID(linkOp->getType()); script << (ESCRIPT_CMD_TYPE)(opTypeHashIDs.exists(opTypeHashID) + ESCRIPT_CMDS_COUNT); _storeOperator(script, linkOp, ++idCounter, ops); stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE); } } else { script << (ESCRIPT_CMD_TYPE)ESCRIPT_CMD__OP_NOEXISTS; stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE); } } } // animated params eU32 paramNr = 0; for (eU32 i=0; i<op->getParameterCount(); i++) { if(op->getParameter(i).getType() == eParameter::TYPE_LABEL) continue; if (op->getParameter(i).getType() != eParameter::TYPE_LINK) { if (op->getParameter(i).isAnimated()) { const eIOperator *animOp = findOperator(op->getParameter(i).getAnimationPathOpId()); if (animOp) { script << (eU8)(paramNr+1); animOp = opEquivalentOp[_resolveOperator(animOp)]; if (opStoredHm.exists(animOp)) { eASSERT(opIdHm.exists(animOp) == eTRUE); script << (ESCRIPT_CMD_TYPE)ESCRIPT_CMD__OP_DONE; eID id = opIdHm[animOp]; script << (eU16)id; stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE) + sizeof(eU16); } else { eU32 opTypeHashID = eOpFactory::get().toHashID(animOp->getType()); script << (ESCRIPT_CMD_TYPE)(opTypeHashIDs.exists(opTypeHashID) + ESCRIPT_CMDS_COUNT); _storeOperator(script, animOp, ++idCounter, ops); stats[statIdx].accsize += sizeof(ESCRIPT_CMD_TYPE); } } } } paramNr++; } script << (eU8)0; // end flag for animated parameters loading stats[statIdx].accsize += sizeof(eU8); }
void eDemoData::_preprocessOpTree(const eIOperator *op) { // check if this op has already been processed if(opEquivalentOp.exists(op)) return; // create op type id if necessary eU32 opTypeHashID = eOpFactory::get().toHashID(op->getType()); if(-1 == opTypeHashIDs.exists(opTypeHashID)) { tStatRecord s; s.name = &op->getType(); s.cnt = 0; s.accsize = 0; opClassNames.append(&op->getMetaInfos().classNameString); opClassFiles.append(&op->getMetaInfos().sourceFileName); stats.append(s); opTypeHashIDs.append(opTypeHashID); } // try to find an equivalent op for inputs and params for (eU32 i=0; i<op->getInputCount(); i++) { const eIOperator *inputOp = _resolveOperator(op->getInputOperator(i)); _preprocessOpTree(inputOp); } for (eU32 i=0; i<op->getParameterCount(); i++) { const eParameter& param = op->getParameter(i); if(param.getType() == eParameter::TYPE_LINK) { const eIOperator *linkOp = _resolveOperator(findOperator(param.getValue().linkedOpId)); if(linkOp) _preprocessOpTree(linkOp); } if(param.isAnimated()) { const eIOperator *linkOp = _resolveOperator(findOperator(param.m_animPathOpId)); if(linkOp) _preprocessOpTree(linkOp); } } // try to find an equivalent op for this op const eIOperator *eqOp = op; for(eU32 o = 0; o < opUniqueOps.getCount(); o++) { const eIOperator *testOp = opUniqueOps.getAt(o); // ensure type and common cardinalities are identical if((eStrCompare(op->getType(), testOp->getType()) != 0) || (op->getParameterCount() != testOp->getParameterCount()) || (op->getInputCount() != testOp->getInputCount())) continue; bool notEqual = false; // compare inputs for (eU32 i=0; i<op->getInputCount(); i++) { const eIOperator *inputOp1 = _resolveOperator(op->getInputOperator(i)); const eIOperator *inputOp2 = _resolveOperator(testOp->getInputOperator(i)); if(opEquivalentOp[inputOp1] != opEquivalentOp[inputOp2]) { notEqual = true; break; } } if(notEqual) continue; // compare parameters for (eU32 i=0; i<op->getParameterCount(); i++) { const eParameter& param1 = op->getParameter(i); const eParameter& param2 = testOp->getParameter(i); if((param1.getType() != param2.getType()) || (param1.isAnimated() != param2.isAnimated())) { notEqual = true; break; } if(param1.getType() == eParameter::TYPE_LINK) { const eIOperator *linkOp1 = _resolveOperator(findOperator(param1.getValue().linkedOpId)); const eIOperator *linkOp2 = _resolveOperator(findOperator(param2.getValue().linkedOpId)); if(opEquivalentOp[linkOp1] != opEquivalentOp[linkOp2]) { notEqual = true; break; } } else { // check raw params if(param1.isAnimated()) { const eIOperator *linkOp1 = _resolveOperator(findOperator(param1.m_animPathOpId)); const eIOperator *linkOp2 = _resolveOperator(findOperator(param2.m_animPathOpId)); if( (param1.getAnimationChannel() != param2.getAnimationChannel()) || (param1.getAnimationTimeOffset() != param2.getAnimationTimeOffset()) || (param1.getAnimationTimeScale() != param2.getAnimationTimeScale()) || (opEquivalentOp[linkOp1] != opEquivalentOp[linkOp2])) { notEqual = true; break; } } else { // plain value parameter if(param1.isTextType()) { if(eStrCompare(param1.m_value.string, param2.m_value.string) != 0) { notEqual = true; break; } } else { if(!eMemEqual(¶m1.m_value, ¶m2.m_value, eParameter::M_RELEVANT_PARAMETER_LENGTH[param1.m_type])) { notEqual = true; break; } } // check bytecode if((param1.m_value.byteCode.size() != param2.m_value.byteCode.size()) || ((param1.m_value.byteCode.size() != 0) && (!eMemEqual(param1.m_value.byteCode.m_data, param2.m_value.byteCode.m_data, param1.m_value.byteCode.size())))) { notEqual = true; break; } } } } #ifdef USE_EQUIVALENT_OP_SEARCH if(notEqual) #endif continue; // all parameters are equal eASSERT(eqOp == op); eqOp = testOp; } if(eqOp == op) { // operator is unique opUniqueOps.insert(op, op); }; opEquivalentOp.insert(op, eqOp); }