示例#1
0
static const char* ODSGetOperatorName( ods_formula_op eOp )
{
    switch (eOp)
    {
        case ODS_OR : return "OR";
        case ODS_AND : return "AND";
        case ODS_NOT : return "NOT";
        case ODS_IF : return "IF";

        case ODS_PI : return "PI";

        //case ODS_T : return "T";
        case ODS_LEN : return "LEN";
        case ODS_LEFT : return "LEFT";
        case ODS_RIGHT : return "RIGHT";
        case ODS_MID : return "MID";

        case ODS_SUM : return "SUM";
        case ODS_AVERAGE : return "AVERAGE";
        case ODS_MIN : return "MIN";
        case ODS_MAX : return "MAX";
        case ODS_COUNT : return "COUNT";
        case ODS_COUNTA : return "COUNTA";

        case ODS_EQ : return "=";
        case ODS_NE : return "<>";
        case ODS_GE : return ">=";
        case ODS_LE : return "<=";
        case ODS_LT : return "<";
        case ODS_GT : return ">";

        case ODS_ADD : return "+";
        case ODS_SUBTRACT : return "-";
        case ODS_MULTIPLY : return "*";
        case ODS_DIVIDE : return "/";
        case ODS_MODULUS : return "MOD";
        case ODS_CONCAT : return "&";

        case ODS_LIST : return "*list*";
        case ODS_CELL : return "*cell*";
        case ODS_CELL_RANGE : return "*cell_range*";
        default:
        {
            const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
            if (psSingleOp != NULL)
                return psSingleOp->pszName;
            return "*unknown*";
        }
    }
}
示例#2
0
int ods_formula_node::EvaluateSingleArgOp(IODSCellEvaluator* poEvaluator)
{
    CPLAssert( eNodeType == SNT_OPERATION );

    const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
    CPLAssert(psSingleOp);

    CPLAssert(nSubExprCount == 1);
    if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
        return FALSE;

    CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
    double dfVal = 0;

    if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
    {
        dfVal = psSingleOp->pfnEval(papoSubExpr[0]->int_value);
    }
    else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
    {
        dfVal = psSingleOp->pfnEval(papoSubExpr[0]->float_value);
    }
    else
    {
        CPLError(CE_Failure, CPLE_NotSupported, "Bad argument type for %s",
                 psSingleOp->pszName);
        return FALSE;
    }

    eNodeType = SNT_CONSTANT;
    field_type = ODS_FIELD_TYPE_FLOAT;
    float_value = dfVal;

    FreeSubExpr();

    return TRUE;
}
示例#3
0
int ods_formulalex( YYSTYPE *ppNode, ods_formula_parse_context *context )
{
    const char *pszInput = context->pszNext;

    *ppNode = NULL;

/* -------------------------------------------------------------------- */
/*      Do we have a start symbol to return?                            */
/* -------------------------------------------------------------------- */
    if( context->nStartToken != 0 )
    {
        int nRet = context->nStartToken;
        context->nStartToken = 0;
        return nRet;
    }

/* -------------------------------------------------------------------- */
/*      Skip white space.                                               */
/* -------------------------------------------------------------------- */
    while( *pszInput == ' ' || *pszInput == '\t'
           || *pszInput == 10 || *pszInput == 13 )
        pszInput++;

    if( *pszInput == '\0' )
    {
        context->pszNext = pszInput;
        return EOF; 
    }

/* -------------------------------------------------------------------- */
/*      Handle string constants.                                        */
/* -------------------------------------------------------------------- */
    if( *pszInput == '"' )
    {
        char *token;
        int i_token;

        pszInput++;

        token = (char *) CPLMalloc(strlen(pszInput)+1);
        i_token = 0;

        while( *pszInput != '\0' )
        {
            if( *pszInput == '\\' && pszInput[1] == '"' )
                pszInput++;
            else if( *pszInput == '\\' && pszInput[1] == '\'' )
                pszInput++;
            else if( *pszInput == '\'' && pszInput[1] == '\'' )
                pszInput++;
            else if( *pszInput == '"' )
            {
                pszInput++;
                break;
            }
            else if( *pszInput == '\'' )
            {
                pszInput++;
                break;
            }
            
            token[i_token++] = *(pszInput++);
        }
        token[i_token] = '\0';

        *ppNode = new ods_formula_node( token );
        CPLFree( token );

        context->pszNext = pszInput;

        return ODST_STRING;
    }

/* -------------------------------------------------------------------- */
/*      Handle numbers.                                                 */
/* -------------------------------------------------------------------- */
    else if( *pszInput >= '0' && *pszInput <= '9' )
    {
        CPLString osToken;
        const char *pszNext = pszInput + 1;

        osToken += *pszInput;

        // collect non-decimal part of number
        while( *pszNext >= '0' && *pszNext <= '9' )
            osToken += *(pszNext++);

        // collect decimal places.
        if( *pszNext == '.' )
        {
            osToken += *(pszNext++);
            while( *pszNext >= '0' && *pszNext <= '9' )
                osToken += *(pszNext++);
        }

        // collect exponent
        if( *pszNext == 'e' || *pszNext == 'E' )
        {
            osToken += *(pszNext++);
            if( *pszNext == '-' || *pszNext == '+' )
                osToken += *(pszNext++);
            while( *pszNext >= '0' && *pszNext <= '9' )
                osToken += *(pszNext++);
        }

        context->pszNext = pszNext;

        if( strstr(osToken,".") 
            || strstr(osToken,"e") 
            || strstr(osToken,"E") )
        {
            *ppNode = new ods_formula_node( CPLAtof(osToken) );
        }
        else
        {
            *ppNode = new ods_formula_node( atoi(osToken) );
        }

        return ODST_NUMBER;
    }

/* -------------------------------------------------------------------- */
/*      Handle alpha-numerics.                                          */
/* -------------------------------------------------------------------- */
    else if( *pszInput == '.' || isalnum( *pszInput ) )
    {
        int nReturn = ODST_IDENTIFIER;
        CPLString osToken;
        const char *pszNext = pszInput + 1;

        osToken += *pszInput;

        // collect text characters
        while( isalnum( *pszNext ) || *pszNext == '_' 
               || ((unsigned char) *pszNext) > 127 )
            osToken += *(pszNext++);

        context->pszNext = pszNext;

        /* Constants */
        if( EQUAL(osToken,"TRUE") )
        {
            *ppNode = new ods_formula_node( 1 );
            return ODST_NUMBER;
        }
        else if( EQUAL(osToken,"FALSE") )
        {
            *ppNode = new ods_formula_node( 0 );
            return ODST_NUMBER;
        }

        else if( EQUAL(osToken,"NOT") )
            nReturn = ODST_NOT;
        else if( EQUAL(osToken,"AND") )
            nReturn = ODST_AND;
        else if( EQUAL(osToken,"OR") )
            nReturn = ODST_OR;
        else if( EQUAL(osToken,"IF") )
            nReturn = ODST_IF;

        /* No-arg functions */
        else if( EQUAL(osToken,"PI") )
        {
            *ppNode = new ods_formula_node( ODS_PI );
            return ODST_FUNCTION_NO_ARG;
        }

        /* Single-arg functions */
        else if( EQUAL(osToken,"LEN") )
        {
            *ppNode = new ods_formula_node( ODS_LEN );
            return ODST_FUNCTION_SINGLE_ARG;
        }
        /*
        else if( EQUAL(osToken,"T") )
        {
            *ppNode = new ods_formula_node( ODS_T );
            return ODST_FUNCTION_SINGLE_ARG;
        }*/
        
        /* Tow-arg functions */
        else if( EQUAL(osToken,"MOD") )
        {
            *ppNode = new ods_formula_node( ODS_MODULUS );
            return ODST_FUNCTION_TWO_ARG;
        }
        else if( EQUAL(osToken,"LEFT") )
        {
            *ppNode = new ods_formula_node( ODS_LEFT );
            return ODST_FUNCTION_TWO_ARG;
        }
        else if( EQUAL(osToken,"RIGHT") )
        {
            *ppNode = new ods_formula_node( ODS_RIGHT );
            return ODST_FUNCTION_TWO_ARG;
        }

        /* Three-arg functions */
        else if( EQUAL(osToken,"MID") )
        {
            *ppNode = new ods_formula_node( ODS_MID );
            return ODST_FUNCTION_THREE_ARG;
        }

        /* Multiple-arg functions */
        else if( EQUAL(osToken,"SUM") )
        {
            *ppNode = new ods_formula_node( ODS_SUM );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }
        else if( EQUAL(osToken,"AVERAGE") )
        {
            *ppNode = new ods_formula_node( ODS_AVERAGE );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }
        else if( EQUAL(osToken,"MIN") )
        {
            *ppNode = new ods_formula_node( ODS_MIN );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }
        else if( EQUAL(osToken,"MAX") )
        {
            *ppNode = new ods_formula_node( ODS_MAX );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }
        else if( EQUAL(osToken,"COUNT") )
        {
            *ppNode = new ods_formula_node( ODS_COUNT );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }
        else if( EQUAL(osToken,"COUNTA") )
        {
            *ppNode = new ods_formula_node( ODS_COUNTA );
            nReturn = ODST_FUNCTION_ARG_LIST;
        }

        else
        {
            const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(osToken);
            if (psSingleOp != NULL)
            {
                *ppNode = new ods_formula_node( psSingleOp->eOp );
                nReturn = ODST_FUNCTION_SINGLE_ARG;
            }
            else
            {
                *ppNode = new ods_formula_node( osToken );
                nReturn = ODST_IDENTIFIER;
            }
        }

        return nReturn;
    }

/* -------------------------------------------------------------------- */
/*      Handle special tokens.                                          */
/* -------------------------------------------------------------------- */
    else
    {
        context->pszNext = pszInput+1;
        return *pszInput;
    }
}