Jan Breuer
2015-09-10 e428a288113dc87ceac66393227e25e060f62279
Add Numeric list parsing
6个文件已修改
135 ■■■■■ 已修改文件
libscpi/inc/scpi/error.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/expression.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/types.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/expression.c 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/lexer.c 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/lexer_private.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/error.h
@@ -92,7 +92,7 @@
    XE(SCPI_ERROR_BLOCK_DATA_ERROR,             -160, "Block data error")                             \
    XE(SCPI_ERROR_INVALID_BLOCK_DATA,           -161, "Invalid block data")                           \
    XE(SCPI_ERROR_BLOCK_DATA_NOT_ALLOWED,       -168, "Block data not allowed")                       \
    XE(SCPI_ERROR_EXPRESSION_PARSING_ERROR,     -170, "Expression error")                             \
    X(SCPI_ERROR_EXPRESSION_PARSING_ERROR,      -170, "Expression error")                             \
    XE(SCPI_ERROR_INVAL_EXPRESSION,             -171, "Invalid expression")                           \
    XE(SCPI_ERROR_EXPRESSION_DATA_NOT_ALLOWED,  -178, "Expression data not allowed")                  \
    XE(SCPI_ERROR_MACRO_DEFINITION_ERROR,       -180, "Macro error")                                  \
libscpi/inc/scpi/expression.h
@@ -42,6 +42,17 @@
extern "C" {
#endif
    
    enum _scpi_expr_result_t {
        SCPI_EXPR_OK = 0,
        SCPI_EXPR_ERROR,
        SCPI_EXPR_NO_MORE,
    };
    typedef enum _scpi_expr_result_t scpi_expr_result_t;
    scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo);
    scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo);
    scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo);
#ifdef __cplusplus
}
#endif
libscpi/inc/scpi/types.h
@@ -141,6 +141,7 @@
    enum _scpi_token_type_t {
        SCPI_TOKEN_COMMA,
        SCPI_TOKEN_SEMICOLON,
        SCPI_TOKEN_COLON,
        SCPI_TOKEN_QUESTION,
        SCPI_TOKEN_NL,
        SCPI_TOKEN_HEXNUM,
libscpi/src/expression.c
@@ -34,4 +34,101 @@
 */
#include "scpi/expression.h"
#include "scpi/error.h"
#include "scpi/parser.h"
#include "lexer_private.h"
static scpi_expr_result_t numericRange(lex_state_t * state, scpi_bool_t * isRange, scpi_token_t * valueFrom, scpi_token_t * valueTo)
{
    if (scpiLex_DecimalNumericProgramData(state, valueFrom)) {
        if (scpiLex_Colon(state, valueTo)) {
            *isRange = TRUE;
            if (scpiLex_DecimalNumericProgramData(state, valueTo)) {
                return SCPI_EXPR_OK;
            } else {
                return SCPI_EXPR_ERROR;
            }
        } else {
            *isRange = FALSE;
            return SCPI_EXPR_OK;
        }
    }
    return SCPI_EXPR_NO_MORE;
}
scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo)
{
    lex_state_t lex;
    int i;
    scpi_expr_result_t res;
    if (!isRange || !valueFrom || !valueTo || !param) {
        SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
        return SCPI_EXPR_ERROR;
    }
    if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) {
        SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR);
        return SCPI_EXPR_ERROR;
    }
    lex.buffer = param->ptr + 1;
    lex.pos = lex.buffer;
    lex.len = param->len - 2;
    for (i = 0; i <= index; i++) {
        res = numericRange(&lex, isRange, valueFrom, valueTo);
        if (res != SCPI_EXPR_OK) {
            break;
        }
        if (i != index) {
            if (!scpiLex_Comma(&lex, valueFrom)) {
                res = SCPI_EXPR_ERROR;
                break;
            }
        }
    }
    if (res == SCPI_EXPR_ERROR) {
        SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR);
    }
    return res;
}
scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo)
{
    scpi_expr_result_t res;
    scpi_bool_t range = FALSE;
    scpi_parameter_t paramFrom;
    scpi_parameter_t paramTo;
    res = SCPI_ExprNumericListEntry(context, param, index, &range, &paramFrom, &paramTo);
    if (res == SCPI_EXPR_OK) {
        SCPI_ParamToInt(context, &paramFrom, valueFrom);
        if (range) {
            SCPI_ParamToInt(context, &paramTo, valueFrom);
        }
    }
    return res;
}
scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo)
{
    scpi_expr_result_t res;
    scpi_bool_t range = FALSE;
    scpi_parameter_t paramFrom;
    scpi_parameter_t paramTo;
    res = SCPI_ExprNumericListEntry(context, param, index, &range, &paramFrom, &paramTo);
    if (res == SCPI_EXPR_OK) {
        SCPI_ParamToDouble(context, &paramFrom, valueFrom);
        if (range) {
            SCPI_ParamToDouble(context, &paramTo, valueFrom);
        }
    }
    return res;
}
libscpi/src/lexer.c
@@ -865,6 +865,26 @@
}
/**
 * Detect token colon
 * @param state
 * @param token
 * @return
 */
int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) {
    token->ptr = state->pos;
    if (skipChr(state, ':')) {
        token->len = 1;
        token->type = SCPI_TOKEN_COLON;
    } else {
        token->len = 0;
        token->type = SCPI_TOKEN_UNKNOWN;
    }
    return token->len;
}
/**
 * Detect token New line
 * @param state
 * @param token
@@ -888,6 +908,3 @@
    return token->len;
}
libscpi/src/lexer_private.h
@@ -56,6 +56,7 @@
    int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL;
    int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) LOCAL;
    int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) LOCAL;
    int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) LOCAL;
    int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) LOCAL;
#ifdef    __cplusplus