首页 > 编程语言 > 详细

踱步狼注释移除状态机算法2019.10

时间:2019-10-07 00:01:51      阅读:99      评论:0      收藏:0      [点我收藏+]

踱步狼注释移除,状态机算法:

switch(…):

case 1.转义字符为最优先处理。

入口条件:只要当前字符是,即必须进来处理。
紧跟在转义字符后面的char, 一般我们是无条件写回客户端的,
但如果此时是在处理,诸如块注释,单行注释,多行注释时,我们不写。
这边为了后面处理回车换行方便,对于\后面如果是xd和xa,我们也顺便处理,即写回xd,xa到客户端,
只要\后面还有一个字符,我们都无条件写回客户端。
这是转义符号的处理,最高优先级!

case 2:如果状态是行注释,但是当前字符既不是0xd,也不是0xa,或者是块注释,但当前字符又不是*

那我们直接丢弃

case 3:如是是在处理单引号,但是当前字符又不是’,

或者在处理双引号,但是当前字符又不是“,
或者在处理js正则,但是当前字符又不是/,
那我们全部写回客户端。

case 4.处理"

入口条件:当处在 js正则表达式, 单引号, #if 0注释, 行注释, 块注释, 状态下,不得进入处理。
且当前状态包含double_quotes_doing,或当前字符正好就是"则必须进来处理。
进入此入口的字符,一律写回客户端。
然后我们重新修改状态机标志:
如果之前没有置double_quotes_doing状态,则置该状态。
如果已置,并且当前字符就是",那么此时就是串的结束,我们清除double_quotes_doing状态标志。

case 5.处理’

处理同上。

, ", ’ 这三者都是比状态值优先级还要高的字符,所以优先处理。

case 6.处理#if 0

入口条件:state == if0_doing
当其后遇到#if时,我们要找到其对应的#endif,并累计出现的#if个数,设为KaTeX parse error: Expected ‘EOF‘, got ‘#‘ at position 10: sum 当其后遇到#?else时,我不知道这个是和上…sum值,如果此时$sum==1,那么是和#if是一伙的,
我们置标志为if0_else_doing,否则还是在#if 0中,即#if 0中存在其它#ifxx

当其后遇到#endif时,我们执行sum−−,如果减一后,发现sum--,如果减一后,发现sum,现sum==0,那么此处的#endif是顶层#if 0的匹配。那么我们置状态为normal_state,即状态机复位。
否则还是在#else中,即#else中存在其它#ifxx
if0_doing状态下遇到的所有字符,一个不少,全部丢弃。

case 7.处理#if 0对应的#else

入口条件:state == if0_else_doing,
当其后遇到#if时,KaTeX parse error: Expected ‘EOF‘, got ‘#‘ at position 21: … 此时我们不想再处理该状态下的#?else了,比如: #if 0…sum–,如果减一后,发现$sum==0,那么此处的#endif是顶层#if 0的匹配。那么我们置状态为normal_state,即状态机复位。
if0_else_doing状态下遇到的所有字符,一个不少,全部写回客户端。

case 8.处理,state == line_comment_start

入口条件:state == line_comment_start
这里是个while循环。
在循环里,我们找0xa或0xd,如果一直没找到,文档处理结束。因为全是单行注释啊。
如果找到,我们要判断换行符前面是不是,是的话,说明还在单行注释里面,继续while循环。
不是\的话,那么此处的0xa或0xd就是行注释结束。行注释代码全部忽略,置状态为normal_state,即状态机复位。

case 9.处理,state == block_comment_start

入口条件:state == block_comment_start
c++中的块注释不允许嵌套,所以很好处理。
我们找*/,找不到的话,说明全文中没有匹配的,那么我们将/*之后所有代码全部写回客户端。(不匹配的块注释,我们不视为注释。)
找到了,则块注释代码全部忽略,置状态为normal_state,即状态机复位。

下面都是对一些优先级较低的字符的处理。

case 10.处理/

入口条件:当前字符为/
如果这是文件末尾最后一个字符,则直接写回客户端。
如果下个字符也是/,则置标志 line_comment_start
如果下个字符是*,则置标志 block_comment_start
如果以上都不是,那么我们看看它是不是js正则。
如果已经置了正则标志,那么此处的/则是正则的结束,那我们就清掉js_regular_start标志。
否则我们要判断,此处是否为一个js正则的开始。
console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
s = s.replace( /’/g, “’’”);
k = /’/;
这些都是正则的合法表示,所以我的判断是
当前行中,/前如果是 ;, ", ‘, =, (, +, -, *, (忽略空串),或者什么都没有, 则此处的/为正则开始.(注意转义字符,/要跳过去,转义加换行也要处理下)

如 /43545\32+4’"5435#/,这个也是合法js正则,如有问题,敬请指正。
3 /‘/;
1 / 3

case 11.处理#

入口条件:当前字符为#, but 当处在 行注释, 状态下,不得进入处理。
当其后遇到if空格或if\t时,我们搜索这之后的第一个非空字符。如果该字符正好是0,那么我们就是找到了#if 0,置state=if0_doing, $sum=1
显然 #if
0

这种情况我们就没检查出来,不做任何处理,全部写回客户端。这样的#if 0代码,也基本上不会出现,出现了我们暂不做清理

踱步狼所有客户端均无需升级,即可使用最新注释清理算法。

感谢网友 洋芋炒土豆片片 提供的js正则bug, 让我们可以不断完善,做到更好。

踱步狼注释移除状态机算法2019.10

原文:https://www.cnblogs.com/strollingwolf/p/11628830.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!