Пример #1
0
int
_gmx_sel_lexer_process_pending(YYSTYPE *yylval, YYLTYPE *yylloc,
                               gmx_sel_lexer_t *state)
{
    if (state->nextparam)
    {
        gmx_ana_selparam_t *param   = state->nextparam;
        bool                bBoolNo = state->bBoolNo;

        if (state->neom > 0)
        {
            --state->neom;
            _gmx_sel_lexer_add_token(yylloc, nullptr, 0, state);
            return END_OF_METHOD;
        }
        state->nextparam = nullptr;
        state->bBoolNo   = false;
        _gmx_sel_lexer_add_token(yylloc, param->name, -1, state);
        return init_param_token(yylval, param, bBoolNo);
    }
    if (state->prev_pos_kw > 0)
    {
        --state->prev_pos_kw;
    }
    if (state->nextMethodSymbol)
    {
        const gmx::SelectionParserSymbol *symbol = state->nextMethodSymbol;
        state->nextMethodSymbol = nullptr;
        return init_method_token(yylval, yylloc, symbol, true, state);
    }
    return 0;
}
Пример #2
0
int
_gmx_sel_lexer_process_pending(YYSTYPE *yylval, gmx_sel_lexer_t *state)
{
    if (state->nextparam)
    {
        gmx_ana_selparam_t *param   = state->nextparam;
        bool                bBoolNo = state->bBoolNo;

        if (state->neom > 0)
        {
            --state->neom;
            return END_OF_METHOD;
        }
        state->nextparam = NULL;
        state->bBoolNo   = false;
        _gmx_sel_lexer_add_token(param->name, -1, state);
        return init_param_token(yylval, param, bBoolNo);
    }
    if (state->prev_pos_kw > 0)
    {
        --state->prev_pos_kw;
    }
    if (state->nextmethod)
    {
        gmx_ana_selmethod_t *method = state->nextmethod;

        state->nextmethod = NULL;
        return init_method_token(yylval, method, true, state);
    }
    return 0;
}
Пример #3
0
int
_gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc,
                                  char *yytext, size_t yyleng,
                                  gmx_sel_lexer_t *state)
{
    /* Check if the identifier matches with a parameter name */
    if (state->msp >= 0)
    {
        gmx_ana_selparam_t *param   = nullptr;
        bool                bBoolNo = false;
        int                 sp      = state->msp;
        while (!param && sp >= 0)
        {
            int             i;
            for (i = 0; i < state->mstack[sp]->nparams; ++i)
            {
                /* Skip NULL parameters and too long parameters */
                if (state->mstack[sp]->param[i].name == nullptr
                    || strlen(state->mstack[sp]->param[i].name) > yyleng)
                {
                    continue;
                }
                if (!strncmp(state->mstack[sp]->param[i].name, yytext, yyleng))
                {
                    param = &state->mstack[sp]->param[i];
                    break;
                }
                /* Check separately for a 'no' prefix on boolean parameters */
                if (state->mstack[sp]->param[i].val.type == NO_VALUE
                    && yyleng > 2 && yytext[0] == 'n' && yytext[1] == 'o'
                    && !strncmp(state->mstack[sp]->param[i].name, yytext+2, yyleng-2))
                {
                    param   = &state->mstack[sp]->param[i];
                    bBoolNo = true;
                    break;
                }
            }
            if (!param)
            {
                --sp;
            }
        }
        if (param)
        {
            if (param->val.type == NO_VALUE && !bBoolNo)
            {
                state->bMatchBool = true;
            }
            if (sp < state->msp)
            {
                state->neom      = state->msp - sp - 1;
                state->nextparam = param;
                state->bBoolNo   = bBoolNo;
                return END_OF_METHOD;
            }
            _gmx_sel_lexer_add_token(yylloc, param->name, -1, state);
            return init_param_token(yylval, param, bBoolNo);
        }
    }

    /* Check if the identifier matches with a symbol */
    const gmx::SelectionParserSymbol *symbol
        = state->sc->symtab->findSymbol(std::string(yytext, yyleng));
    /* If there is no match, return the token as a string */
    if (!symbol)
    {
        yylval->str = gmx_strndup(yytext, yyleng);
        _gmx_sel_lexer_add_token(yylloc, yytext, yyleng, state);
        return IDENTIFIER;
    }
    gmx::SelectionParserSymbol::SymbolType symtype = symbol->type();
    /* For method symbols, we need some extra processing. */
    if (symtype == gmx::SelectionParserSymbol::MethodSymbol)
    {
        return init_method_token(yylval, yylloc, symbol, state->prev_pos_kw > 0, state);
    }
    _gmx_sel_lexer_add_token(yylloc, symbol->name().c_str(), -1, state);
    /* Reserved symbols should have been caught earlier */
    if (symtype == gmx::SelectionParserSymbol::ReservedSymbol)
    {
        GMX_THROW(gmx::InternalError(gmx::formatString(
                                             "Mismatch between tokenizer and reserved symbol table (for '%s')",
                                             symbol->name().c_str())));
    }
    /* For variable symbols, return the type of the variable value */
    if (symtype == gmx::SelectionParserSymbol::VariableSymbol)
    {
        const gmx::SelectionTreeElementPointer &var = symbol->variableValue();
        /* Return simple tokens for constant variables */
        if (var->type == SEL_CONST)
        {
            switch (var->v.type)
            {
                case INT_VALUE:
                    yylval->i = var->v.u.i[0];
                    return TOK_INT;
                case REAL_VALUE:
                    yylval->r = var->v.u.r[0];
                    return TOK_REAL;
                case POS_VALUE:
                    break;
                default:
                    GMX_THROW(gmx::InternalError("Unsupported variable type"));
            }
        }
        yylval->sel = new gmx::SelectionTreeElementPointer(var);
        switch (var->v.type)
        {
            case INT_VALUE:   return VARIABLE_NUMERIC;
            case REAL_VALUE:  return VARIABLE_NUMERIC;
            case POS_VALUE:   return VARIABLE_POS;
            case GROUP_VALUE: return VARIABLE_GROUP;
            default:
                delete yylval->sel;
                GMX_THROW(gmx::InternalError("Unsupported variable type"));
        }
        /* This position should not be reached. */
    }
    /* For position symbols, we need to return KEYWORD_POS, but we also need
     * some additional handling. */
    if (symtype == gmx::SelectionParserSymbol::PositionSymbol)
    {
        state->bMatchOf    = true;
        yylval->str        = gmx_strdup(symbol->name().c_str());
        state->prev_pos_kw = 2;
        return KEYWORD_POS;
    }
    /* Should not be reached */
    return INVALID;
}