了解用于检测C风格注释的状态机

时间:2012-03-03 19:21:43

标签: c enums comments

除了处理嵌套注释输入的方式外,我已经理解了该程序的全部功能。我不清楚State Star的功能。 c!='*'意味着什么?

假设输入为haha /* hello /*world */,则在第一个星形后如果出现斜线,则控制转换为PROGRAM状态。但是为什么它会占c!='*'

#include<stdio.h>
#include<conio.h>

void main()
{
enum{ /*Enum construct declares states */
    PROGRAM,
    SLASH,
    STAR,
    QUOTE,
    COMMENT,
    LITERAL
}state;

/* If state is quote then its either " or '*/

state = PROGRAM;

for(;;)
{
    int c = getchar();
    int quote = 0 ;

    switch(state) {
    case SLASH:
        /* Program text following a slash */
        if (c == '*') {
            state = COMMENT;
            break;
        }
        putchar('/');
        state = PROGRAM;

    case PROGRAM:
        /*Program Text*/
        if (c == '\''||c == '"') {
            state = QUOTE;
            quote = c;
            putchar(quote);
        }
        else if (c == '/')
            state = SLASH;
        else
            putchar(c);
        break;

    case COMMENT:
        /* Comment */
        if (c == '*')
            state = STAR;
        break;

    case STAR:
        /*Comment following a Star */
        if (c == '/')
            state = PROGRAM;
        else if (c != '*') {
            state = COMMENT;
            putchar(' ');
        }
        break;

    case QUOTE:
        /*Within a quote or a string */
        putchar(c);
        if (c == '\\')
            state = LITERAL;
        else if (c == quote)
            state = PROGRAM;
        break;

    case LITERAL:
        /*Within a literal having /*/
        putchar(c);
        state = QUOTE;
        break;
    }
}

printf("Can it handle this /* I wonder */");
getch();
}

3 个答案:

答案 0 :(得分:1)

这是为了应对这样的输入:

blah /* comment **/ blah
                 ^

如果您在我标记的位置恢复为COMMENT,那么您将不会寻找/以恢复为PROGRAM。您需要留在STAR

答案 1 :(得分:0)

如果您在州STAR并且找到STAR,那么您希望留在州STAR,以防您查看****/

之类的内容

答案 2 :(得分:0)

假设我们处于COMMENT状态(我们刚遇到'/ *'),此代码将继续循环,直到看到“*”。但是,如果我们在'*'之后看到'/',我们应该只离开COMMENT州。如果我们没有看到斜线,但是让自己回到评论状态,我们将跳过评论结束的情况,如'** /',因为我们不会继续尝试找到'/' STAR州。COMMENT。您将返回{{1}}并在下一次迭代中查看c =='/',跳过实际上注释结束的内容,然后将程序文本拖到下一个'* /'。