状态机示例-提取c程序注释

来源:互联网 时间:1970-01-01

# 状态机方法:
# 将C源码一个字符一个字符地送入状态机,如果在注释状态,则输出字符,否则跳过。
# 可能改变状态机状态的字符(事件)有 /、*、/n、其它字符,不同的状态识别不同的事件。
# 状态分为两类:
# 注释态-包括 slash、lc_comment、bc_comment、start几个小状态)
# 非注释态-只有text状态)。
#
# 状态机图:

 

 

此状态图可分解为2个状态图(或者说 由2个状态图合成),它们分别是:

 

 

 

1 只识别行注释的状态机(此图有点错误):2 只识别块注释的状态机:  

 

 

 

 

 

 

 

# // 行释
# /* 块注释 */

use strict;
use warnings;
use Encode;

my $cnt=0;        
# counter
my $str;
my $char;
my @chars;
my $fsm = "text";
# text
# slash
# lc_comment
# bc_comment
# start

while (<DATA>)
{
    
#print "$_";
    $cnt++;
    $str = decode("gb2312", $_);
    @chars = split //, $str;
    
#print "@chars";
    foreach $char (@chars)
    {
        
# print encode("gb2312", $char);
        $char = encode("gb2312", $char);       
        unless ($fsm eq "text")
        {
            print "$char";                
# comment    
        }
        
        if($fsm eq "text")
        {
            if($char eq "/")
            {
                $fsm = "slash";
                print "$char";            
# comment
            }
        }
        elsif($fsm eq "bc_comment")
        {
            if($char eq "*")
            {
                $fsm = "start";
            }
        }
        elsif($fsm eq "lc_comment")
        {
            if($char eq "/n")
            {
                $fsm = "text";
            }
        }
        elsif($fsm eq "slash")
        {
            if($char eq "/")
            {
                $fsm = "lc_comment";
            }
            elsif($char eq "*")
            {
                $fsm = "bc_comment";
            }
            else
            {
                $fsm = "text";
            }
        }
        elsif($fsm eq "start")
        {
            if($char eq "/")
            {
                $fsm = "text";
            }
            else
            {
                $fsm = "bc_comment";
            }
        }
        else
        {
            
# fsm error
        }
    }   
}
print "FSM:$fsm/n"; # comment-error if not "text"

__DATA__
行注释
// this is a line comment
 // this is a line /* comment * /

块注释(只占一行)
/* this is a block comment, in one line. */
/* this is a block comment, // in one line. */

块注释(跨行)
/*
this is a block comment, in multi-line.
*/

块注释中的//属于注释内容
/* this is a
block comment, but
// not a line comment */

块注释中的/*属于注释内容
/* this is a
/* block
/* comment */

块注释不能嵌套,如下面是非法的块注释
/*
illegal comment, because
/* nest... */
ing
*/

void SetPwm(unsigned long m) // 这个行注释与代码在同一行,再与块注释符混合 /* 用regExp难以识别它。 */
{
    printf("hi!");
}



相关阅读:
Top