C语言中的词法分析 - 如何在检测多行注释时读取并输出星号?

时间:2017-12-15 06:02:23

标签: c lexical-analysis lexical

我正在开发一个词法分析程序,在检测单行注释时一切正常。这是我的单行注释检测代码。

//Single Comment
if ((Current_Character == '/') && (fgetc(File_Input) == '/')){
    printf("%c", Current_Character);
    do{
        printf ("%c", Current_Character);
        Current_Character = fgetc (File_Input);
    }while(Current_Character != '\n');
    printf("\b \t | COMMENT\n", Current_Character);
    i = -1;
    Lexeme_Count++;
    Comment_Count++;
}

但是当我试图检测多行评论时,它得到了一个逻辑错误,它无法检测到开头的星号。这是我的多行注释检测代码:

//Multi-Line Comment
if((Current_Character == '/') && (fgetc(File_Input) == '*')){ 
    printf ("%c", fgetc(File_Input));
    do{
        printf ("%c", Current_Character);
        Current_Character = fgetc(File_Input);
    }while(Current_Character != '/');

    printf("\b | COMMENT\n", Current_Character);
    i = -1;
    Lexeme_Count++;
    Comment_Count++;
}

当前字符用于多行注释的第一个字符,即反斜杠,第二个字符是(fgetc(File_Input)(从文件获取下一个最新字符)用于打开askterisk。< / p>

这是我输入的文件的内容:

#include <conio.h>

{

int a[3],t1,t2;

t1=2; a[0]=1; a[1]=2; a[t1]=3;

t2=

-

(a[2]+t1*6)/(a[2]

-

t1);

if t2>5 then

print(t2);

else {

int t3;

t3=99;

t2=

-

25;

print(

-

t1+t2*t3); // this is a comment on 2 lines

} endif /* THIS IS A MUTLI-LINE COMMENT  ON 2 LINES
*/ }

This is my current output

2 个答案:

答案 0 :(得分:2)

你有:

if((Current_Character == '/') && (fgetc(File_Input) == '*')){ 
    printf ("%c", fgetc(File_Input));
    do{
        printf ("%c", Current_Character);
        Current_Character = fgetc(File_Input);
    }while(Current_Character != '/');

第一个printf()应该打印fgetc()返回的字符,您知道它是*,因此您可以使用putchar('*');或(如果您真的坚持)printf("%c", '*')printf("*")

请注意,潜伏着另一个问题:

x = a/b;

目前尚不清楚哪个评论区块首先执行,但在分区后它们都会丢失b。在C中的评论检测中还有许多其他细微之处 - 我不会用它们来解决所有问题,但足以说“在C中删除注释很难”(在C ++中更难)。您未解决的问题之一是意外的EOF(文件结束)。

您可能需要一个peek()函数来查看下一个字符而不使用它:

int peek(FILE *fp)
{
    int c = fgetc(fp);
    if (c != EOF)
        ungetc(c, fp);
    return c;
}

答案 1 :(得分:0)

此代码段会跳过所有字符,直到您检测到*/为止,考虑到您有***/等结尾的特殊情况:

int state = 0;
while((c = getchar()) != EOF) {
    switch(state) {
    case 0:
        switch(c) {
        case '*': state = 1; continue;
        default: /* process as comment char, but ignore */
            continue;
        } /* NOTREACHED */
    case 1:
        switch(c) {
        case '*': continue;
        case '/': /* end comment processing and return */
             state = 0;
             return COMMENT;  /* or continue, depending on scanner */
        default: /* any other char returns to state 0 */
             state = 0;
             /* process comment char */
             continue;
        } /* NOTREACHED */
    } /* switch */
} /* while */