分析牛人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

原文地址:https://www.cnblogs.com/wadeyu/p/2784894.html