js: support RegExpr such as 'var p = /L/gi;'
authoryu.dongliang <18588496441@163.com>
Mon, 27 Oct 2025 13:45:02 +0000 (21:45 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 27 Oct 2025 13:45:37 +0000 (21:45 +0800)
examples/js.html
js/parse/scf_dfa.c
js/parse/scf_dfa_expr.c

index 4c21780dcc67bb378758544b281c34b58495c83f..852612d82a53607be200458946093dc673de30d2 100644 (file)
@@ -9,7 +9,7 @@
 <script>
 
 var str = "hello world";
-var p   = RegExpr("/L/gi");
+var p   = /L/gi;
 document.write(str.match(p));
 
 </script>
index 790cbfb1ea19165b2f77369f4fefc2b88c155370..e10711b0b89ad62e81f829c547e16e152e5d6e37 100644 (file)
@@ -357,36 +357,36 @@ static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_ve
                                }
                        }
                }
+       }
 
-               if (SCF_DFA_OK == ret) {
-                       scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
+       if (SCF_DFA_OK == ret) {
+               scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
 
-                       while (*pp) {
-                               scf_dfa_hook_t* hook = *pp;
-                               scf_dfa_node_t* hook_node = hook->node;
+               while (*pp) {
+                       scf_dfa_hook_t* hook = *pp;
+                       scf_dfa_node_t* hook_node = hook->node;
 
-                               *pp = hook->next;
-                               free(hook);
-                               hook = NULL;
+                       *pp = hook->next;
+                       free(hook);
+                       hook = NULL;
 
-                               scf_logi("\033[34m end hook: %s->action()\033[0m\n", hook_node->name);
+                       scf_logi("\033[34m end hook: %s->action()\033[0m\n", hook_node->name);
 
-                               if (!hook_node->action)
-                                       continue;
+                       if (!hook_node->action)
+                               continue;
 
-                               ret = hook_node->action(dfa, words, data);
+                       ret = hook_node->action(dfa, words, data);
 
-                               if (SCF_DFA_OK == ret)
-                                       continue;
+                       if (SCF_DFA_OK == ret)
+                               continue;
 
-                               if (SCF_DFA_SWITCH_TO == ret) {
-                                       scf_logi("\033[34m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name);
+                       if (SCF_DFA_SWITCH_TO == ret) {
+                               scf_logi("\033[34m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name);
 
-                                       node = hook_node;
-                                       ret  = SCF_DFA_NEXT_WORD;
-                               }
-                               break;
+                               node = hook_node;
+                               ret  = SCF_DFA_NEXT_WORD;
                        }
+                       break;
                }
        }
 
index 205c3c40fa2094e8f90266b71ec03177806333ff..60348e77e49e62189bf10676c55f752d64fc85c3 100644 (file)
@@ -49,6 +49,9 @@ static int _expr_is_unary_op(scf_dfa_t* dfa, void* word)
                        || SCF_LEX_WORD_KEY_SIZEOF == w->type)
                return 0;
 
+       if (SCF_LEX_WORD_DIV == w->type)
+               return 1;
+
        scf_operator_t* op = scf_find_base_operator(w->text->data, 1);
        if (op)
                return 1;
@@ -422,7 +425,58 @@ static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int
 
 static int _expr_action_unary_op(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       scf_logd("\n");
+       scf_lex_word_t*  w = words->data[words->size - 1];
+       scf_lex_word_t*  w1;
+       scf_lex_word_t*  w2;
+
+       if (SCF_LEX_WORD_DIV == w->type) {
+               while (1) {
+                       w1 = dfa->ops->pop_word(dfa);
+                       assert(w1);
+
+                       if (SCF_LEX_WORD_EOF == w1->type) {
+                               scf_loge("\n");
+
+                               scf_lex_word_free(w1);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       int tmp = w1->type;
+                       int ret = scf_string_cat(w->text, w1->text);
+
+                       scf_lex_word_free(w1);
+                       w1 = NULL;
+                       if (ret < 0)
+                               return ret;
+
+                       if (SCF_LEX_WORD_DIV == tmp) {
+                               w2 = dfa->ops->pop_word(dfa);
+                               assert(w2);
+
+                               if (SCF_LEX_WORD_ID != w2->type) {
+                                       scf_loge("\n");
+
+                                       scf_lex_word_free(w2);
+                                       return SCF_DFA_ERROR;
+                               }
+
+                               ret = scf_string_cat(w->text, w2->text);
+
+                               scf_lex_word_free(w2);
+                               w2 = NULL;
+                               if (ret < 0)
+                                       return ret;
+
+                               w->data.s = scf_string_clone(w->text);
+                               if (!w->data.s)
+                                       return SCF_DFA_ERROR;
+
+                               w->type = SCF_LEX_WORD_CONST_STRING;
+                               return SCF_DFA_CONTINUE;
+                       }
+               }
+       }
+
        return _expr_action_op(dfa, words, data, 1);
 }