Browse Source

feat: 优化了if和while的匹配

对else后的do和while/if语句进行报错
分支语句添加\n结束符
允许使用分号作为if和while分支的结尾, 并且避免进入defualt_模式增加\n结束符
SongZihuan 4 years ago
parent
commit
e4cc0e8662
3 changed files with 37 additions and 10 deletions
  1. 1 0
      include/__grammar.h
  2. 34 7
      parser/grammar.c
  3. 2 3
      parser/syntax.c

+ 1 - 0
include/__grammar.h

@@ -20,6 +20,7 @@ writeLog(pm->paser_debug, pasers_level, "\n"message, __VA_ARGS__); \
 #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 addEnter(pm) backToken_(pm, makeLexToken(MATHER_ENTER, NULL, NULL))
 #define addToken_ backToken_
 #define call_success(pm) (pm->status == success)
 

+ 34 - 7
parser/grammar.c

@@ -80,6 +80,7 @@ void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
             else{
                 if (global) {
                     syntaxError(pm, command_list_error, 1, "ERROR from parserCommand list(get stop)");
+                    printf("stop = %d\n", stop);
                     freeToken(command_token, true, true);
                 }
                 else{
@@ -140,7 +141,6 @@ void parserCommand(PASERSSIGNATURE){
     if (!status)
         goto return_;
     addStatementToken(COMMAND, st, pm);
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get  command success\n", NULL);
     return_:
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get return\n", NULL);
 }
@@ -176,6 +176,10 @@ void parserIf(PASERSSIGNATURE){
             else
                 have_if = true;
         case MATHER_ELIF: {
+            if (else_st != NULL) {
+                syntaxError(pm, syntax_error, 1, "get elif after else\n");
+                goto error_;
+            }
             Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
             delToken(pm);
             if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a if condition"))
@@ -195,6 +199,8 @@ void parserIf(PASERSSIGNATURE){
             goto again;
         }
         case MATHER_DO: {
+            if (else_st != NULL)
+                goto default_;
             Statement *code_tmp = NULL;
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a if...do code"))
@@ -203,6 +209,10 @@ void parserIf(PASERSSIGNATURE){
             goto again;
         }
         case MATHER_ELSE:
+            if (else_st != NULL){
+                syntaxError(pm, syntax_error, 1, "get else after else\n");
+                goto error_;
+            }
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a if...else code"))
                 goto error_;
@@ -211,12 +221,17 @@ void parserIf(PASERSSIGNATURE){
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a if...else code"))
                 goto error_;
-            goto again;
+            break;
         case MATHER_ENTER:
             delToken(pm);
             goto again;
-        default:
-            default_: break;
+        case MATHER_SEMICOLON:
+            break;
+        default:{
+            default_:
+            addEnter(pm);
+            break;
+        }
     }
 
     st = makeIfStatement();
@@ -266,11 +281,17 @@ void parserWhile(PASERSSIGNATURE){
             goto again;
         }
         case MATHER_DO:
+            if (do_st != NULL || else_st != NULL)
+                goto default_;
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a while...do code"))
                 goto error_;
             goto again;
         case MATHER_ELSE:
+            if (else_st != NULL) {
+                syntaxError(pm, syntax_error, 1, "get else after else\n");
+                goto error_;
+            }
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a while...else code"))
                 goto error_;
@@ -279,12 +300,17 @@ void parserWhile(PASERSSIGNATURE){
             delToken(pm);
             if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a while...finally code"))
                 goto error_;
-            goto again;
+            break;
         case MATHER_ENTER:
             delToken(pm);
             goto again;
-        default:
-            default_: break;
+        case MATHER_SEMICOLON:
+            break;
+        default: {
+            default_:
+            addEnter(pm);
+            break;
+        }
     }
 
     st = makeWhileStatement();
@@ -320,6 +346,7 @@ void parserDef(PASERSSIGNATURE){
         goto error_;
 
     st = makeFunctionStatement(name_tmp, code_tmp);
+    addEnter(pm);
     addStatementToken(FUNCTION, st, pm);
     return;
 

+ 2 - 3
parser/syntax.c

@@ -302,9 +302,8 @@ Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug) {
     }
     Token *tmp;
     if (status == -2){
-        status = MATHER_ERROR_;
-        writeLog_(debug, LEXICAL_DEBUG, "lexical ERROR\n", NULL);
-        tmp = makeLexToken(status, NULL, NULL);
+        writeLog_(debug, ERROR, "lexical ERROR\n", NULL);
+        tmp = makeLexToken(MATHER_ERROR_, NULL, NULL);
         goto return_;
     }
     tmp = makeLexToken(status, mathers->mathers[status]->str, mathers->mathers[status]->second_str);