Jan Breuer
2013-03-22 4d39507183e0ace2d73f04817a398e858b66b677
Update lexer, start of implementing parser
5个文件已修改
163 ■■■■■ 已修改文件
libscpi/inc/scpi/lexer.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/lexer.c 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/parser.c 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/scpi.g 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/test/test_lexer.c 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/lexer.h
@@ -60,6 +60,8 @@
    TokProgramExpression,
    TokCompoundProgramHeader,
    TokCommonProgramHeader,
    TokCompoundQueryProgramHeader,
    TokCommonQueryProgramHeader,
    TokWhiteSpace,
    TokUnknown,
};
@@ -81,8 +83,6 @@
int SCPI_LexWhiteSpace(lex_state_t * state, token_t * token);
int SCPI_LexCommonProgramHeader(lex_state_t * state, token_t * token);
int SCPI_LexCompoundProgramHeader(lex_state_t * state,  token_t * token);
int SCPI_LexProgramHeader(lex_state_t * state,  token_t * token);
int SCPI_LexQuestion(lex_state_t * state, token_t * token);
int SCPI_LexCharacterProgramData(lex_state_t * state, token_t * token);
libscpi/src/lexer.c
@@ -217,79 +217,62 @@
}
/* 7.6.1 <COMMAND PROGRAM HEADER> */
int SCPI_LexCommonProgramHeader(lex_state_t * state, token_t * token) {
    token->ptr = state->pos;
static int skipCommonProgramHeader(lex_state_t * state) {
    if (skipStar(state)) {
        if(!skipProgramMnemonic(state)) {
            state->pos--;
        } else {
            return 1;
        }
    }
    token->len = state->pos - token->ptr;
    if((token->len > 0)) {
        token->type = TokCommonProgramHeader;
    } else {
        token->type = TokUnknown;
        state->pos = token->ptr;
        token->len = 0;
    }
    return token->len;
    return 0;
}
int SCPI_LexCompoundProgramHeader(lex_state_t * state,  token_t * token) {
    token->ptr = state->pos;
static int skipCompoundProgramHeader(lex_state_t * state) {
    const char * rollback = state->pos;
    
    skipColon(state);
    
    if(skipProgramMnemonic(state)) {
        while(skipColon(state)) {
            if(!skipProgramMnemonic(state)) {
                // TODO: lexer error
                break;
                state->pos = rollback;
                return 0;
            }
        }
    }
    token->len = state->pos - token->ptr;
    if((token->len > 0)) {
        token->type = TokCompoundProgramHeader;
        return 1;
    } else {
        token->type = TokUnknown;
        state->pos = token->ptr;
        token->len = 0;
        state->pos = rollback;
        return 0;
    }
    return token->len;
}
int SCPI_LexProgramHeader(lex_state_t * state,  token_t * token) {
    int res;
    res = SCPI_LexCommonProgramHeader(state, token);
    if(res > 0) return res;
    res = SCPI_LexCompoundProgramHeader(state, token);
    if(res > 0) return res;
    return 0;
}
int SCPI_LexQuestion(lex_state_t * state, token_t * token) {
    token->ptr = state->pos;
    token->type = TokUnknown;
    
    if (skipChr(state, '?')) {
        token->len = 1;
        token->type = TokQuiestion;
    } else {
        token->len = 0;
        token->type = TokUnknown;
    if(skipCommonProgramHeader(state)) {
        if (skipChr(state, '?')) {
            token->type = TokCommonQueryProgramHeader;
        } else {
            token->type = TokCommonProgramHeader;
        }
    } else if(skipCompoundProgramHeader(state)) {
        if (skipChr(state, '?')) {
            token->type = TokCompoundQueryProgramHeader;
        } else {
            token->type = TokCompoundProgramHeader;
        }
    }
    
    return token->len;
    if (token->type != TokUnknown) {
        token->len = state->pos - token->ptr;
    } else {
        token->len = 0;
        state->pos = token->ptr;
    }
    return token->len;
}
/* 7.7.1 <CHARACTER PROGRAM DATA> */
libscpi/src/parser.c
@@ -39,6 +39,7 @@
#include "scpi/config.h"
#include "scpi/parser.h"
#include "scpi/lexer.h"
#include "utils.h"
#include "scpi/error.h"
@@ -664,3 +665,52 @@
    return FALSE;
}
void SCPI_ProgramMessageUnit(scpi_t * context) {
    lex_state_t state;
    token_t tmp;
    token_t header;
    token_t token;
    state.buffer = state.pos = context->buffer.data;
    state.len = context->buffer.position;
    /* ignore whitespace at the begginig */
    SCPI_LexWhiteSpace(&state, &tmp);
    SCPI_LexProgramHeader(&state, &header);
    SCPI_LexWhiteSpace(&state, &tmp);
    SCPI_ParseProgramDate(context, &state, &token);
    SCPI_LexWhiteSpace(&state, &tmp);
    {
        SCPI_LexComma(&state, &token);
        SCPI_LexWhiteSpace(&state, &tmp);
        SCPI_ParseProgramDate(context, &state);
        SCPI_LexWhiteSpace(&state, &tmp);
    }
    SCPI_LexNewLine(&state, &tmp);
}
libscpi/src/scpi.g
@@ -10,7 +10,7 @@
    
    
programMessageUnit 
    :    WS* programHeader QUESTION? (WS programData (COMMA programData)*)?
    :    WS* programHeader (WS programData (COMMA programData)*)?
    ;
programHeader
@@ -19,11 +19,11 @@
    ;
compoundProgramHeader
    :    COLON? PROGRAM_MNEMONIC (COLON PROGRAM_MNEMONIC)*
    :    COLON? PROGRAM_MNEMONIC (COLON PROGRAM_MNEMONIC)* QUESTION?
    ;
    
commonProgramHeader 
    :    STAR PROGRAM_MNEMONIC
    :    STAR PROGRAM_MNEMONIC QUESTION?
    ;
    
programDataSeparator 
libscpi/test/test_lexer.c
@@ -44,6 +44,8 @@
        case TokProgramExpression: return "TokProgramExpression";
        case TokCompoundProgramHeader: return "TokCompoundProgramHeader";
        case TokCommonProgramHeader: return "TokCommonProgramHeader";
        case TokCompoundQueryProgramHeader: return "TokCompoundQueryProgramHeader";
        case TokCommonQueryProgramHeader: return "TokCommonQueryProgramHeader";
        case TokWhiteSpace: return "TokWhiteSpace";
        default: return "TokUnknown";
    }
@@ -91,7 +93,8 @@
void testWhiteSpace(void) {
    TEST_TOKEN("  \t MEA", SCPI_LexWhiteSpace, 0, 4, TokWhiteSpace);
    TEST_TOKEN("  \t MEAS", SCPI_LexWhiteSpace, 0, 4, TokWhiteSpace);
    TEST_TOKEN("MEAS", SCPI_LexWhiteSpace, 0, 0, TokUnknown);
}
void testNondecimal(void) {
@@ -120,14 +123,15 @@
}
void testProgramHeader(void) {
    TEST_TOKEN("*IDN? ", SCPI_LexCommonProgramHeader, 0, 4, TokCommonProgramHeader);
    TEST_TOKEN("*?; ", SCPI_LexCommonProgramHeader, 0, 0, TokUnknown);
    TEST_TOKEN("MEAS:VOLT:DC? ", SCPI_LexCommonProgramHeader, 0, 0, TokUnknown);
    TEST_TOKEN("MEAS:VOLT:DC? ", SCPI_LexCompoundProgramHeader, 0, 12, TokCompoundProgramHeader);
    TEST_TOKEN(":MEAS:VOLT:DC? ", SCPI_LexCompoundProgramHeader, 0, 13, TokCompoundProgramHeader);
    TEST_TOKEN(":MEAS::VOLT:DC? ", SCPI_LexCompoundProgramHeader, 0, 6, TokCompoundProgramHeader);
    TEST_TOKEN(":MEAS::VOLT:DC? ", SCPI_LexProgramHeader, 0, 6, TokCompoundProgramHeader);
    TEST_TOKEN("*IDN?", SCPI_LexProgramHeader, 0, 4, TokCommonProgramHeader);
    TEST_TOKEN("*IDN? ", SCPI_LexProgramHeader, 0, 5, TokCommonQueryProgramHeader);
    TEST_TOKEN("*RST ", SCPI_LexProgramHeader, 0, 4, TokCommonProgramHeader);
    TEST_TOKEN("*?; ", SCPI_LexProgramHeader, 0, 0, TokUnknown);
    TEST_TOKEN("MEAS:VOLT:DC? ", SCPI_LexProgramHeader, 0, 13, TokCompoundQueryProgramHeader);
    TEST_TOKEN("CONF:VOLT:DC ", SCPI_LexProgramHeader, 0, 12, TokCompoundProgramHeader);
    TEST_TOKEN(":MEAS:VOLT:DC? ", SCPI_LexProgramHeader, 0, 14, TokCompoundQueryProgramHeader);
    TEST_TOKEN(":MEAS::VOLT:DC? ", SCPI_LexProgramHeader, 0, 0, TokUnknown);
    TEST_TOKEN("*IDN?", SCPI_LexProgramHeader, 0, 5, TokCommonQueryProgramHeader);
    TEST_TOKEN("*RST", SCPI_LexProgramHeader, 0, 4, TokCommonProgramHeader);
}
void testArbitraryBlock(void) {