From 4d39507183e0ace2d73f04817a398e858b66b677 Mon Sep 17 00:00:00 2001 From: Jan Breuer <jan.breuer@jaybee.cz> Date: 周五, 22 3月 2013 01:40:22 +0800 Subject: [PATCH] Update lexer, start of implementing parser --- libscpi/src/lexer.c | 81 ++++++++++---------------- libscpi/test/test_lexer.c | 22 ++++--- libscpi/src/parser.c | 50 ++++++++++++++++ libscpi/inc/scpi/lexer.h | 4 libscpi/src/scpi.g | 6 +- 5 files changed, 100 insertions(+), 63 deletions(-) diff --git a/libscpi/inc/scpi/lexer.h b/libscpi/inc/scpi/lexer.h index c2124b9..6aaeca6 100644 --- a/libscpi/inc/scpi/lexer.h +++ b/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); diff --git a/libscpi/src/lexer.c b/libscpi/src/lexer.c index abca2de..1507eed 100644 --- a/libscpi/src/lexer.c +++ b/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> */ diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 2ff12c2..df73700 100644 --- a/libscpi/src/parser.c +++ b/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); +} + + + + + + + + + + + + + + diff --git a/libscpi/src/scpi.g b/libscpi/src/scpi.g index 3a86647..a3993ff 100644 --- a/libscpi/src/scpi.g +++ b/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 diff --git a/libscpi/test/test_lexer.c b/libscpi/test/test_lexer.c index 47a8dfe..6e593c0 100644 --- a/libscpi/test/test_lexer.c +++ b/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) { -- Gitblit v1.9.1