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