[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]  


9. Отладка вашего анализатора

Если грамматика Bison компилируется правильно, но при запуске делает не то, чего вы хотите, помочь вам выяснить, почему это происходит, может средство трассировки анализатора yydebug.

Чтобы включить компиляцию возможностей трассировки, вы должны определить макрос YYDEBUG как ненулевое значение при компиляции анализатора. Вы можете использовать параметр компилятора `-DYYDEBUG=1' или поместить `#define YYDEBUG 1' в секцию объявлений C файла грамматики (см. раздел 4.1.1 Секция объявлений C). Вместо этого можно использовать параметр `-t' при запуске Bison (см. раздел 10. Вызов Bison) или объявление %debug (см. раздел 4.7.8 Обзор объявлений Bison). Мы полагаем, что вы всегда будете определять YYDEBUG, так что отладка всегда будет возможна.

Средство трассировки выводит собщения, используя макровызовы вида YYFPRINTF (stderr, формат, аргументы, где формат и аргументы -- обычные формат и аргументы функции printf. Если вы определяете YYDEBUG как ненулевое значение, но не определяете YYFPRINTF, автоматически включается <stdio.h> и YYFPRINTF определяется как fprintf.

После того, как вы скомпилировали программу с использованием средств трассировки, чтобы потребовать выполнения трассировки, нужно поместить ненулевое значение в переменную yydebug. Вы можете сделать это, заставив это делать код на C (возможно, в функции main), или изменить это значение отладчиком C.

Каждый шаг, предпринимаемый анализатором, когда yydebug не равно нулю, даёт одну или две строки информации о трассировке, выдаваемой на stderr. Сообщения трассировки говорят о следующем:

Для осмысления этой информации полезно обратиться к файлу листинга, выдаваемому параметром Bison `-v' (см. раздел 10. Вызов Bison). Этот файл показывает смысл каждого состояния в терминах позиций в различных правилах, а также, что будет происходить в каждом состоянии при каждой возможной входной лексеме. Читая последовательные сообщения трассировки, вы можете видеть, что анализатор функционирует в соответствии с его спецификацией в файле листинга. В конце концов вы дойдёте до места, где происходит что-либо нежелательное, и увидите, какие части грамматики несут за это ответственность.

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

Отладочная информация обычно содержит тип каждой прочитанной лексемы, но не её семантическое значение. Вы можете также определить макрос YYPRINT, чтобы предоставить способ вывода значения. Если вы определяете YYPRINT, он должен принимать три аргумента. Анализатор будет передавать ему стандартный поток ввода/вывода, числовой код типа лексемы и значение лексемы (из yylval).

Приведём пример YYPRINT, подходящего для многофункционального калькулятора (см. раздел 3.5.1 Объявления mfcalc): #define YYPRINT(file, type, value) yyprint (file, type, value) static void yyprint (FILE *file, int type, YYSTYPE value) { if (type == VAR) fprintf (file, " %s", value.tptr->name); else if (type == NUM) fprintf (file, " %d", value.val); }


[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]