AVR / 1_Uniproff / Doc1
.docИсходя из условия задания, на входе программы мы имеем текстовый файлик на языке C.
То, что в нем, в каждой строке может быть только по одному оператору и допустИм комментарий, мне кажется практически неважным.
На выходе программы, то есть функционал должен быть следующим:
-
печать текста исходного файла
-
анализ текста исходного файла по варианту задания
-
печать результата анализа
Вне зависимости от варианта задания существуют моменты, которые все же придется обрабатывать всем, кто выполняет эту задачу. Это связано с лексикой языка С, сюда относится обработка комментариев /*,*/,//; литералов ’’, ””; арифметических скобок () и программных блоков { и } (это типа операторов BEGIN и END в Паскале).
Для того чтобы упростить всю обработку и выполнять сложные проверки всего одним условием (например, если нам встретится ключевое слово IF, то чтобы принять его за команду - нужно сначала проверить не находится ли этот IF в комментариях или может быть это литерал) введем специальную переменную flag типа CHAR.
Несмотря но то, что тип символьный, мы ее будем использовать не как символ, а как байт данных. Как ты знаешь, каждый байт состоит их 8-ми бит, которые могут принимать значение только 0 или 1. Всего комбинаций 0 и 1 в 8-ми битах – 256; от 00000000 до 11111111, но сейчас это не важно пока. Мы придадим каждому биту свой смысл:
№ бита |
Операция |
Описание |
0 |
{
} |
Если встретится {, то установим этот бит в 1 и прибавим к переменной braces единицу. Если встретится }, то вычтем из braces 1, и если braces станет <=0, то этот бит сбросим в 0 |
1 |
( ) |
Аналогично с битом 0, только отслеживаем круглые скобки и изменяем переменную pars, а не braces |
2 |
“ “ |
Если встречается “ впервые, то устанавливаем бит в 1. Если бит установлен, но снова встретилась “, то сбрасываем его в 0. Исключением является комбинация \“ – в этом случае нужно обрабатывать и предыдущий символ \. Если он присутствует, то сбрасывать в 0 этот бит не нужно – это не конец литерала. |
3 |
‘ ‘ |
Аналогично с битом 2. |
4 |
/* */ |
При встрече последовательно символов /* устанавливаем бит в 1. При встрече */ - сбрасываем бит в 0. Вне зависимости от того сколько раз подряд встретится /*, первая же */ закроет комментарий. Облом. |
5 |
// [ENTER] |
Если встречается //, устанавливаем бит в 1. Если этот бит установлен и встретился символ конца строки, то сбрасываем бит. (в принципе можно сбрасывать всегда по концу строки) |
6 |
Резерв |
Не используется |
7 |
Резерв |
Не используется |
Теперь для точного определения является ли встретившийся IF оператором, можно проверить состояние флагов на текущий момент (когда считали оператор IF из файла):
IF (!(flag & 0x3C)) { // значит IF - оператор}