#c #compiler-construction #eof #lexical-analysis
#c #компилятор-построение #eof #лексический анализ
Вопрос:
Как я должен сигнализировать EOF при чтении в файле на C ? Я пишу сканер прямого кодирования, как часть проекта компилятора, который считывает файл и разбивает его на токены для языка.
Я должен прочитать всю программу, удалить комментарии и сжать пробелы. Затем поместите полученную программу по символам в буфер с максимальным размером 1024 символа. Поэтому, когда мы опустеем, мы будем пополнять буфер или что-то еще.
Чтобы открыть файл, я написал следующее:
// Open source file.
source_file.open (filename);
if (source_file.fail()) {
// Failed to open source file.
cerr << "Can't open source file " << *filename << endl;
buffer_fatal_error();
Чтобы заполнить буфер, я хочу использовать цикл while и выполнить итерацию, например
int i = 0;
// Iterate through the whole file
while(source_file.at(i) != EOF)
{
// If not a tab or newline add to buffer
if (source_file.at(i) != "n" || source_file.at(i) != "t")
{
bufferList.add(source_file.at(i));
}
i ;
}
Есть ли способ сигнализировать EOF подобным образом для файла, который я открываю?
Это более или менее общий план того, что нужно делать. Мне нужно будет выяснить, как пополнить буфер, когда он будет пуст, или использовать двойную буферизацию. Мне также нужно выяснить, как удалить комментарий, который начинался #
бы с. Например # This is a comment
. После этого мой сканер увидит #
и удалит все, пока не получит следующий символ новой строки.
Комментарии:
1. EOF означает, что вы просто ищете нулевое значение в конце файла
2. Попробуйте использовать
std::vector<char>
для буфера иistream::read()
считывать данные в буфер.3. @ThomasMatthews
istream::read()
удалит пробелы?4. @ThomasMatthews кроме того, мы можем принимать только 1024 символа за раз, поэтому нам придется периодически пополнять буфер. Не уверен, как сигнализировать об этом.
5.
istream::read
Не удаляет пробелы. Вы можете сделать это при разборе буфера. Поместитеistream::read
вwhile
выражение.
Ответ №1:
Попробуйте это:
char c;
std::vector<char> buffer(1024);
while (source_file.get(c))
{
if ((c != 'n') || (c != 't'))
{
buffer.push_back(c);
}
}
Стандартный метод чтения данных заключается в проверке результата операции чтения в while
цикле.
Для чтения блока вы могли бы сделать что-то вроде этого:
char buffer[1024];
while (source_file.read(buffer, sizeof(buffer))
{
// Process the buffer here
}
Вы также должны использовать std::istream::gcount()
, чтобы получить количество символов, считанных из файла, поскольку оно может быть меньше размера буфера.
Комментарии:
1. Я понимаю верхнюю часть этого ответа. Но имеет ли значение, что можно сказать
source_file.get(c)
по сравнению сsource_file.at(c)
, или они одинаковы? Я думаю, я просто запутался в том, чтоread
делает и как использовать это для удаления комментариев и сжатия пробелов.2. Извините, но я не вижу
at()
метода дляstd::istream
.