缠绕问题

在实际开发中,哪怕是最简单的问题,通常也是缠绕的。这也是让程序员最为费心的问题之一。比如识别注释。注释以 /*开始,然后什么也不用管,直到遇到*/结束。自C++发明以来,又增加了//前导的单行注释。但是光根据这样的注释规则并不能识别注释,因为源程序中还有字符串。字符串中含有的注释符并不作为注释解释。所以识别注释必须同时识别字符串。字符串的格式是以"开始,然后是任意字符,直到再以引号结束。

为了避免过于繁琐,这里用lex文法来描述这个问题。lex的格式是:
  模式  识别动作

于是,是这样一些规则:
%%
“.*” {printf("{string-S}");ECHO;printf("{String-E}");}
/*.**/ {printf("/*…commentA…*/\n");}
//.**\n {printf("//…commentB…\n"); }
. {ECHO;}

为了防止与lex元符号冲突,实际的代码还需加上\转义符保护。像这样:

%%
\".*\"        {printf("{
    
    string}");ECHO;printf("{
    
    \\String}");}
\/\*.*\*\/    {
    
    printf("/*...commentA...*/\n");}
\/\/.*\n      {
    
    printf("//....commentB...\n"); }
.       {
    
    ECHO;}

%%
int yywrap()
{
    
    
        return 1;
}
int main()
{
    
    
        yylex();
        return 0;
}

这就基本可以用了。但是还不严格。这里注释不能越行,字符串里也不能含有引号。为了满足这两个要求,规则还要更复杂。

%%
\"([^\\"]|\\\")*\"        {printf("{
    
    string}");ECHO;printf("{
    
    \\String}");}
\/\*([^\*]|\*[^\/])*\*\/  {
    
    printf("/*...commentA...*/\n");}
\/\/.*\n               {
    
    printf("//....commentB...\n"); }
.                      {
    
    ECHO;}

%%
int yywrap()
{
    
    
        return 1;
}
int main()
{
    
    
        yylex();
        return 0;
}

这样就可以了。实际开发中遇到的缠绕问题会更复杂。但总是可以为每个状态节点分配一个不同的字符,从而转化为词法识别的问题。值得一提的是,
最后,软件设计的单位,和问题缠绕的粒度相关。

猜你喜欢

转载自blog.csdn.net/aaasssdddd96/article/details/113094652