1
0
Эх сурвалжийг харах

解包赋值和隐式list声明

SongZihuan 5 жил өмнө
parent
commit
8f64e78b7a
6 өөрчлөгдсөн 128 нэмэгдсэн , 12 устгасан
  1. 4 1
      inter/cfunc.c
  2. 2 0
      inter/interpreter.c
  3. 1 1
      paser/paser.c
  4. 3 0
      paser/paser.h
  5. 117 10
      paser/syntax.c
  6. 1 0
      paser/token.h

+ 4 - 1
inter/cfunc.c

@@ -2057,14 +2057,17 @@ GWARF_value parameter_to_list(parameter *tmp_s, var_list *the_var){  // 把param
         if(tmp_s->type != only_value){
             goto next;  // 跳过这一个
         }
-        
+        puts("cul 1");
         result_tmp = traverse(tmp_s->u.value, the_var, false);  // 不需要取__value__
+        printf("type = %d\n", tmp_s->u.value->type);
+        puts("cul 2");
         if(is_error(&result_tmp) || is_space(&result_tmp)){  // Name Error错误
             goto next;  // 直接指向下一个
         }
         index += 1;
         return_list.value.list_value->list_value = realloc(return_list.value.list_value->list_value, sizeof(GWARF_value) * index);  // 申请新空间
         return_list.value.list_value->list_value[index - 1] = result_tmp.value;  // 保存value
+        puts("count one");
         next: tmp_s = tmp_s->next;  // 指向下一个
     }
     return_list.value.list_value->index = index;

+ 2 - 0
inter/interpreter.c

@@ -180,7 +180,9 @@ GWARF_result read_statement(statement *the_statement, var_list *the_var, var_lis
             // base_value返回字面量 -> 主要返回object类型,还会返回GWARF_value的其他类型供生成object类型
             break;
         case base_list:  // get value[所有字面量均为这个表达式]
+            puts("WWWW2");
             return_value.value = to_object(parameter_to_list(the_statement->code.base_list.value, the_var), the_var);  // code
+            puts("WWWW");
             break;
         case base_dict:  // get value[所有字面量均为这个表达式]
             return_value.value = to_object(parameter_to_dict(the_statement->code.base_dict.value, the_var), the_var);  // code

+ 1 - 1
paser/paser.c

@@ -9,7 +9,7 @@
 #include "syntax.c"
 
 // int paser_status = 1;
-p_status paser_status = {.is_parameter = false, .is_func=false, .is_list=false, .is_dict=false};
+p_status paser_status = {.is_parameter = false, .is_func=false, .is_list=false, .is_dict=false, .is_left=false, .is_peq=false, .is_for=false};
 
 void do_exit(void);
 void setup();

+ 3 - 0
paser/paser.h

@@ -11,6 +11,9 @@ typedef struct p_status
     bool is_func;  // func模式不匹配 ()
     bool is_list;  // 不匹配参数的POW和name_value
     bool is_dict;  // 不匹配参数的MUL和非only_value选项以及用:取代=
+    bool is_left;  // 是否为最左边的公式
+    bool is_peq;  // 正在使用解包赋值
+    bool is_for;  // for循环,用于排除COMMA的使用[top_exp]
 } p_status;
 
 

+ 117 - 10
paser/syntax.c

@@ -35,6 +35,7 @@ void return_(p_status *status, token_node *list);
 void formal_parameter(p_status *status, token_node *list);
 void list_(p_status *status, token_node *list);
 void dict_(p_status *status, token_node *list);
+void hide_list(p_status *status, token_node *list);
 void paser_error(char *text);
 
 /*
@@ -86,6 +87,7 @@ void command_list(p_status *status, token_node *list){  // 多项式
 command : top_exp <ENTER>
 */
 void command(p_status *status, token_node *list){  // 多项式
+    status->is_left = false;  // is_left复位[只有top_exp会开启以及element会开启]
     fprintf(status_log, "[info][grammar]  mode status: command\n", text);
     token left, new_token;
 
@@ -158,7 +160,9 @@ void command(p_status *status, token_node *list){  // 多项式
     else{  // 表达式
         fprintf(status_log, "[info][grammar]  (command)back one token to (top_exp)\n");
         back_one_token(list, left);
+        status->is_left = true;
         get_base_token(status, list, top_exp, new_token);
+        status->is_left = false;
         if(new_token.type != NON_top_exp){
             back_one_token(list, new_token);  // 往回[不匹配类型]
             return;
@@ -312,7 +316,9 @@ void for_(p_status *status, token_node *list){
         }
         else{
             back_one_token(list, exp_1);
+            status->is_for = true;
             get_base_token(status,list,top_exp,exp_1);  // 不是使用right token,不需要执行safe_get_token
+            status->is_for = false;
             if(exp_1.type != NON_top_exp){  // 不是表达式
                 paser_error("Don't get 'top_exp'");
             }
@@ -329,7 +335,9 @@ void for_(p_status *status, token_node *list){
         }
         else{
             back_one_token(list, exp_2);
+            status->is_for = true;
             get_base_token(status,list,top_exp,exp_2);  // 不是使用right token,不需要执行safe_get_token
+            status->is_for = false;
             if(exp_2.type != NON_top_exp){  // 不是表达式
                 paser_error("Don't get 'top_exp'");
             }
@@ -347,7 +355,9 @@ void for_(p_status *status, token_node *list){
         }
         else{
             back_one_token(list, exp_3);
+            status->is_for = true;
             get_base_token(status,list,top_exp,exp_3);  // 不是使用right token,不需要执行safe_get_token
+            status->is_for = false;
             if(exp_3.type != NON_top_exp){  // 不是表达式
                 paser_error("Don't get 'top_exp'");
             }
@@ -456,13 +466,13 @@ void formal_parameter(p_status *status, token_node *list){  // 因试分解
         get_pop_token(status, list, comma);
         if(comma.type == COMMA_PASER){
             get_pop_token(status, list, before);
-            if(before.type == MUL_PASER){
+            if(before.type == MUL_PASER && !status->is_peq){
                 if(status->is_dict){
                     paser_error("dict shouldn't get '*'");
                 }
                 mode = put_args;
             }
-            else if(before.type == POW_PASER){
+            else if(before.type == POW_PASER && !status->is_peq){
                 if(status->is_list){
                     paser_error("list shouldn't get '*'");
                 }
@@ -484,11 +494,13 @@ void formal_parameter(p_status *status, token_node *list){  // 因试分解
             new_token = left;
             parameter *tmp = NULL;
             get_pop_token(status, list, eq);
-            if(eq.type == (status->is_dict ? COLON_PASER : EQ_PASER)){  // name_value模式
+            if(eq.type == ((status->is_dict || status->is_peq) ? COLON_PASER : EQ_PASER)){  // name_value模式
                 if(status->is_list){
                     paser_error("list shouldn't get '='");
                 }
+                if(status->is_peq) status->is_parameter = true;
                 get_right_token(status, list, top_exp, value_token);
+                if(status->is_peq) status->is_parameter = false;
                 if(value_token.type != NON_top_exp){
                     paser_error("Don't get a top_exp");
                     return;
@@ -564,11 +576,13 @@ void formal_parameter(p_status *status, token_node *list){  // 因试分解
         parameter *tmp = NULL;
         get_pop_token(status, list, eq);
         printf("eq.type = %d\n", eq.type);
-        if(eq.type == (status->is_dict ? COLON_PASER : EQ_PASER)){  // name_value模式
+        if(eq.type == ((status->is_dict || status->is_peq) ? COLON_PASER : EQ_PASER)){  // name_value模式
             if(status->is_list){
                 paser_error("list shouldn't get '='");
             }
+            if(status->is_peq) status->is_parameter = false;
             get_right_token(status, list, top_exp, value_token);
+            if(status->is_peq) status->is_parameter = true;
             if(value_token.type != NON_top_exp){
                 paser_error("Don't get a top_exp");
                 return;
@@ -883,9 +897,9 @@ void eq_number(p_status *status, token_node *list){  // 因试分解
         get_pop_token(status, list, symbol);
 
         if(symbol.type == EQ_PASER && !status->is_parameter){  // 模式2/3
-            get_right_token(status, list, call_back_, right);  // 回调右边
-            if(right.type != NON_call){
-                paser_error("Don't get a call_back_");
+            get_right_token(status, list, hide_list, right);  // 回调右边
+            if(right.type != NON_hide_list){
+                paser_error("Don't get a hide_list");
             }
             // 逻辑操作
             new_token.type = NON_eq;
@@ -910,19 +924,109 @@ void eq_number(p_status *status, token_node *list){  // 因试分解
         }
     }
     else{  // 模式1
+        // is_left将会在这里消亡为false
         fprintf(status_log, "[info][grammar]  (bool_or)back one token to (bool_and)\n");
         back_one_token(list, left);
-        get_base_token(status, list, call_back_, new_token);
-        if(new_token.type != NON_call){
+        get_base_token(status, list, hide_list, new_token);  // hide_list会处理is_left
+        if(new_token.type != NON_hide_list){
             back_one_token(list, new_token);  // 往回[不匹配类型]
             return;
         }
+        if(status->is_left){  // 必须是在最左边
+            status->is_left = false;  // 设置为false,随后一切top_exp行为均不执行这一步骤
+            token comma, p_left, eq_t, p_right, tmp;
+            parameter *the_right;
+            get_pop_token(status, list,comma);
+            if(comma.type == COMMA_PASER){  // a,b = [1,2]的赋值方式
+                back_one_token(list, new_token);  // 先把new_token和comma一起回退
+                back_again(list, comma);
+                
+                status->is_peq = true;
+                get_base_token(status,list,formal_parameter,p_left);
+                status->is_peq = false;
+                
+                get_pop_token(status, list, eq_t);
+                if(eq_t.type != EQ_PASER){
+                    paser_error("Don't get '='[1]");
+                }
+
+                get_pop_token(status,list,tmp);
+                if(tmp.type == POW_PASER || tmp.type == MUL_PASER || tmp.type == COLON_PASER){
+                    if(tmp.type != COLON_PASER){
+                        back_again(list, tmp);
+                    }
+                    get_right_token(status,list,formal_parameter,p_right);
+                    if(p_right.type != NON_parameter){
+                        paser_error("Don't get formal_parameter");
+                    }
+                    the_right = p_right.data.parameter_list;
+                }
+                else{
+                    back_again(list, tmp);
+                    get_right_token(status,list,hide_list,p_right);
+                    if(p_right.type != NON_hide_list){
+                        paser_error("Don't get hide_list");
+                    }
+                    the_right = make_parameter_value(p_right.data.statement_value);
+                    the_right->type = put_args;
+                    the_right->u.var = the_right->u.value;
+                }
+
+                new_token.data_type = statement_value;
+                new_token.data.statement_value = make_statement();
+                new_token.data.statement_value->type = pack_eq;
+                new_token.data.statement_value->code.pack_eq.left = p_left.data.parameter_list;
+                new_token.data.statement_value->code.pack_eq.right = the_right;
+            }
+            else{
+                back_again(list, comma);  // 回退comma 使用back_again目的是让new_token在comma之前
+            }
+        }
         new_token.type = NON_eq;
         add_node(list, new_token);
         return eq_number(status, list);  // 回调自己
     }
 }
 
+void hide_list(p_status *status, token_node *list){
+    fprintf(status_log, "[info][grammar]  mode status: top_exp\n");
+    token exp;
+    bool old_is_left = status->is_left;
+    status->is_left = false;
+    get_base_token(status,list,call_back_,exp);
+    status->is_left = old_is_left;
+    if(exp.type != NON_call){
+        back_one_token(list, exp);
+        return;
+    }
+    if(status->is_func + status->is_left + status->is_parameter + status->is_for + status->is_list + status->is_dict == 0){  // 几个会用到逗号的选项先排除
+        token comma;
+        get_pop_token(status,list,comma);
+        printf("comma.type = %d\n", comma.type);
+        if(comma.type == COMMA_PASER){
+            token new_token;
+            back_one_token(list, exp);
+            back_again(list, comma);
+            status->is_list = true;
+            get_base_token(status, list, formal_parameter, new_token);
+            status->is_list = false;
+            if(new_token.type != NON_parameter){
+                paser_error("Don't get formal_parameter");
+            }
+            statement *code_tmp =  make_statement();
+            code_tmp->type = base_list;
+            code_tmp->code.base_list.value = new_token.data.parameter_list;
+            exp.data.statement_value = code_tmp;
+            exp.data_type = statement_value;
+        }
+        else{
+            back_again(list, comma);
+        }
+    }
+    exp.type = NON_hide_list;
+    add_node(list, exp);  // 压入节点
+    return;
+}
 /*
 call_back_ : bool_or
            | call_back_ LB RB
@@ -1766,7 +1870,9 @@ void element(p_status *status, token_node *list){  // 数字归约
     gett = pop_node(list);  // 取得一个token
     if(gett.type == LB_PASER){  // 模式3
         fprintf(status_log, "[info][grammar]  (element)get LB\n");
+        status->is_left = true;  // 允许复位
         get_right_token(status, list, top_exp, new_token);
+        status->is_left = false;
         if(new_token.type != NON_top_exp){
             paser_error("Don't get 'top_exp'");            
         }
@@ -1802,7 +1908,9 @@ void element(p_status *status, token_node *list){  // 数字归约
     }
     else if(gett.type == LI_PASER){  // [1]a或[1]列表或[1,2,3,4]列表
         token exp_token, rb, tmp_var;
+        status->is_list = true;  // 防止top_exp收走逗号
         get_right_token(status, list, top_exp, exp_token);
+        status->is_list = false;  // 防止top_exp收走逗号
         if(exp_token.type == RI_PASER){  //可以认定为空list
             back_one_token(list, gett);
             back_again(list, exp_token);
@@ -2021,7 +2129,6 @@ void var_token(p_status *status, token_node *list){  // 数字归约
 /*
 number : INT_PASER
        | DOUBLE_PASER
-       | LB top_exp RB
 */
 void paser_value(p_status *status, token_node *list){  // 数字归约
     fprintf(status_log, "[info][grammar]  mode status: paser_value\n");

+ 1 - 0
paser/token.h

@@ -208,6 +208,7 @@ typedef enum token_type
     NON_return = -37,
     NON_list = -38,
     NON_dict = -39,
+    NON_hide_list = -40,
 } token_type;
 
 typedef union token_data