Лексический анализ на языке C. Как сделать так, чтобы звездочка читалась и выводилась при обнаружении многострочного комментария?

Я работаю над программой лексического анализа, все работает нормально при обнаружении однострочного комментария. Это мой код для обнаружения однострочных комментариев.

//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.

Это содержимое файла, который я ввел:

#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
*/ }

Это мой текущий вывод


person Community    schedule 15.12.2017    source источник


Ответы (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;
}
person Jonathan Leffler    schedule 15.12.2017

этот фрагмент кода пропускает все символы, пока вы не обнаружите */, учитывая особые случаи, когда у вас есть такие окончания, как ***/:

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 */
person Luis Colorado    schedule 19.12.2017