Чтение онлайн

на главную - закладки

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

<Function> ::= <FuncName> '(' <MathExpr> {<ListSeparator> <MathExpr>} ')'

<FuncName> ::= 'sin' | 'cos' | 'ln' | 'log' | 'mean'

Отдельного комментария требует символ

<ListSeparator>
, разделяющий аргументы в функции. В Delphi, как и во многих других языках программирования, таким разделителем служит запятая. Но наша грамматика определена так, что запятая, в принципе, может служить разделителем целой и дробной части числа. Как уже говорилось, в этом случае может возникнуть неоднозначность в выражениях типа
f(1,5)
— это вызов функции
f
то ли с
одним аргументом 1.5, то ли с двумя аргументами 1 и 5. Чтобы избежать подобных неоднозначностей, в нашей грамматике разделителем аргументов будет символ, выбранный разделителем элементов списка (в русской локализации Windows это точка с запятой). Для корректной работы программы следите, чтобы на вашем компьютере разделители элементов списка, а также целой и дробной частей не оказались одинаковыми.

Особенность нашего нового синтаксиса в том, что он допускает любое число аргументов для любой функции, т.е., например, выражение

sin(0, 1, 2, 4)
синтаксически корректно (при условии, что разделителем элементов списка является запятая), хотя смысла это выражение не имеет. Можно было бы ввести отдельные синтаксические правила для функций с одним аргументом, с двумя аргументами и с произвольным числом аргументов, но такой подход встречается редко, т.к. обычно намного проще осуществить проверку на этапе семантического анализа (т.е. в нашем случае — при вычислении функции).

Для реализации новых синтаксических и семантических правил в код вносятся следующие изменения. Во-первых, появляются новые лексемы

ltLog
,
ltMean
и
ltListSeparator
, а соответствующие методы лексического анализатора модифицируются так, чтобы распознавать их. Во-вторых, модифицируется функция
Func
— она сначала вычисляет все аргументы, переданные функции, а потом проверяет, является ли количество аргументов допустимым, и если да, вычисляет требуемую функцию.

Для лучшего понимания работы лексического и синтаксического анализатора рекомендуем самостоятельно выполнить следующие задания (или хотя бы просто подумать, как их выполнить).

1. Расширить определение

<Expr>
таким образом, чтобы в нем можно было объединять несколько операций сравнения с помощью
or
,
and
,
xor
. При этом потребуется поддержка скобок, т.к. иначе анализатор во многих случаях не сможет отличить логические операторы с низким приоритетом от одноименных арифметических.

2. Изменить грамматику таким образом, чтобы имя функции стало идентификатором, а не зарезервированным словом.

3. Сделать комментарии вложенными. Сейчас в последовательности символов "{a{b}c}" считается, что комментарий заканчивается перед символом "с", т.к. лексический анализатор игнорирует все открывающие фигурные скобки в комментариях. Сделать так, чтобы комментарий считался закрытым только тогда, когда число закрывающих скобок сравняется с числом открывающих.

4. Добавить поддержку шестнадцатеричных целых констант. Для их записи использовать, как и в Delphi, символ "$", после которого должна идти последовательность из одной или нескольких шестнадцатеричных цифр.

5. Добавить возможность изменения приоритета операций с помощью не только круглых, но и квадратных скобок. Рассмотреть два варианта: когда круглые и квадратные скобки полностью взаимозаменяемы (т.е., например, допустимо выражение

2*(2+2]
) и когда закрывающая скобка должна быть такой же формы, как и открывающая.

Еще одна возможность, которую даст лексический анализатор — это обработка ошибок без исключений (иногда это может быть полезно). Пусть в анализаторе есть флаг, который взводится при обнаружении ошибки. Пока этот флаг сброшен, лексический анализатор работает обычным образом. Но если он

взведен, вызов функции
Next
не делает ничего, а свойство
Lexeme
всегда возвращает лексему
ltEnd
, независимо от того, дошел ли анализатор до конца строки или нет. После выполнения анализа проверяется этот флаг, и по его состоянию делается вывод о том, произошла ли ошибка. Соответственно, лексический анализатор должен иметь метод для установки этого флага извне. чтобы синтаксический анализатор мог его установить при обнаружении ошибки.

Примечание

Флагом можно сделать строковое поле, хранящее сообщение об ошибке. Пока эта строка пуста, флаг считается сброшенным, когда строка не пуста, считается, что флаг взведен. Таким образом, синтаксический анализатор формирует при необходимости сообщение об ошибке и помещает его в это поле лексического анализатора, и тот переходит в "ошибочный" режим. Так мы обеспечиваем и реализацию флага, и передачу сообщения об ошибке. В этом случае в структуре

ТLexeme
можно избавиться от поля
Pos
— позицию последней выделенной лексемы можно сделать внутренним полем лексического анализатора, и тот сам добавит номер позиции к сообщению, сформированному синтаксическим анализатором.

4.10. Еще немного теории

Теперь, познакомившись с синтаксическим анализом на практике, вернемся к теории и немного поговорим о типах грамматик и об альтернативных методах синтаксического анализа и вычисления выражений. Эти вопросы мы здесь рассмотрим только ознакомительно, а более детальное их описание можно найти в [6–8].

Грамматики языков по способу описания можно разделить на четыре типа, причем каждый следующий тип является подмножеством предыдущего.

1. Общие грамматики. Синтаксические правила в этих грамматиках имеют вид

a ::= b
, где
а
и
b
— произвольные цепочки из терминальных и нетерминальных символов (возможно, пустые). Единственное требование — хотя бы в одной из этих цепочек должен быть хотя бы один нетерминальный символ.

2. Контекстно-зависимые грамматики. Здесь правила имеют следующий вид

a<X>b ::= acb
, где
а
,
b
и
c
произвольные цепочки терминальных и нетерминальных символов,
<X>
— некоторый нетерминальный символ. Таким образом, символ
<X>
может заменяться на последовательность символов
c
только в контексте цепочек
a
и
b
.

3. Контекстно-свободные грамматики. Это контекстно-зависимые грамматики, из которых убран контекст, т.е. правила записываются в виде

<X> ::= с
. В контекстно-свободных грамматиках нетерминальный символ 
<X>
заменяется на цепочку
c
в любом контексте.

4. Регулярные (они же — автоматные) грамматики. Это контекстно-свободные грамматики, в которых запрещены любые формы рекурсивных определений.

Из этих определений легко сделать вывод, что в данной главе, пока мы не ввели в выражения скобки, наши грамматики относились к классу регулярных, а со скобками — к классу контекстно-свободных грамматик. Что же касается первых двух классов грамматик, то они неудобны ни для распознавания человеком, ни для написания анализаторов, поэтому данные грамматики применяются, в основном, только для описания естественных языков.

Поделиться:
Популярные книги

Адвокат Империи 3

Карелин Сергей Витальевич
3. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 3

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

Вонгозеро

Вагнер Яна
1. Вонгозеро
Детективы:
триллеры
9.19
рейтинг книги
Вонгозеро

Ведьма Вильхельма

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
8.67
рейтинг книги
Ведьма Вильхельма

Папина дочка

Рам Янка
4. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Папина дочка

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Как я строил магическую империю 7

Зубов Константин
7. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 7

Лучший из худший 3

Дашко Дмитрий
3. Лучший из худших
Фантастика:
городское фэнтези
попаданцы
аниме
6.00
рейтинг книги
Лучший из худший 3

Штурмовик из будущего 3

Политов Дмитрий Валерьевич
3. Небо в огне
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Штурмовик из будущего 3

Последний попаданец 2

Зубов Константин
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Последний попаданец 2

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье