char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { if( !isNumeric( *in ) && !isCharacter( *in ) ) { ++in; } in = lookForNextToken( in, end ); Value::ValueType type( Value::ddl_none ); size_t arrayLen( 0 ); in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); if( Value::ddl_none != type ) { // parse a primitive data type in = lookForNextToken( in, end ); if( *in == Grammar::OpenBracketToken[ 0 ] ) { Reference *refs( ddl_nullptr ); DataArrayList *dtArrayList( ddl_nullptr ); Value *values( ddl_nullptr ); if( 1 == arrayLen ) { size_t numRefs( 0 ), numValues( 0 ); in = parseDataList( in, end, type, &values, numValues, &refs, numRefs ); setNodeValues( top(), values ); setNodeReferences( top(), refs ); } else if( arrayLen > 1 ) { in = parseDataArrayList( in, end, type, &dtArrayList ); setNodeDataArrayList( top(), dtArrayList ); } else { std::cerr << "0 for array is invalid." << std::endl; error = true; } } in = lookForNextToken( in, end ); if( *in != '}' ) { logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback ); return ddl_nullptr; } else { //in++; } } else { // parse a complex data type in = parseNextNode( in, end ); } return in; }
char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataArrayList ) { if ( ddl_nullptr == dataArrayList ) { return in; } *dataArrayList = ddl_nullptr; if( ddl_nullptr == in || in == end ) { return in; } in = lookForNextToken( in, end ); if( *in == Grammar::OpenBracketToken[ 0 ] ) { ++in; Value *currentValue( ddl_nullptr ); Reference *refs( ddl_nullptr ); DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); do { size_t numRefs( 0 ), numValues( 0 ); currentValue = ddl_nullptr; in = parseDataList( in, end, type, ¤tValue, numValues, &refs, numRefs ); if( ddl_nullptr != currentValue || 0 != numRefs ) { if( ddl_nullptr == prev ) { *dataArrayList = createDataArrayList( currentValue, numValues, refs, numRefs ); prev = *dataArrayList; } else { currentDataList = createDataArrayList( currentValue, numValues, refs, numRefs ); if( ddl_nullptr != prev ) { prev->m_next = currentDataList; prev = currentDataList; } } } } while( Grammar::CommaSeparator[ 0 ] == *in && in != end ); in = lookForNextToken( in, end ); ++in; } return in; }
bool Calculator::execute(const char *formula, const char *formula_end, double &result) { double value; #if CAVAN_MATH_DEBUG println("formula = %s", text_header(formula, formula_end - formula)); #endif mStackOperand.clear(); mStackOperator.clear(); mLastFieldType = FIELD_TYPE_NONE; while (formula < formula_end) { Operator *op = matchOperator(formula); if (op) { Operator *top; if (mStackOperator.top(top)) { if (top->getPriority() <= op->getPriority()) { if (!top->execute(mStackOperand)) { setErrMsg(top->getErrMsg()); return false; } mStackOperator.pop(top); } } if (op->getOmitMul() && mLastFieldType == FIELD_TYPE_VALUE && mStackOperand.hasData()) { Operator *mul = matchOperator("*"); if (mul) { mStackOperator.push(mul); } } switch (op->getType()) { case OPERATOR_TYPE2: case OPERATOR_TYPE1_RIGHT: if (!mStackOperator.push(op)) { setErrMsg("Operator stack overfrow"); return false; } formula += op->getLength(); break; case OPERATOR_TYPE1_LEFT: case OPERATOR_TYPE_CONSTANT: if (!op->execute(mStackOperand)) { setErrMsg(op->getErrMsg()); return false; } formula += op->getLength(); break; case OPERATOR_TYPE_LIST: { Stack<double> stack(200); if (!parseDataList(formula + op->getLength(), formula_end, &formula, stack)) { return false; } if (!op->execute(stack, mStackOperand)) { setErrMsg(op->getErrMsg()); return false; } break; } default: setErrMsg("Invalid operator"); return false; } mLastFieldType = FIELD_TYPE_OPERATOR; } else { switch (*formula) { case ' ': case '\r': case '\n': case '\t': case '\f': formula++; break; case '0' ... '9': value = text2double_unsigned(formula, formula_end, &formula, 10); if (mLastFieldType == FIELD_TYPE_OPERATOR && mStackOperator.count() == 1 && mStackOperand.isEmpty()) { Operator *op; if (mStackOperator.top(op) && strcmp(op->getSymbol(), "-") == 0) { value = -value; mStackOperator.pop(op); } } if (!mStackOperand.push(value)) { setErrMsg("Operand stack overfrow"); return false; } mLastFieldType = FIELD_TYPE_VALUE; break; case '(': case '[': case '{': { const char *p = get_bracket_pair(formula, formula_end); if (p == NULL) { setErrMsg("No matching brackets"); return false; } Calculator calculator; if (!calculator.execute(formula + 1, p, value)) { setErrMsg(calculator.getErrMsg()); return false; } if (!mStackOperand.push(value)) { setErrMsg("Operand stack overfrow"); return false; } formula = p + 1; mLastFieldType = FIELD_TYPE_BRACKET; break; } default: setErrMsg("Invalid symbol"); return false; } } } while (1) { Operator *op; if (!mStackOperator.pop(op)) { break; } if (!op->execute(mStackOperand)) { setErrMsg(op->getErrMsg()); return false; } } if (!mStackOperand.pop(result)) { setErrMsg("Missing operand"); return false; } if (mStackOperand.hasData()) { setErrMsg("Too much operand"); return false; } return true; }