Чтение всего файла или отображение памяти будет быстрее, но может вызвать проблемы, если вы хотите, чтобы ваш язык мог #include
другие файлы, поскольку они также будут отображаться в памяти или считываться в память.
Функции stdio будут работать хорошо, потому что они обычно пытаются буферизовать данные для вас, но они также являются универсальными, поэтому они также пытаются искать шаблоны использования, которые отличаются от чтения файла от начала до конца, но этого не должно быть слишком много накладных расходов.
Хороший баланс - иметь большой кольцевой буфер (x * 2 * 4096 - хороший размер), который вы загружаете с данными файла, а затем читаете ваш токенизатор. Всякий раз, когда объем данных блока передается вашему токенизатору (и вы знаете, что он не будет возвращен), вы можете пополнить этот блок новыми данными из файла и обновить некоторую информацию о местоположении буфера.
Еще одна вещь, которую следует учитывать, - есть ли вероятность, что токенизатор когда-либо понадобится, чтобы его можно было использовать для чтения из канала или от человека, вводящего непосредственно какой-либо текст. В этих случаях ваши чтения могут возвращать меньше данных, чем вы запрашивали, не будучи в конце файла, а метод буферизации, о котором я упоминал выше, становится более сложным. Буферизация stdio хороша для этого, поскольку ее можно легко переключить на / из строчной или блочной буферизации (или без буферизации).
Использование gnu fast lex (flex, но не Adobe Flash) или аналогичного может значительно облегчить проблему со всем этим. Вам следует изучить возможность его использования для генерации кода C для вашего токенизатора (лексический анализ).
Что бы вы ни делали, вы должны попытаться сделать так, чтобы ваш код можно было легко изменить для использования другой формы функций просмотра и потребления следующего символа, чтобы, если вы передумаете, вам не пришлось бы начинать заново.
11.08.2010