[ Содержание ] [ Предыдущая ] [ Следующая ]
Эта глава содержит разнообразные подсказки по подготовке эффективных, легкоизменяемых и ясных спецификаций. Каждая секция более или менее независима.
Сложно предоставить реальные действия правилам, сохраняя читаемый файл спецификаций. Hижеследующий рекомендации по стилю во многом следуют Брайану Кернигану.
Пример в Приложении A написан в этом стиле, так же как и примеры в тексте статьи (где позволяет место). Пользователь должен сам решить эти стилистические вопросы; однако, центральной проблемой является читабельность правил невзирая на трясину кода действий.
Алгоритм, используемый парсером Yacc-а поощряет к так называемым лево-рекурсивным грамматическим правилам: правила формы
name : name rest_of_rule ;
Эти правила часто появляются при написании спецификаций последовательностей и списков:
list : item
| list ',' item
;
и
seq : item
| seq item
;
В каждом из этих случаев первое правило может быть понижено только для первого предмета, а второе - только для второго и всех последующих.
С право-рекурсивными правилами, такими как
seq : item
| item seq
;
парсер будет немного больше, а предметы будет видимы и понижаемы справа налево. Что более важно, внутреннему стеку парсера будет угрожать опасность переполнения при чтении очень длинных последовательностей. Таким образом, пользователь должен использовать левую рекурсию везде, где это приемлемо.
Стоит обсудить, имеет ли какой-нибудь смысл последовательность из нуля элементов, и если имеет, обсудим написание спецификации последовательности с пустым правилом:
seq : /* empty */
| seq item
;
Повторяем, первое правило всегда будет понижаться ровно один раз, перед тем, как прочитан первый предмет, а затем понижается первое правило один раз для каждого предмета. Разрешение пустыъ последовательностей часто ведет к увеличивающейся общности. Однако могут возникнуть конфликты, если Yacc-y зададут вопрос, какая пустая последовательность была увидена, когда он видел недостаточно, чтобы это знать.
Hекоторые лексические решения зависят от контекста. Hапример, лексический анализатор может захотеть удалить пустые пространства, но только не внутри строк в кавычках. Или имена могут записываться в таблицу символов в объявлениях, но не в выражениях.
Одним из способов обработки такой ситуации является создание глобального флага, опрашиваемого лексическим анализатором и устанавливаемый действиями. Hапример, предположим, что программа состоит из нуля или более объявлений, за которыми следуют ноль или более операторов. Рассмотрим:
%{
int dflag;
%}
... other declarations ...
%%
prog : decls stats
;
decls: /* empty */
{ dflag = 1; }
| decls declaration
;
stats: /* empty */
{ dflag = 0; }
| stats statement
;
... other rules ...
Флаг dflag при чтении операторов стал 0, а при чтении объявлений - 1, за исключением первого токена в первом операторе. Этот токен должен быть увиден парсером перед тем, как он может сказать, что секция объявлений закончилась и начались операторы. Во многих случаях, это единственное исключение не затрагивает лексическое сканирование.
Этот прием "черного хода" может быть использован во вред. Тем не менее, он преставляет собой способ, которым можно сделать вещи, которые сложно, если не совсем невозможно сделать по другому.
Hекоторые языки программирования позволяют пользователю использовать такие слова, как "if", которые обычно резервируются, как метки или имена переменных, при условии того, что такое использование не конфликтует с легальным использованием этих имен в языке программирования. Это крайне сложно сделать в рамках Yacc-а; сложно передать лексическому анализатору информацию о том, что "это появление 'if' есть ключевое слово, а это - переменная". Пользователь может совершить это, используя механизм, описанный в последней подсекции, но это трудно.
Hекоторое количество способов для облегчения этого обсуждаются. До тех пор, лучше, чтобы ключевые слова были зарезервированны; то есть запрещены для использования в качестве имен переменных. В любом случае, есть сильные стилистические причины, чтобы предпочесть именно это.
[ Содержание ] [ Предыдущая ] [ Следующая ]
c 1998-2000 SoloTony (Antonio Solo) | solotony@mail.ru |