ОКРУЖЕНИЕ YACC'А
В результате обработки пользовательской спецификации утилитой yacc создается содержащий C-подпрограммы файл y.tab.c. Функция, которую порождает yacc, называется yyparse(); это функция с целочисленным результатом. Когда она выполняется, то периодически запрашивает у yylex(), функции лексического анализа, заданной пользователем (см. раздел ЛЕКСИЧЕСКИЙ АНАЛИЗ), входные лексемы. В конечном итоге либо обнаруживается ошибка, yyparse() возвращает значение 1 и восстановление после ошибки невозможно, либо лексический анализатор возвращает маркер конца и разбор успешно завершается. В этом случае yyparse() возвращает значение 0.
Чтобы получить работающую программу, пользователь должен сформировать для процедуры разбора определенное окружение. Например, как в любой программе на языке C, должна быть определена процедура с именем main(), вызывающая yyparse(). Кроме того, чтобы печатать сообщение об обнаруженной синтаксической ошибке, нужна процедура, называемая yyerror().
Эти две процедуры в той или иной форме должны быть заданы пользователем. Чтобы упростить на начальном этапе работу с yacc'ом, предоставляется библиотека с подразумеваемыми версиями функций main() и yyerror(). Библиотека задается при помощи аргумента -ly команды cc(1) или редактора связей. Исходный текст
main () { return (yyparse ()); }
и
#include <stdio.h>
yyerror (s) char *s; { (void) fprintf (stderr, "%s\n", s); }
демонстрирует банальность этих предопределенных программ. Аргумент у функции yyerror() - текст, содержащий сообщение об ошибке, обычно syntax error. В реальных приложениях чаще выполняются более сложные действия. Обычно программа подсчитывает номер входной строки и печатает его вместе с сообщением об обнаружении синтаксической ошибки. Внешняя переменная целого типа yychar содержит номер предварительно просмотренной лексемы на момент обнаружения ошибки. Это может представлять некоторый интерес для формирования лучшей диагностики. Так как функция main()
вероятнее всего задается пользователем (необходимо прочесть аргументы и т.п.), yacc-библиотека полезна только в маленьких проектах или на ранних этапах разработки больших.
Внешняя переменная целого типа yydebug обычно устанавливается равной 0. Если она имеет ненулевое значение, процедура разбора будет выдавать подробное описание действий, включающее сообщение о прочитанных входных символах и выполняемых операциях раз- бора. Значение этой переменной можно переустановить, используя отладчик sdb(1).