Jelajahi Sumber

feat: 字符串支持使用ascii或转义字符

SongZihuan 4 tahun lalu
induk
melakukan
52cb03ab57

+ 3 - 0
VirtulMathCore/include/lexical.h

@@ -20,6 +20,7 @@ struct LexMather{
     int string_type;
     char *str;
     char *second_str;
+    int ascii;
     enum LexMatherStatus{
         LEXMATHER_START=1,
         LEXMATHER_ING_1,
@@ -27,6 +28,7 @@ struct LexMather{
         LEXMATHER_ING_3,
         LEXMATHER_ING_4,
         LEXMATHER_ING_5,
+        LEXMATHER_ING_6,
         LEXMATHER_END_1,
         LEXMATHER_END_2,
         LEXMATHER_MISTAKE,
@@ -44,6 +46,7 @@ typedef struct LexMathers LexMathers;
 
 int readChar(LexFile *file);
 void backChar(LexFile *file);
+void clearLexFile(LexFile *file);
 
 LexFile *makeLexFile(char *dir);
 void freeLexFile(LexFile *file);

+ 9 - 8
VirtulMathCore/parser/grammar.c

@@ -46,21 +46,22 @@ void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st)
     while (!should_break){
         token_type = readBackToken(pm);
         if (token_type == -3 || token_type == -2)
-            goto return_;
+            break;
         else if (token_type == MATHER_EOF){
             delToken(pm);
-            goto return_;
+            break;
         }
         else if (token_type == MATHER_ENTER || token_type == MATHER_SEMICOLON){
             delToken(pm);
-            if (!is_one || !have_command)
-                continue;
+            if (is_one && have_command)
+                break;
         }
         else{
             Token *command_token = NULL;
             int stop;
+            have_command = true;
             if (!callChildToken(CALLPASERSSIGNATURE, parserCommand, COMMAND, &command_token, command_message, command_list_error))
-                goto return_;
+                break;
             line = command_token->line;
             stop = readBackToken(pm);
             if (stop == MATHER_ENTER) {
@@ -81,14 +82,14 @@ void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st)
                     connectStatement(st, command_token->data.st);
                     freeToken(command_token, false);
                 }
-                goto return_;
+                break;
             }
-            have_command = true;
             connectStatement(st, command_token->data.st);
             freeToken(command_token, false);
         }
     }
-    return_:
+    if (is_one)
+        clearLexFile(pm->tm->file);
     signal(SIGINT, bak);
     if (pm_KeyInterrupt != signal_reset) {
         pm_KeyInterrupt = signal_reset;

+ 8 - 0
VirtulMathCore/parser/lexical.c

@@ -26,6 +26,13 @@ void backChar(LexFile *file){
         file->line --;
 }
 
+void clearLexFile(LexFile *file) {
+    int ch;
+    backChar(file);
+    while ((ch = readChar(file)) != '\n' && ch != EOF)
+        PASS;
+}
+
 LexFile *makeLexFile(char *dir){
     LexFile *tmp = memCalloc(1, sizeof(LexFile));
     tmp->is_std = (bool)(dir == NULL);
@@ -55,6 +62,7 @@ void freeLexFile(LexFile *file) {
  */
 void setupMather(LexMather *mather){
     mather->len = 0;
+    mather->ascii = 0;
     mather->str = NULL;
     mather->second_str = NULL;
     mather->string_type = '"';

+ 61 - 2
VirtulMathCore/parser/syntax.c

@@ -61,9 +61,8 @@ void varMather(int p, LexMather *mather){
         else if(mather->status == LEXMATHER_START)
             mather->status = LEXMATHER_MISTAKE;
     }
-    else{
+    else
         mather->status = LEXMATHER_MISTAKE;
-    }
 }
 
 /**
@@ -85,6 +84,8 @@ void stringMather(int p, LexMather *mather){
     else if (mather->status == LEXMATHER_ING_1)
         if (mather->string_type == p)
             mather->status = LEXMATHER_ING_4;
+        else if ('\\' == p)
+            mather->status = LEXMATHER_ING_5;
         else if (EOF == p)
             mather->status = LEXMATHER_MISTAKE;
         else{
@@ -104,6 +105,64 @@ void stringMather(int p, LexMather *mather){
         }
         else
             mather->status = LEXMATHER_END_1;
+    else if (mather->status == LEXMATHER_ING_5){
+        char new = -1;
+        switch (p) {
+            case 'n':
+                new = '\n';
+                break;
+            case 't':
+                new = '\t';
+                break;
+            case 'b':
+                new = '\b';
+                break;
+            case 'a':
+                new = '\a';
+                break;
+            case 'r':
+                new = '\r';
+                break;
+            case '\'':
+                new = '\'';
+                break;
+            case '"':
+                new = '"';
+                break;
+            case '\\':
+                new = '\\';
+                break;
+            case '[':
+                mather->status = LEXMATHER_ING_6;
+                break;
+            default :
+            case '0':
+                mather->status = LEXMATHER_MISTAKE;
+                break;
+        }
+        if (new != -1) {
+            mather->str = memStrCharcpy(mather->str, 1, true, true, new);
+            mather->status = LEXMATHER_ING_1;
+            mather->len ++;
+        }
+    }
+    else if (mather->status == LEXMATHER_ING_6)
+        if (p == ']')
+            if (mather->ascii <= 0)
+                mather->status = LEXMATHER_MISTAKE;
+            else {
+                mather->str = memStrCharcpy(mather->str, 1, true, true, (char)mather->ascii);
+                mather->status = LEXMATHER_ING_1;
+                mather->len ++;
+            }
+        else if (isdigit(p)){
+            char num_[2] = {(char)p, 0};
+            int num = (int)strtol(num_, NULL, 10);
+            mather->ascii = (mather->ascii * 10) + num;
+            if (mather->ascii > 127)
+                mather->status = LEXMATHER_MISTAKE;
+        } else
+            mather->status = LEXMATHER_MISTAKE;
     else
         mather->status = LEXMATHER_MISTAKE;
 }