花了几天时间看源码才弄清楚状态之间的转换关系,画了如下状态关系转换图:
牛人源代码如下:
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