• 分析牛人js版删除代码注释(状态机机制)


    花了几天时间看源码才弄清楚状态之间的转换关系,画了如下状态关系转换图:

    牛人源代码如下:

      1 function on_format(id) {
      2     var textarea = document.getElementById(id);
      3     var text = textarea.value;
      4     var obj = format_obj();
      5     obj.init();
      6     obj.g_trigraph_on = document.getElementById('format_trigraph').checked;
      7     len = text.length;
      8     for (var c = 0; c < len; ++c) {
      9         obj.deal(text.substring(c, c+1));
     10     }
     11     obj.deal('EOF');
     12     textarea.value = obj.g_output_string;
     13 }
     14 function format_obj() {
     15     return {
     16         s_normal:           0,
     17         s_char:             1,
     18         s_char_conv:        2,
     19         s_string:           3,
     20         s_string_conv:      4,
     21         s_linecomment:      5,
     22         s_linecomment_conv: 6,
     23         s_comment1:         7,
     24         s_comment:          8,
     25         s_commented1:       9,
     26         s_conv:             10,
     27         s_eof:              11,
     28 
     29 
     30         g_state:            0,
     31         g_conv_state:       0,
     32         g_convlinecnt:      0,
     33         g_trigraph:         0,
     34         g_output_string:    "",
     35 
     36         g_trigraph_on:      1,
     37 
     38         put:
     39             function(c) {
     40                 this.g_output_string += c;
     41             },
     42         init:
     43             function() {
     44                 this.g_state = this.s_normal;
     45                 this.g_conv_state = this.s_normal;
     46                 this.g_trigraph = 0;
     47                 this.g_output_string = ""
     48             },
     49 
     50         deal:
     51             function(c) {
     52                 if (this.g_trigraph_on) {
     53                     if (c == '?') { // trigraph pre process
     54                         if (this.g_trigraph < 2) {
     55                             this.g_trigraph++;
     56                             return 0;
     57                         }
     58                     } else if (this.g_trigraph == 2 && c == '/') {
     59                         c = '\\';
     60                         this.g_trigraph = 0;
     61                     } else if (this.g_trigraph > 0) {
     62                         var t = this.g_trigraph;
     63                         this.g_trigraph = 2;
     64                         while (t--) this.deal('?');
     65                         this.g_trigraph = 0;
     66                     }
     67                 }
     68                 if (this.g_conv_state == this.s_conv) { // '\' at end of line
     69                     this.g_conv_state = this.s_normal;
     70                     if (c == '\n') {
     71                         ++this.g_convlinecnt;
     72                         return 0;
     73                     } else {
     74                         if (this.g_state == this.s_comment1) {
     75                             this.put('/');
     76                             while (this.g_convlinecnt) --this.g_convlinecnt, this.put("\\\n");
     77                             this.put('\\');
     78                             this.g_state = this.s_normal;
     79                         } else if (this.g_state == this.s_commented1) {
     80                             this.g_state = this.s_comment;
     81                         }
     82                     }
     83                 } else if (c == '\\') {
     84                     if (this.g_state == this.s_comment1 || this.g_state == this.s_commented1) {
     85                         this.g_conv_state = this.s_conv;
     86                         return 0;
     87                     }
     88                 }
     89                 switch(this.g_state) {
     90                     case this.s_normal:
     91                         if (c == '\"') this.g_state = this.s_string, this.put(c);
     92                         else if (c == '\'') this.g_state = this.s_char, this.put(c);
     93                         else if (c == '/') this.g_state = this.s_comment1, this.g_convlinecnt = 0;
     94                         else if (c == 'EOF') this.g_state = this.s_eof;
     95                         else this.put(c);
     96                         break;
     97                     case this.s_char:
     98                         this.put(c);
     99                         if (c == '\'') this.g_state = this.s_normal;
    100                         else if (c == '\\') this.g_state = this.s_char_conv;
    101                         else if (c == 'EOF') this.g_state = this.s_eof;
    102                         break;
    103                     case this.s_char_conv:
    104                         this.put(c);
    105                         this.g_state = this.s_char;
    106                         break;
    107                     case this.s_string:
    108                         this.put(c);
    109                         if (c == '\"') this.g_state = this.s_normal;
    110                         else if (c == '\\') this.g_state = this.s_string_conv;
    111                         else if (c == 'EOF') this.g_state = this.s_eof;
    112                         break;
    113                     case this.s_string_conv:
    114                         this.put(c);
    115                         this.g_state = this.s_string;
    116                         break;
    117                     case this.s_linecomment:
    118                         if (c == '\\') this.g_state = this.s_linecomment_conv;
    119                         else if (c == '\n') this.g_state = this.s_normal, this.put(c);
    120                         else if (c == 'EOF') this.g_state = this.s_eof;
    121                         break;
    122                     case this.s_linecomment_conv:
    123                         if (c == '\\') ;
    124                         else if (c == 'EOF') this.g_state = this.s_eof;
    125                         else this.g_state = this.s_linecomment;
    126                         break;
    127                     case this.s_comment1:
    128                         if (c == '/') this.g_state = this.s_linecomment;
    129                         else if (c == '*') this.g_state = this.s_comment;
    130                         else if (c == 'EOF') this.g_state = this.s_eof;
    131                         else {
    132                             this.put('/');
    133                             while (this.g_convlinecnt) --this.g_convlinecnt, this.put("\\\n");
    134                             this.g_state = this.s_normal;
    135                             this.deal(c);
    136                         }
    137                         break;
    138                     case this.s_comment:
    139                         if (c == '*') this.g_state = this.s_commented1;
    140                         else if (c == 'EOF') this.g_state = this.s_eof;
    141                         break;
    142                     case this.s_commented1:
    143                         if (c == '/') this.g_state = this.s_normal, this.put(' ');
    144                         else if (c == 'EOF') this.g_state = this.s_eof;
    145                         else this.g_state = this.s_comment;
    146                         break;
    147                     case this.s_eof:
    148                         return -1;
    149                     default:
    150                         return -2;
    151                 }
    152                 return 0;
    153             },
    154     }
    155 }

    原文地址:http://blog.misakamm.org/p/395

  • 相关阅读:
    Java如何重置正则表达式的模式?
    Java如何创建用户自定义异常?
    Java如何使用线程异常?
    Java如何打印异常的堆栈?
    Java数组超出范围时如何处理多个异常?
    Java如何处理已检查异常?
    Java如何使用重载方法处理异常?
    Java如何使用catch来处理异常?
    Java如何处理空堆栈异常?
    Java如何处理运行时异常?
  • 原文地址:https://www.cnblogs.com/wadeyu/p/2784894.html
Copyright © 2020-2023  润新知