Мне нужно исправить эти две проблемы в программе.Основываясь на входных данных, мне нужно исправить код, чтобы получить желаемый результат - PullRequest
0 голосов
/ 01 марта 2019
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void handle(FILE *np)// this is to handle newline characters
{
    putc('\n', np);

}
/* skip a C multi-line comment, return the last byte read or EOF */
int m_cmnt(FILE *fp, int *lineno_p) {
FILE *np = stdout;
int prev, ch, replacement = ' ';
for (prev = 0; (ch = getc(fp)) != EOF; prev = ch) {
    if (prev == '\\' && ch == 'n') {
        replacement = '\n';
        ++*lineno_p;
        }
    if (prev == '*' && ch == '/')
        return replacement;
    }

return EOF;
}

int main(int argc, char *argv[]) {
FILE *fp = stdin, *np = stdout;
int ch,prev;
bool String = 0;
const char *filename = "<stdin>";
int lineno = 1;

fp = fopen(filename, "r");
np = fopen(argv[2], "w");

if (argc > 1) {
    if ((fp = fopen(filename = argv[1], "r")) == NULL) {
        fprintf(stderr, "Cannot open input file %s: \n",
                filename);
        exit(EXIT_FAILURE);
    }
}
if (argc > 2) {
    if ((np = fopen(argv[2], "w")) == NULL) {
        fprintf(stderr, "Cannot open output file %s: \n",
                argv[2]);
        exit(EXIT_FAILURE);
    }
}

while ((ch = getc(fp)) != EOF) {
    if (ch == '\n')
        lineno++;
    /* file pointer currently not inside a string */
    if (!String) {
        if (ch == '/') {
            ch = getc(fp);
            if (ch == '\n')
                lineno++;
            if (ch == '*') {
                int startline = lineno;
                ch = m_cmnt(fp, &lineno);
                if (ch == EOF) {
                    fprintf(stderr, "%s:%d: error: unterminated comment started on line %d\n",
                            filename, lineno, startline);
                            exit(EXIT_FAILURE);
                    break;
                }
                putc(ch, np);
            } else {
                putc('/', np);
                putc(ch, np);
            }
        }
         else if ( ch=='\\')/*to handle newline character*/
            {
                prev=ch ;
                ch= getc(fp) ;
                switch(ch)
                {
                    case 'n'  :
                                handle(np);
                                 break ;
                    /*default   :
                                 putc(prev , np) ;
                                 putc(ch , np) ;
                                 break ;*/
                }
            }
        else {
            putc(ch, np);
        }
    } else {
        putc(ch, np);
    }
    if (ch == '"' || ch == '\'')
        String = !String;
}
fclose(fp);
fclose(np);
//remove(arr[1]);
//rename("temp.txt", arr[1]);
return EXIT_SUCCESS;
}

Я работаю над этим проектом уже почти неделю.Я задавал много вопросов на этом сайте, чтобы помочь мне получить желаемый результат. Основы этой программы - удалить многострочные комментарии из исходного файла и записать остальные в некоторый выходной файл. Также необходимо игнорировать любую вещь, которая находится внутри строкового литерала или символьного литерала (например, экранированные символы). Теперь я пришел, чтобы завершить это, но мне все еще нужно добиться этих двух выходных данных, показанных ниже

INPUT1 = //*SOMECOMMENT*/  
OUTPUT1 = /
INPUT2 = "this \"test"/*test*/
OUTOUT2 = "this \"test"

Текущий (ошибочный) вывод показан ниже

INPUT1 = //*SOMECOMMENT*/  
OUTPUT1 = //*SOMECOMMENT*/    This is wrong.
INPUT2 = "this \"test"/*test*/
OUTOUT2 = "this \"test"/*test*/   This is also wrong.

Программа не работает для случая, когда комментарий идет после косой черты (/) и второго сбояПрограмма не игнорирует escape-символ внутри строки или символьного литерала.Мне нужно исправить эти две проблемы, пожалуйста.

1 Ответ

0 голосов
/ 04 марта 2019

Если ваша проблема в том, что вы хотите прочитать входной поток символов, разделить этот поток на токены, а затем испустить только подмножество этих токенов, я думаю, что Lex - это именно тот инструмент, который вам нужен.ищу.

Если я правильно понимаю ваш комментарий, файл, который вы пытаетесь прочитать и преобразовать, сам по себе является Си-кодом.Поэтому вам нужно будет создать определение Lex для правил языка C.

Быстрый поиск показал эту спецификацию Lex грамматики ANSI C .Я не могу ручаться за его точность или говорить с его лицензированием.На первый взгляд кажется, что он поддерживает только C89.Но, вероятно, достаточно указать вам правильное направление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...