Sfoglia il codice sorgente

refactor: grammar代码重构

去除ts的token_ahead和ahead成员
把grammar操作ts的宏改写为特有函数
取出非必须的ts操作函数
ts使用token的链表, 放弃使用数组
grammar代码冗余优化
SongZihuan 4 anni fa
parent
commit
e3208fc78d
8 ha cambiato i file con 296 aggiunte e 415 eliminazioni
  1. 14 60
      include/__grammar.h
  2. 1 0
      include/__macro.h
  3. 1 1
      include/statement.h
  4. 5 8
      include/token.h
  5. 8 1
      main.c
  6. 229 242
      parser/grammar.c
  7. 37 103
      parser/token.c
  8. 1 0
      src/runbranch.c

+ 14 - 60
include/__grammar.h

@@ -17,68 +17,12 @@ writeLog(pm->paser_debug, pasers_level, "\n"message, __VA_ARGS__); \
 #define writeLog_(...) PASS
 #endif
 
-// TODO-szh 优化token操作, 减少内存操作
-#define popAheadToken(token_var, pm) do{ \
-doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count); \
-pm->count ++; \
-safeGetToken(pm->tm, pm->paser_debug); \
-/* 执行popheanToken之前执行readBackToken因此不必再检查status */ \
-token_var = popToken(pm->tm->ts, pm->paser_debug); \
-} while(0) /*弹出预读的token*/
-
-#define addStatementToken(type, st, pm) do{\
-Token *tmp_new_token; \
-tmp_new_token = makeStatementToken(type, st); \
-addToken(pm->tm->ts, tmp_new_token, pm->paser_debug); \
-backToken(pm->tm->ts, pm->paser_debug); \
-} while(0)
-
-#define backToken_(pm, token) do{ \
-addToken(pm->tm->ts, (token), pm->paser_debug); \
-backToken(pm->tm->ts, pm->paser_debug); \
-}while(0)
-
+#define addStatementToken(type, st, pm) addBackToken(pm->tm->ts, makeStatementToken(type, st), pm->paser_debug)
+#define delToken(pm) freeToken(popAheadToken(pm), true, false)
+#define backToken_(pm, token) addBackToken(pm->tm->ts, (token), pm->paser_debug)
 #define addToken_ backToken_
-
 #define call_success(pm) (pm->status == success)
 
-#define delToken(pm) do{ \
-Token *tmp_token; \
-popAheadToken(tmp_token, pm); \
-freeToken(tmp_token, true, false); \
-}while(0)
-
-#define checkToken(pm, type, error_) do{ \
-int token = readBackToken(pm); \
-if (token != type){ \
-goto error_; \
-} \
-delToken(pm); \
-}while(0)
-
-// pasersCommand专属macro
-#define commandCallBack(pm, st, call, type, return_) do{ \
-writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: call "#call"\n", NULL); \
-Token *tmp_token = NULL; \
-call(CALLPASERSSIGNATURE); \
-if (!call_success(pm) || readBackToken(pm) != type) \
-goto return_; \
-popAheadToken(tmp_token, pm); \
-st = tmp_token->data.st; \
-freeToken(tmp_token, true, false); \
-} while(0)
-
-#define commandCallControl(pm, st, call, type, return_) do{ \
-writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: call pasers"#call"\n", NULL); \
-Token *tmp_token = NULL; \
-parserControl(CALLPASERSSIGNATURE, call, type); \
-if (!call_success(pm) || readBackToken(pm) != type) \
-goto return_; \
-popAheadToken(tmp_token, pm); \
-st = tmp_token->data.st; \
-freeToken(tmp_token, true, false); \
-} while(0)
-
 void parserCommand(PASERSSIGNATURE);
 void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type);
 void parserDef(PASERSSIGNATURE);
@@ -94,7 +38,17 @@ void parserAssignment(PASERSSIGNATURE);
 void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int, int, char *, char *);
 void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*tailFunction)(PASERSSIGNATURE, Token *left_token,  Statement **st), int , int , char *, char *);
 
-void syntaxError(ParserMessage *pm, char *message, int status);
+void syntaxError(ParserMessage *pm, int status, int num, ...);
 int readBackToken(ParserMessage *pm);
+Token *popAheadToken(ParserMessage *pm);
+bool checkToken_(ParserMessage *pm, int type);
+bool commandCallControl_(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type, Statement **st, char *message);
+bool commandCallBack_(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int type, Statement **st, char *message);
+bool callParserCode(PASERSSIGNATURE, Statement **st,char *message);
+bool callParserAs(PASERSSIGNATURE, Statement **st,char *message);
+bool callChildStatement(PASERSSIGNATURE, void (*call)(PASERSSIGNATURE), int type, Statement **st, char *message);
+
+bool callChildToken(ParserMessage *pm, Inter *inter, void (*call)(ParserMessage *, Inter *), int type, Token **tmp,
+                    char *message, int error_type);
 
 #endif //VIRTUALMATH___GRAMMAR_H

+ 1 - 0
include/__macro.h

@@ -5,6 +5,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <getopt.h>
 
 #define bool int
 #define true 1

+ 1 - 1
include/statement.h

@@ -102,7 +102,7 @@ typedef struct StatementList{
         do_b,
     } type;
     struct Statement *condition;
-    struct Statement *var;  // TODO-szh if等分支计算结果允许赋值
+    struct Statement *var;
     struct Statement *code;
     struct StatementList *next;
 } StatementList;

+ 5 - 8
include/token.h

@@ -111,13 +111,13 @@ typedef struct Token{
         char *second_str;  // 针对123.4j这种形式设定的,其中second_str存储j
         struct Statement *st;
     } data;
+    struct Token *last;
+    struct Token *next;
 } Token;
 
 typedef struct TokenStream{
-    Token **token_list;  // 存储token的列表
-    Token **token_ahead;  // 提前存储token的列表
+    Token *token_list;  // 提前存储token的列表
     int size;
-    int ahead;
 } TokenStream;
 
 typedef struct TokenMessage{
@@ -135,11 +135,8 @@ void freeToken(Token *tk, bool self, bool error);
 extern Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug);
 
 
-int safeGetToken(TokenMessage *tm, FILE *debug);
-Token *forwardToken(TokenStream *ts, FILE *debug);
-Token *backToken(TokenStream *ts, FILE *debug);
-void addToken(TokenStream *ts, Token *new_tk, FILE *debug);
-Token *popToken(TokenStream *ts, FILE *debug);
+void addBackToken(TokenStream *ts, Token *new_tk, FILE *debug);
+Token *popNewToken(TokenMessage *tm, FILE *debug);
 
 TokenMessage *makeTokenMessage(char *file_dir, char *debug);
 void freeTokenMessage(TokenMessage *tm, bool self);

+ 8 - 1
main.c

@@ -1,5 +1,4 @@
 #include "__virtualmath.h"
-#include <getopt.h>
 
 static const struct option long_option[]={
         {"input",required_argument,NULL,'i'},
@@ -117,3 +116,11 @@ void freeArgs(){
     memFree(args.file);
     memFree(args.file);
 }
+
+/*
+ *  TODO-szh try...except 分支
+ *  TODO-szh 抛出异常
+ *  TODO-szh restart语句
+ *  TODO-szh 函数参数
+ *  TODO-szh 列表、字典
+ */

+ 229 - 242
parser/grammar.c

@@ -64,17 +64,11 @@ void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
         else{
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: call command\n", NULL);
             Token *command_token;
-            parserCommand(CALLPASERSSIGNATURE);
-            if (!call_success(pm)){
+            if (!callChildToken(CALLPASERSSIGNATURE, parserCommand, COMMAND, &command_token,
+                               (global ? "ERROR from command list(get parserCommand)" : NULL),
+                               command_list_error)){
                 goto return_;
             }
-            if (COMMAND != readBackToken(pm)){
-                if (global){
-                    syntaxError(pm, "ERROR from command list(get parserCommand)", command_list_error);
-                }
-                goto return_;
-            }
-            popAheadToken(command_token, pm);
 
             stop = readBackToken(pm);
             if (stop == MATHER_ENTER || stop == MATHER_SEMICOLON){
@@ -85,7 +79,7 @@ void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
             }
             else{
                 if (global) {
-                    syntaxError(pm, "ERROR from parserCommand list(get stop)", command_list_error);
+                    syntaxError(pm, command_list_error, 1, "ERROR from parserCommand list(get stop)");
                     freeToken(command_token, true, true);
                 }
                 else{
@@ -114,35 +108,37 @@ void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
  * | parserOperation
  */
 void parserCommand(PASERSSIGNATURE){
-    int token_type;
+    int token_type, status;
     Statement *st = NULL;
     token_type = readBackToken(pm);
     switch (token_type) {
         case MATHER_DEF :
-            commandCallBack(pm, st, parserDef, FUNCTION, return_);
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserDef, FUNCTION, &st, "Command: call def\n");
             break;
         case MATHER_IF :
-            commandCallBack(pm, st, parserIf, IF_BRANCH, return_);
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserIf, IF_BRANCH, &st, "Command: call def\n");
             break;
         case MATHER_WHILE :
-            commandCallBack(pm, st, parserWhile, WHILE_BRANCH, return_);
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserWhile, WHILE_BRANCH, &st, "Command: call def\n");
             break;
         case MATHER_BREAK :
-            commandCallControl(pm, st, makeBreakStatement, BREAK, return_);
+            status = commandCallControl_(CALLPASERSSIGNATURE, makeBreakStatement, BREAK, &st, "Command: call break\n");
             break;
         case MATHER_CONTINUE :
-            commandCallControl(pm, st, makeContinueStatement, CONTINUE, return_);
+            status = commandCallControl_(CALLPASERSSIGNATURE, makeContinueStatement, CONTINUE, &st, "Command: call continue\n");
             break;
         case MATHER_REGO :
-            commandCallControl(pm, st, makeRegoStatement, REGO, return_);
+            status = commandCallControl_(CALLPASERSSIGNATURE, makeRegoStatement, REGO, &st, "Command: call rego\n");
             break;
         case MATHER_RETURN :
-            commandCallControl(pm, st, makeReturnStatement, RETURN, return_);
+            status = commandCallControl_(CALLPASERSSIGNATURE, makeReturnStatement, RETURN,  &st, "Command: call return\n");
             break;
         default :
-            commandCallBack(pm, st, parserOperation, OPERATION, return_);
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserOperation, OPERATION, &st, "Command: call def\n");
             break;
     }
+    if (!status)
+        goto return_;
     addStatementToken(COMMAND, st, pm);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get  command success\n", NULL);
     return_:
@@ -157,7 +153,7 @@ void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int typ
         goto return_;
     if (readBackToken(pm) == OPERATION){
         Token *tmp;
-        popAheadToken(tmp, pm);
+        tmp= popAheadToken(pm);
         times = tmp->data.st;
         freeToken(tmp, true, false);
     }
@@ -168,8 +164,7 @@ void parserControl(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int typ
 }
 
 void parserIf(PASERSSIGNATURE){
-    Token *if_token = NULL, *code_token = NULL;
-    struct Statement *st = NULL, *var_st = NULL, *else_st = NULL, *finally_st = NULL;
+    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL;
     StatementList *sl = NULL;
     bool have_if = false;
     // TODO-szh 设置重复警告 (添加PASS语句)
@@ -180,78 +175,42 @@ void parserIf(PASERSSIGNATURE){
                 goto default_;
             else
                 have_if = true;
-        case MATHER_ELIF:
+        case MATHER_ELIF: {
+            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
             delToken(pm);
-            parserOperation(CALLPASERSSIGNATURE);
-            if (!call_success(pm))
-                goto return_;
-            if (readBackToken(pm) != OPERATION){
-                syntaxError(pm, "Don't get a if condition", syntax_error);
-                goto return_;
-            }
-            popAheadToken(if_token, pm);
+            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a if condition"))
+                goto error_;
 
-            if (readBackToken(pm) == MATHER_AS){
-                delToken(pm);
-                Token *var_token = NULL;
-                parserOperation(CALLPASERSSIGNATURE);
-                if (!call_success(pm))
-                    goto return_;
-                if (readBackToken(pm) != OPERATION){
-                    syntaxError(pm, "Don't get a if var", syntax_error);
-                    goto return_;
-                }
-                popAheadToken(var_token, pm);
-                var_st = var_token->data.st;
-                freeToken(var_token, true, false);
+            if (!callParserAs(CALLPASERSSIGNATURE, &var_tmp, "Don't get a while var")) {
+                freeStatement(condition_tmp);
+                goto error_;
             }
 
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
-                error_:
-                freeToken(if_token, true, true);
-                syntaxError(pm, "Don't get a if code", syntax_error);
-                goto return_;
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if code")) {
+                freeStatement(condition_tmp);
+                freeStatement(var_tmp);
+                goto error_;
             }
-            popAheadToken(code_token, pm);
-            sl = makeConnectStatementList(sl, if_token->data.st, var_st, code_token->data.st, if_b);
-            freeToken(if_token, true, false);
-            freeToken(code_token, true, false);
-            var_st = NULL;
+            sl = makeConnectStatementList(sl, condition_tmp, var_tmp, code_tmp, if_b);
             goto again;
-        case MATHER_DO:
+        }
+        case MATHER_DO: {
+            Statement *code_tmp = NULL;
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if...do code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            sl = makeConnectStatementList(sl, NULL, NULL, code_token->data.st, do_b);
-            freeToken(code_token, true, false);
+            sl = makeConnectStatementList(sl, NULL, NULL, code_tmp, do_b);
             goto again;
+        }
         case MATHER_ELSE:
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a if...else code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            if (else_st != NULL)
-                freeStatement(else_st);
-            else_st = code_token->data.st;
-            freeToken(code_token, true, false);
             goto again;
         case MATHER_FINALLY:
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a if...else code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            if (finally_st != NULL)
-                freeStatement(finally_st);
-            finally_st = code_token->data.st;
-            freeToken(code_token, true, false);
             goto again;
         case MATHER_ENTER:
             delToken(pm);
@@ -265,100 +224,61 @@ void parserIf(PASERSSIGNATURE){
     st->u.if_branch.else_list = else_st;
     st->u.if_branch.finally = finally_st;
     addStatementToken(IF_BRANCH, st, pm);
+    return;
 
-    return_:
+    error_:
+    freeStatement(else_st);
+    freeStatement(finally_st);
+    freeStatementList(sl);
     return;
 }
 
 void parserWhile(PASERSSIGNATURE){
-    Token *while_token = NULL, *code_token = NULL;
-    struct Statement *st = NULL, *var_st = NULL, *else_st = NULL, *finally_st = NULL,*do_st = NULL;
+    struct Statement *st = NULL, *else_st = NULL, *finally_st = NULL,*do_st = NULL;
     StatementList *sl = NULL;
     bool have_while = false;
 
     again:
     switch (readBackToken(pm)) {
-        case MATHER_WHILE:
+        case MATHER_WHILE: {
             if (have_while)
                 goto default_;
             else
                 have_while = true;
 
+            Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
             delToken(pm);
-            parserOperation(CALLPASERSSIGNATURE);
-            if (!call_success(pm))
-                goto return_;
-            if (readBackToken(pm) != OPERATION){
-                syntaxError(pm, "Don't get a else while condition", syntax_error);
-                goto return_;
-            }
-            popAheadToken(while_token, pm);
+            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a while condition"))
+                goto error_;
 
-            if (readBackToken(pm) == MATHER_AS){
-                delToken(pm);
-                Token *var_token = NULL;
-                parserOperation(CALLPASERSSIGNATURE);
-                if (!call_success(pm))
-                    goto return_;
-                if (readBackToken(pm) != OPERATION){
-                    syntaxError(pm, "Don't get a while var", syntax_error);
-                    goto return_;
-                }
-                popAheadToken(var_token, pm);
-                var_st = var_token->data.st;
-                freeToken(var_token, true, false);
+            if (!callParserAs(CALLPASERSSIGNATURE, &var_tmp, "Don't get a while var")){
+                freeStatement(condition_tmp);
+                goto error_;
             }
-
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
-                error_:
-                freeToken(while_token, true, true);
-                syntaxError(pm, "Don't get a while code", syntax_error);
-                goto return_;
+            if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a while code")) {
+                freeStatement(condition_tmp);
+                freeStatement(var_tmp);
+                goto error_;
             }
-            popAheadToken(code_token, pm);
             if (sl != NULL)
                 freeStatementList(sl);
-            sl = makeStatementList(while_token->data.st, var_st, code_token->data.st, if_b);
-            freeToken(while_token, true, false);
-            freeToken(code_token, true, false);
-            var_st = NULL;
+            sl = makeStatementList(condition_tmp, var_tmp, code_tmp, if_b);
             goto again;
+        }
         case MATHER_DO:
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a while...do code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            if (do_st != NULL)
-                freeStatement(do_st);
-            do_st = code_token->data.st;
-            freeToken(code_token, true, false);
             goto again;
         case MATHER_ELSE:
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a while...else code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            if (else_st != NULL)
-                freeStatement(else_st);
-            else_st = code_token->data.st;
-            freeToken(code_token, true, false);
             goto again;
         case MATHER_FINALLY:
             delToken(pm);
-            parserCode(CALLPASERSSIGNATURE);
-            if (!call_success(pm) && readBackToken(pm) != CODE){
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a while...finally code"))
                 goto error_;
-            }
-            popAheadToken(code_token, pm);
-            if (finally_st != NULL)
-                freeStatement(finally_st);
-            finally_st = code_token->data.st;
-            freeToken(code_token, true, false);
             goto again;
         case MATHER_ENTER:
             delToken(pm);
@@ -373,70 +293,67 @@ void parserWhile(PASERSSIGNATURE){
     st->u.while_branch.finally = finally_st;
     st->u.while_branch.after = do_st;
     addStatementToken(WHILE_BRANCH, st, pm);
+    return;
 
-    return_:
+    error_:
+    freeStatement(else_st);
+    freeStatement(finally_st);
+    freeStatement(do_st);
+    freeStatementList(sl);
     return;
 }
 
 void parserDef(PASERSSIGNATURE){
-    Token *name_token = NULL, *code_token = NULL;
-    struct Statement *st = NULL;
+    struct Statement *st = NULL, *name_tmp = NULL, *code_tmp = NULL;
     delToken(pm);
 
-    parserBaseValue(CALLPASERSSIGNATURE);
-    if (!call_success(pm))
-        goto return_;
-    if (readBackToken(pm) != BASEVALUE){
-        syntaxError(pm, "Don't get a function name", syntax_error);
-        goto return_;
-    }
-    popAheadToken(name_token, pm);
+    if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &name_tmp, "Don't get a function name"))
+        goto error_;
 
-    checkToken(pm, MATHER_LP, error_);
-    checkToken(pm, MATHER_RP, error_);
+    if (!checkToken_(pm, MATHER_LP) || !checkToken_(pm, MATHER_RP)){
+        goto error_;
+    }
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: get function title success\n", NULL);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: call parserCode\n", NULL);
-    parserCode(CALLPASERSSIGNATURE);
-    if (!call_success(pm)){
+
+    if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code"))
         goto error_;
-    }
-    if (readBackToken(pm) != CODE){
-        error_:
-        freeToken(name_token, true, true);
-        syntaxError(pm, "Don't get a function code", syntax_error);
-        goto return_;
-    }
-    popAheadToken(code_token, pm);
 
-    st = makeFunctionStatement(name_token->data.st, code_token->data.st);
+    st = makeFunctionStatement(name_tmp, code_tmp);
     addStatementToken(FUNCTION, st, pm);
-    freeToken(code_token, true, false);
-    freeToken(name_token, true, false);
+    return;
 
-    return_:
+    error_:
+    freeStatement(name_tmp);
+    freeStatement(code_tmp);
+    syntaxError(pm, syntax_error, 1, "Don't get a function code");
     return;
 }
 
 void parserCode(PASERSSIGNATURE){
     Token *code_token = NULL, *tk = NULL;
-    struct Statement *st = makeStatement();
+    Statement *st = makeStatement();
     while (true){
-        checkToken(pm, MATHER_LC, again_);  // 若匹配的不是{则检查是否匹配到\n
-        break;  // 若匹配到{则跳出循环
-        again_: checkToken(pm, MATHER_ENTER, return_);  // 若不是\n则跳到return_
+        if (!checkToken_(pm, MATHER_LC))
+            goto again_;
+        break;
+        again_:
+        if (!checkToken_(pm, MATHER_ENTER))
+            goto return_;
     }
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList\n", NULL);
     parserCommandList(CALLPASERSSIGNATURE, false, st);
     if (!call_success(pm)){
-        goto return_;
+        goto error_;
     }
     if (readBackToken(pm) != COMMANDLIST){
-        syntaxError(pm, "Not CommandList\n", syntax_error);
-        goto return_;
+        syntaxError(pm, syntax_error, 1, "Not CommandList\n");
+        goto error_;
     }
-    popAheadToken(code_token, pm);
+    code_token = popAheadToken(pm);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList success\n", NULL);
-    checkToken(pm, MATHER_RC, error_);
+    if (!checkToken_(pm, MATHER_RC))
+        goto error_;
 
     return_:
     addStatementToken(CODE, st, pm);
@@ -444,8 +361,9 @@ void parserCode(PASERSSIGNATURE){
     return;
 
     error_:
-    syntaxError(pm, "Don't get the }", syntax_error);
+    syntaxError(pm, syntax_error, 1, "Don't get the }");
     freeToken(code_token, true, true);
+    freeStatement(st);
 }
 
 /**
@@ -454,23 +372,17 @@ void parserCode(PASERSSIGNATURE){
  * | parserAssignment
  */
 void parserOperation(PASERSSIGNATURE){
-    Token *operation_token = NULL;
+    Statement *operation_st = NULL;
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: call assignment\n", NULL);
-    parserAssignment(CALLPASERSSIGNATURE);
-    if (!call_success(pm))
-        goto return_;
-    if (readBackToken(pm) != ASSIGNMENT){
+    if (!callChildStatement(CALLPASERSSIGNATURE, parserAssignment, ASSIGNMENT, &operation_st, NULL))
         goto return_;
-    }
-    popAheadToken(operation_token, pm);
-    /*...do something for operation...*/
 
-    addStatementToken(OPERATION, operation_token->data.st, pm);
-    freeToken(operation_token, true, false);
+    addStatementToken(OPERATION, operation_st, pm);
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: get polynomial success\n", NULL);
 
     return_:
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: return\n", NULL);
+    return;
 }
 
 /**
@@ -549,13 +461,12 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
         return -1;
     }
     delToken(pm);
-    checkToken(pm, MATHER_RP, error_);
+    if (!checkToken_(pm, MATHER_RP)){
+        syntaxError(pm, syntax_error, 1, "Don't get ) from call back");
+        return 0;
+    }
     *st = makeCallStatement(left_token->data.st);
     return 1;
-
-    error_:
-    syntaxError(pm, "Don't get ) from call back", syntax_error);
-    return 0;
 }
 void parserCallBack(PASERSSIGNATURE){
     return tailOperation(CALLPASERSSIGNATURE, parserBaseValue, tailCall, BASEVALUE, CALLBACK,
@@ -563,24 +474,14 @@ void parserCallBack(PASERSSIGNATURE){
 }
 
 int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
-    Token *operation_token;
-
-    parserOperation(CALLPASERSSIGNATURE);
-    if (!call_success(pm)){
-        return 0;
-    }
-    if (readBackToken(pm) != OPERATION){
+    if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, NULL))
         return 0;
-    }
-    popAheadToken(operation_token, pm);
 
     if (readBackToken(pm) != right_type){
+        freeStatement(*st);
         return -1;
     }
     delToken(pm);
-
-    *st = operation_token->data.st;
-    freeToken(operation_token, true, false);
     return 1;
 }
 
@@ -597,7 +498,7 @@ void parserBaseValue(PASERSSIGNATURE){
     token_type = readBackToken(pm);
     if(MATHER_NUMBER == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number\n", NULL);
-        popAheadToken(value_token, pm);
+        value_token= popAheadToken(pm);
         char *stop;
         st = makeStatement();
         st->type = base_value;
@@ -605,14 +506,14 @@ void parserBaseValue(PASERSSIGNATURE){
     }
     else if(MATHER_STRING == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string\n", NULL);
-        popAheadToken(value_token, pm);
+        value_token= popAheadToken(pm);
         st = makeStatement();
         st->type = base_value;
         st->u.base_value.value = makeStringValue(value_token->data.str, inter);
     }
     else if(MATHER_VAR == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get var\n", NULL);
-        popAheadToken(value_token, pm);
+        value_token= popAheadToken(pm);
         st = makeStatement();
         st->type = base_var;
         st->u.base_var.name = memStrcpy(value_token->data.str, 0, false, false);
@@ -622,22 +523,22 @@ void parserBaseValue(PASERSSIGNATURE){
         int tmp;
         Statement *tmp_st = NULL;
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
-        popAheadToken(value_token, pm);
+        value_token= popAheadToken(pm);
 
         tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RB, &tmp_st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);
-            syntaxError(pm, "Don't get operation from list/var", syntax_error);
+            syntaxError(pm, syntax_error, 1, "Don't get operation from list/var");
             goto return_;
         }
         else if(tmp == -1){
             freeToken(value_token, true, true);
-            syntaxError(pm, "Don't get ] from list/var", syntax_error);
+            syntaxError(pm, syntax_error, 1, "Don't get ] from list/var");
             goto return_;
         }
         if (MATHER_VAR == readBackToken(pm)){
             Token *var_token;
-            popAheadToken(var_token, pm);
+            var_token= popAheadToken(pm);
             st = makeStatement();
             st->type = base_var;
             st->u.base_var.name = memStrcpy(var_token->data.str, 0, false, false);
@@ -648,16 +549,16 @@ void parserBaseValue(PASERSSIGNATURE){
     }
     else if(MATHER_LP == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
-        popAheadToken(value_token, pm);
+        value_token= popAheadToken(pm);
         int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);
-            syntaxError(pm, "Don't get operation from Base Value", syntax_error);
+            syntaxError(pm, syntax_error, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
             freeToken(value_token, true, true);
-            syntaxError(pm, "Don't get ) from Base Value", syntax_error);
+            syntaxError(pm, syntax_error, 1, "Don't get ) from Base Value");
             goto return_;
         }
     }
@@ -680,17 +581,14 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
         readBackToken(pm);
         if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
-            callBack(CALLPASERSSIGNATURE);
-            if (!call_success(pm) || (readBackToken(pm) != type))
+            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
                 goto return_;
-            popAheadToken(left_token, pm);
-            addStatementToken(self_type, left_token->data.st, pm);
-            freeToken(left_token, true, false);
+            addStatementToken(self_type, st, pm);
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
                       "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
             continue;
         }
-        popAheadToken(left_token, pm);
+        left_token= popAheadToken(pm);
 
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
         if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st)){
@@ -703,25 +601,20 @@ inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
                   "%s: get symbol success\n%s: call %s[right]\n", self_name, self_name, call_name);
 
-        callBack(CALLPASERSSIGNATURE);  // 获得
+        callBack(CALLPASERSSIGNATURE);  // 获得
         if (!call_success(pm)){
             freeToken(left_token, true, false);
             freeStatement(st);
             goto return_;
         }
         if (readBackToken(pm) != type){  // 若非正确数值
-            char *tmp1, *tmp2;
-            tmp1 = memStrcat("ERROR from ", self_name);
-            tmp2 = memStrcat(tmp1, "(get right)");
-            syntaxError(pm, tmp2, syntax_error);
-            memFree(tmp1);
-            memFree(tmp2);
+            syntaxError(pm, syntax_error, 3, "ERROR from ", self_name, "(get right)");
             freeToken(left_token, true, true);
             freeStatement(st);
             goto return_;
         }
 
-        popAheadToken(right_token, pm);
+        right_token= popAheadToken(pm);
         addToken_(pm, setOperationFromToken(st, left_token, right_token, self_type));
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
     }
@@ -736,17 +629,14 @@ inline void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), in
 
         if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
-            callBack(CALLPASERSSIGNATURE);
-            if ((!call_success(pm)) || readBackToken(pm) != type)
+            if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
                 goto return_;
-            popAheadToken(left_token, pm);
-            addStatementToken(self_type, left_token->data.st, pm);
-            freeToken(left_token, true, false);
+            addStatementToken(self_type, st, pm);
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
                       "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
             continue;
         }
-        popAheadToken(left_token, pm);
+        left_token= popAheadToken(pm);
 
         int tail_status = tailFunction(CALLPASERSSIGNATURE, left_token, &st);
         if (tail_status == -1){
@@ -775,22 +665,119 @@ inline void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), in
  * @param message 错误信息
  * @param status 错误类型
  */
-void syntaxError(ParserMessage *pm, char *message, int status){
+void syntaxError(ParserMessage *pm, int status, int num, ...) {
     if (pm->status != success)
         return;
+
+    char *message = NULL;
+    va_list message_args;
+    if (status <= 0){
+        message = "Not message";
+        goto not_message;
+    }
+    va_start(message_args, num);
+    for (int i=0; i < num; i++) {
+        char *new_message;
+        new_message = memStrcat(message, va_arg(message_args, char *));
+        memFree(message);
+        message = new_message;
+    }
+    va_end(message_args);
+
+    not_message:
     pm->status = status;
-    pm->status_message = memStrcpy(message, 0, false, false);
+    pm->status_message = message;
 }
 
 int readBackToken(ParserMessage *pm){
-    // TODO-szh 优化执行效果
     writeLog(pm->grammar_debug, GRAMMAR_DEBUG, "token operation number : %d\n", pm->count);
     writeLog(pm->paser_debug, DEBUG, "\ntoken operation number : %d\n", pm->count);
     pm->count ++;
-    int status = safeGetToken(pm->tm, pm->paser_debug);
-    if (status == -2){
-        syntaxError(pm, "lexical make some error", lexical_error);
+    Token *tmp = popNewToken(pm->tm, pm->paser_debug);
+    if (tmp->token_type == -2){
+        freeToken(tmp, true, false);
+        syntaxError(pm, lexical_error, 1, "lexical make some error");
+    }
+    addBackToken(pm->tm->ts, tmp, pm->paser_debug);
+    return tmp->token_type;
+}
+
+Token *popAheadToken(ParserMessage *pm){
+    doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count ++);
+    return popNewToken(pm->tm, pm->paser_debug);
+}
+
+bool checkToken_(ParserMessage *pm, int type){
+    if (readBackToken(pm) != type){
+        return false;
     }
-    backToken(pm->tm->ts, pm->paser_debug);
-    return status;
-}
+    delToken(pm);
+    return true;
+}
+
+bool commandCallControl_(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type, Statement **st, char *message){
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "message", NULL);
+    Token *tmp_token = NULL;
+    parserControl(CALLPASERSSIGNATURE, callBack, type);
+    if (!call_success(pm) || readBackToken(pm) != type)
+        return false;
+    tmp_token = popAheadToken(pm);
+    *st = tmp_token->data.st;
+    freeToken(tmp_token, true, false);
+    return true;
+}
+
+inline bool commandCallBack_(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int type, Statement **st, char *message){
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, message, NULL);
+    return callChildStatement(CALLPASERSSIGNATURE, callBack, type, st, NULL);
+}
+
+bool callParserCode(PASERSSIGNATURE, Statement **st,char *message){
+    Statement *new_st = NULL;
+    if(!callChildStatement(CALLPASERSSIGNATURE, parserCode, CODE, &new_st, message)){
+        return false;
+    }
+    if (*st != NULL)
+        freeStatement(*st);
+    *st = new_st;
+    return true;
+}
+
+bool callParserAs(PASERSSIGNATURE, Statement **st,char *message){
+    if (readBackToken(pm) == MATHER_AS) {
+        delToken(pm);
+        return callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, message);
+    }
+    else
+        *st = NULL;
+    return true;
+}
+
+bool callChildToken(ParserMessage *pm, Inter *inter, void (*call)(ParserMessage *, Inter *), int type, Token **tmp,
+                    char *message, int error_type) {
+    call(CALLPASERSSIGNATURE);
+    if (!call_success(pm)) {
+        *tmp = NULL;
+        return false;
+    }
+    if (readBackToken(pm) != type) {
+        *tmp = NULL;
+        if (message != NULL)
+            syntaxError(pm, error_type, 1, message);
+        return false;
+    }
+    *tmp = popAheadToken(pm);
+    return true;
+}
+
+bool callChildStatement(PASERSSIGNATURE, void (*call)(PASERSSIGNATURE), int type, Statement **st, char *message){
+    Token *tmp = NULL;
+    bool status = callChildToken(CALLPASERSSIGNATURE, call, type, &tmp, message, syntax_error);
+    if (!status){
+        *st = NULL;
+        return false;
+    }
+    *st = tmp->data.st;
+    freeToken(tmp, true, false);
+    return true;
+}

+ 37 - 103
parser/token.c

@@ -6,6 +6,8 @@ Token *makeToken(){
     tmp->data.str = NULL;
     tmp->data.st = NULL;
     tmp->data.second_str = NULL;
+    tmp->next = NULL;
+    tmp->last = NULL;
     return tmp;
 }
 
@@ -41,22 +43,18 @@ void freeToken(Token *tk, bool self, bool error) {
 TokenStream *makeTokenStream(){
     TokenStream *tmp = memCalloc(1, sizeof(TokenStream));
     tmp->size = 0;
-    tmp->ahead = 0;
     tmp->token_list = NULL;
-    tmp->token_ahead = NULL;
     return tmp;
 }
 
 void freeToekStream(TokenStream *ts, bool self) {
     freeBase(ts, return_);
-    for (int i=0; i < ts->size; i++){
-        freeToken(ts->token_list[i], true, false);
+    Token *tmp = ts->token_list;
+    while (tmp != NULL){
+        Token *tmp_next = tmp->next;
+        freeToken(tmp, true, false);
+        tmp = tmp_next;
     }
-    for (int i=0; i < ts->ahead; i++){
-        freeToken(ts->token_ahead[i], true, false);
-    }
-    memFree(ts->token_list);
-    memFree(ts->token_ahead);
     if (self){
         memFree(ts);
     }
@@ -98,117 +96,56 @@ void freeTokenMessage(TokenMessage *tm, bool self) {
 }
 
 /**
- * 添加一个token到token_list,token_ahend保持
+ * 添加一个token到token_ahend,token_list保持
  * @param ts
  * @param new_tk
  */
-void addToken(TokenStream *ts, Token *new_tk, FILE *debug) {
+void addBackToken(TokenStream *ts, Token *new_tk, FILE *debug) {
     printTokenEnter(new_tk, debug, DEBUG, "add Token: ");
-    Token **new_list = memCalloc(ts->size + 1, sizeof(Token *));
-    for (int i=0; i < ts->size; i++){
-        new_list[i] = ts->token_list[i];
-    }
-    new_list[ts->size] = new_tk;
+    Token *tmp = ts->token_list;
+
+    ts->token_list = new_tk;
+    new_tk->next = tmp;
+    new_tk->last = NULL;
+    if (tmp != NULL)
+        tmp->last = new_tk;
     ts->size ++;
-    memFree(ts->token_list);
-    ts->token_list = new_list;
     MACRO_printTokenStream(ts, debug, DEEP_DEBUG);
 }
 
 /**
- * 从token_list弹出一个token,保持token_ahend
+ * 从token_ahead弹出一个token,保持token_list
  * @param ts
  * @return
  */
 Token *popToken(TokenStream *ts, FILE *debug) {
-    Token **new_list = memCalloc(ts->size - 1, sizeof(Token *));
-    for (int i=0; i < ts->size - 1; i++){
-        new_list[i] = ts->token_list[i];
-    }
-    Token *tmp = ts->token_list[ts->size - 1];
-    memFree(ts->token_list);
-    ts->token_list = new_list;
+    Token *tmp = ts->token_list;
+    ts->token_list = tmp->next;
+    tmp->next = NULL;
+    tmp->last = NULL;
+    if (ts->token_list != NULL)
+        ts->token_list->last = NULL;
     ts->size --;
     printTokenEnter(tmp, debug, DEBUG, "pop Token: ");
     MACRO_printTokenStream(ts, debug, DEEP_DEBUG);
     return tmp;
 }
 
-/**
- * 把token_list的一个token退回到token_ahend
- * @param ts
- * @return
- */
-Token *backToken(TokenStream *ts, FILE *debug) {
-    Token **new_list = memCalloc(ts->size - 1, sizeof(Token *));
-    Token **new_ahead = memCalloc(ts->ahead + 1, sizeof(Token *));
-    for (int i=0; i < ts->size - 1; i++){
-        new_list[i] = ts->token_list[i];
-    }
-    for (int i=0; i < ts->ahead; i++){
-        new_ahead[i] = ts->token_ahead[i];
-    }
-    new_ahead[ts->ahead] = ts->token_list[ts->size - 1];
-    memFree(ts->token_list);
-    memFree(ts->token_ahead);
-    ts->token_ahead = new_ahead;
-    ts->token_list = new_list;
-    ts->size --;
-    ts->ahead ++;
-    printTokenEnter(new_ahead[ts->ahead - 1], debug, DEBUG, "back Token: ");
-    MACRO_printTokenStream(ts, debug, DEEP_DEBUG);
-    return new_ahead[ts->ahead - 1];
-}
-
-/**
- * backToken的逆向操作
- * @param ts
- * @return
- */
-Token *forwardToken(TokenStream *ts, FILE *debug) {
-    Token **new_list = memCalloc(ts->size + 1, sizeof(Token *));
-    Token **new_ahead = memCalloc(ts->ahead - 1, sizeof(Token *));
-    for (int i=0; i < ts->size; i++){
-        new_list[i] = ts->token_list[i];
-    }
-    for (int i=0; i < ts->ahead - 1; i++){
-        new_ahead[i] = ts->token_ahead[i];
-    }
-    new_list[ts->size] = ts->token_ahead[ts->ahead - 1];
-    memFree(ts->token_list);
-    memFree(ts->token_ahead);
-    ts->token_ahead = new_ahead;
-    ts->token_list = new_list;
-    ts->size ++;
-    ts->ahead --;
-    printTokenEnter(new_list[ts->size - 1], debug, DEBUG, "forward Token: ");
-    MACRO_printTokenStream(ts, debug, DEEP_DEBUG);
-    return new_list[ts->size - 1];
-}
-
-/**
- * 获取token, 并且放入token_list中
- * 自动处理backToken
- * @param tm
- * @return 返回获取token的token_type
- */
-int safeGetToken(TokenMessage *tm, FILE *debug) {
-    writeLog_(debug, DEBUG, "safe get token : ", NULL);
+Token *popNewToken(TokenMessage *tm, FILE *debug) {
     Token *tmp;
-    if (tm->ts->ahead == 0){
-        writeLog_(debug, DEBUG, "get token: %d\n", tm->file->count);
+    writeLog_(debug, DEBUG, "pop new token : ", NULL);
+    if (tm->ts->size == 0){
         tmp = getToken(tm->file, tm->mathers, tm->debug);
-        addToken(tm->ts, tmp, debug);
-        MACRO_printTokenStream(tm->ts, debug, DEBUG);
     }
     else{
-        // forwardToken 会有详细的日志输出
-        tmp = forwardToken(tm->ts, debug);
+        tmp = popToken(tm->ts, debug);
     }
-    return tmp->token_type;
+    writeLog_(debug, DEBUG, "get token: %d\nnew token: ", tm->file->count);
+    printToken(tmp, debug, DEBUG);
+    writeLog_(debug, DEBUG, "\n", NULL);
+    return tmp;
 }
 
-
 void printToken(Token *tk, FILE *debug, int type) {
     if (tk->token_type >= 0) {
         char *tmp = tk->data.str, *second_tmp = tk->data.second_str;
@@ -231,17 +168,14 @@ void printToken(Token *tk, FILE *debug, int type) {
 
 void printTokenStream(TokenStream *ts, FILE *debug, int type) {
     writeLog_(debug, type, "token_list: ", NULL);
-    for (int i=0; i < ts->size; i ++){
-        if (i > 0)
-            writeLog_(debug, type, "-", NULL);
-        printToken(ts->token_list[i], debug, type);
-    }
-    writeLog_(debug, type, "\n", NULL);
-    writeLog_(debug, type, "token_ahead: ", NULL);
-    for (int i=0; i < ts->ahead; i ++){
+    Token *tmp = ts->token_list;
+    int i = 0;
+    while (tmp != NULL){
         if (i > 0)
             writeLog_(debug, type, "-", NULL);
-        printToken(ts->token_ahead[i], debug, type);
+        printToken(tmp, debug, type);
+        tmp = tmp->next;
+        i++;
     }
     writeLog_(debug, type, "\n", NULL);
 }

+ 1 - 0
src/runbranch.c

@@ -13,6 +13,7 @@ bool checkBool(Value *value){
     }
 }
 
+// TODO-szh 检查rego对else的支持
 Result ifBranch(INTER_FUNCTIONSIG) {
     Result result, else_tmp, finally_tmp;
     StatementList *if_list = st->u.if_branch.if_list;