Обнаружение ошибок и сообщение о них
В каждой фазе компиляции могут встретиться ошибки. Однако после их обнаружения необходимы определенные действия, чтобы продолжить компиляцию и выявить другие ошибки в исходной программе. Компилятор, который останавливается при обнаружении первой же ошибки, не настолько полезен в работе, каким мог бы быть.
В процессе синтаксического и семантического анализа обычно обрабатывается большая часть ошибок, обнаруживаемых компилятором. При лексическом анализе выявляются ошибки, при которых символы из входного потока не формируют ни один из токенов языка. Ошибки, при которых поток токенов нарушает структурные правила (синтаксис) языка, определяются в фазе синтаксического анализа. В процессе семантического анализа компилятор пытается обнаружить конструкции, корректные с точки зрения синтаксиса, но не имеющие смысла с точки зрения выполняемых операций, например попытка сложения двух идентификаторов, один из которых — имя массива, а второй — имя процедуры. Обработка ошибок в каждой фазе компиляции будет рассмотрена детальнее в разделах книги, посвященных каждой из фаз в отдельности.
Фазы анализа
В процессе трансляции изменяется внутреннее представление исходной программы. Для иллюстрации рассмотрим инструкцию.
На рис. 1.10 показано внутреннее представление инструкции после каждой фазы.
При лексическом анализе символы исходной программы считываются и группируются в поток токенов, в котором каждый токен представляет логически связанную последовательность символов— идентификатор, ключевое слово (if, while и т.п.), символ пунктуации или многосимвольный оператор типа:=. Последовательность символов, формирующая токен, называется лексемой токена.
Некоторые токены дополняются "лексическим значением". Например, когда найден идентификатор rate, лексический анализатор не только генерирует токен, скажем id, но и вносит лексему rate в таблицу символов, если ее там нет. Лексическое значение, связанное с этим появлением токена id, указывает на запись rate в таблице символов.
В этом разделе мы будем использовать обозначения idi, id2 и id3 для position, initial и rate, чтобы подчеркнуть отличие внутреннего представления идентификатора от последовательности символов, формирующих его. Инструкция (1.1) после лексического анализа выглядит так:
Нужно также создать токены для многосимвольного оператора:= и числа 60, но об этом — в главе 2, "Простой однопроходный компилятор". Детальнее лексический анализ рассматривается в главе 3, "Лексический анализ".
position:= initial + rate * 60
|
Синтаксический анализатор
|
Генератор промежуточного кода
|
temp1:= ittoreal(60);
temp2:= id3 * temp1;
temp3:= id2 * temp2;
id1:= temp3;
|
temp1:= id3 * 60;
id1:= id2 + temp1;
|
MOVF id3, R2
MOVF #60.0, R2
MOVF id2, R1
ADDF R2, R1
MOVF R2, id1
|
Таблица символов
| position
| …
|
| initial
| …
|
| rate
| …
|
|
|
|
Рис. 1.10. Трансляция инструкции
Вторая и третья фазы, синтаксический и семантический анализ, также были рассмотрены в разделе 1.2. При синтаксическом анализе на поток токенов налагается иерархическая структура, которую можно изобразить с помощью синтаксического дерева, приведенного на рис. 1.11а. Типичная структура данных для такого дерева показана на рис. 1.116. Ее внутренний узел представляет собой запись с полем для оператора и двумя полями с указателями на дочерние записи. Лист представляет собой запись с двумя или более полями (для идентификации токена в листе и записи информации о токене). Дополнительная информация о языковых конструкциях может содержаться в дополнительных полях записей для узлов. Синтаксический и семантический анализ будут детальнее рассматриваться в главах 4, "Синтаксический анализ", и 6, "Проверка типов", соответственно.
а) б)
Рис. 1.11. Структура данных (б) для дерева (а)
Дата добавления: 2015-11-30; просмотров: 48 | Нарушение авторских прав
mybiblioteka.su - 2015-2024 год. (0.006 сек.)