
- •Упрощенная модель компилятора. Проходы компилятора.
- •3. Проходы компиляторов
- •Задача идентификации. Транслитерация.
- •Методы лексического анализа.
- •Использование автомата для решения задачи идентификации слов (различные классы лексем).
- •Контекстно-свободные грамматики. Основные определения.
- •Задание кс грамматики. Способы задания грамматик: синтаксические диаграммы, форма Бекуса-Наура.
- •Выводы. Деревья синтаксического разбора.
- •Праволинейная грамматика.
- •Лишние нетерминалы.
- •Атрибутные грамматики. Наследуемые и синтезируемые атрибуты.
- •1 Синтезируемые атрибуты
- •2 Наследуемые атрибуты
- •Использование автоматов с магазинной памятью для нисходящего разбора.
- •Общие правила построения нисходящего распознающего автомата.
- •Распознающий автомат для s - грамматик.
- •Ll(1) - грамматики. Множество выбора.
- •Метод рекурсивного спуска.
- •Обработка ошибок при нисходящем разборе.Обнаружение и нейтрализация ошибок.
- •Восходящие методы синтаксического разбора. Метод перенос-свертка.
- •Задачи семантического анализа. Семантические соглашения.
Использование автомата для решения задачи идентификации слов (различные классы лексем).
Пара, класс символа и его значение, поступают на вход сканера, который выбирает для анализа тот ее элемент, который наиболее удобен в данный момент. Например, при анализе идентификатора удобнее манипулировать понятием "буква", тогда как при анализе действительного числа можно сразу смотреть значение буквы "E" или "e", означающей начало порядка. Следует также отметить, что во всех дальнейших рассуждениях будем считать, что понятия "буква" и "цифра" являются терминалами, как полученные в транслитераторе до начала лексического анализа. В предыдущей трактовке эти понятия считались нетерминальными символами.
Классификация лексем
Пусть
дан алфавит: {a,
b,
c,
i,
l,
},
где
- символ окончания цепочки (обобщенный
символ разделителя)
Задана грамматика: call, all, ill, ball, cab. Пусть ε – начальное состояние. Ошибочное состояние будем обозначать: 100
Способ 1: Таблица переходов
|
a |
B |
C |
I |
l |
|
Ε |
‘a’ |
‘b’ |
‘c’ |
‘i' |
100 |
|
‘a’ |
100 |
100 |
100 |
100 |
‘al’ |
|
‘al’ |
100 |
100 |
100 |
100 |
‘all’ |
|
‘all’ |
100 |
100 |
100 |
100 |
100 |
Распознали слово |
‘c’ |
‘ca’ |
100 |
100 |
100 |
100 |
|
‘ca’ |
100 |
‘cab’ |
100 |
100 |
‘cal’ |
|
‘cab’ |
100 |
100 |
100 |
100 |
100 |
Распознали слово |
‘cal’ |
100 |
100 |
100 |
‘call’ |
100 |
|
‘call’ |
100 |
100 |
100 |
100 |
100 |
Распознали слово |
… |
|
|
|
|
|
|
Можно сохранять только значащие переходы
Достоинство: простота
Недостатки:
Неэффективное использование памяти
Невозможность расширения
Первый недостаток можно устранить, если хранить не таблицу переходов, а список.
Способ 2: Список переходов
Ε |
a |
10 |
|
12 |
|
|
"all" |
|
b |
20 |
|
|
100 |
|
|
|
c |
30 |
|
20 |
A |
21 |
|
|
i |
40 |
|
|
100 |
|
|
|
100 |
|
|
21 |
L |
22 |
|
10 |
l |
11 |
|
|
100 |
|
|
|
100 |
|
|
22 |
L |
23 |
|
11 |
l |
12 |
|
|
100 |
|
|
|
100 |
|
|
23 |
|
|
"ball" |
|
|
|
|
|
100 |
|
|
Преимущество: меньшее использование памяти
Способ 3: Список переходов (более оптимальный вариант)
ε |
a |
10 |
|
10 |
L |
|
|
20 |
a |
|
|
30 |
a |
31 |
|
31 |
l |
|
|
b |
20 |
|
|
L |
|
|
|
l |
|
|
|
b |
|
|
|
l |
|
|
c |
30 |
|
|
|
"all" |
|
|
l |
|
|
|
|
"cab" |
|
|
|
"call" |
|
i |
40 |
|
|
100 |
|
|
|
|
"ball" |
|
|
100 |
|
|
|
100 |
|
|
100 |
|
|
|
|
|
|
|
100 |
|
|
|
|
|
|
|
|
|
Преимущество: легко расширяемый автомат
Недостаток: полезен только тогда, когда слова начинаются с разных букв
Проблема: есть состояние, которое соответствует начальному состоянию, где перечислены все буквы, с которых могут начинаться слова.
Арифметические операции
К арифметическим операциям можно отнести и зарезервированные слова: div, not, and, xor, or.
+ - * /
< > =
<= >= <>
Автомат: {<, >, =, }
|
|
< |
> |
= |
|
|
ε |
“<” |
“>” |
“=” |
|
1 |
< |
100 |
“>” |
“=” |
“<” |
2 |
<= |
100 |
100 |
100 |
“<=” |
3 |
<> |
100 |
100 |
100 |
“<>” |
4 |
> |
100 |
100 |
“=” |
“>” |
5 |
>= |
100 |
100 |
100 |
“>=” |
6 |
= |
100 |
100 |
100 |
“=” |
Правила
Обозначения:
* - повторяется некоторое количество раз
? – может быть либо один раз, либо ни разу (для обозначения регулярной цепочки)
( )? и [ ] – эквивалентны
[+|-]digit*
Примеры: +1, -1, 0, +10
num digit*(.digit*)?(E(+|-)?digit)?
Пример: 10.875E-25
id letter((letter|digit)*)? // для идентификаторов