Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Debugging

Boost , ,

Debugging

Природа Spirit сверху вниз позволяет легко отлаживать генерируемый парсер с помощью стандартного отладчика в комплекте с компилятором C++, который мы используем. С рекурсивным спуском, прохождение разбора использует аппаратный стек через механизмы вызова функций C++. Нет никаких сложно отладочных таблиц или государственных машин, которые заслоняют логический поток анализа. След стека, который мы видим в отладчике, точно следует иерархической структуре грамматики.

Поскольку любое производственное правило может инициировать прохождение разбора, гораздо легче определить ошибки, сосредоточившись на одном или нескольких правилах. Для относительно сложных задач разбора, так же, как мы пишем надежные программы на C++, рекомендуется разрабатывать грамматику итеративно на основе каждого модуля, где каждый модуль является небольшим подмножеством полной грамматики. Таким образом, мы можем тестировать отдельные модули по частям, пока не достигнем самого верхнего модуля. Например, при разработке языка сценариев мы можем начать с выражений, затем перейти к утверждениям, затем функциям, вверх, пока у нас не будет полной грамматики.

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

Debugging Macros

BOOST_SPIRIT_ASSERT_EXCEPTION

Дух содержит утверждения, которые могут активироваться, когда дух используется неправильно. По умолчанию эти утверждения используют макрос утверждения из стандартной библиотеки. Если вы хотите, чтобы дух бросил исключение, определитеBOOST_SPIRIT_ASSERT_EXCEPTIONк названию класса, который вы хотите бросить. Конструктор этого класса будет переданconst char*строгая версия файла, строка и условие утверждения, когда он брошен. Если вы хотите полностью отключить утверждение,#define NDEBUG.

BOOST_SPIRIT_DEBUG

Определите это, чтобы обеспечить отладку.

При включенной отладке в ключевых точках процесса разбора генерируется специальный выход с использованием стандартного оператора выводаоператора.<<сBoost_SPIRIT_DEBUG_OUT(по умолчаниюstd::cout, см. ниже) как его левый операнд.

In order to use spirit's debugging support you must ensure that appropriate overloads of operator<< taking BOOST_SPIRIT_DEBUG_OUT as its left operand are available. The expected semantics are those of the standard output operator.

These overloads may be provided either within the namespace where the corresponding class is declared (will be found through Argument Dependent Lookup) or [within an anonymous namespace] within namespace boost::spirit, so it is visible where it is called.

Note in particular that when BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES is set, overloads of operator<< taking instances of the types used in closures as their right operands are required.

You may find an example of overloading the output operator for std::pair in a related FAQ entry.

По умолчанию, если определен макросBOOST_SPIRIT_DEBUG, генерируется весь доступный выход отладки. Чтобы точно настроить количество сгенерированного текста, вы можете определитьBOOST_SPIRIT_DEBUG_FLAGSпостоянная равна комбинации следующих флагов:

Available flags to fine tune debug output
BOOST_SPIRIT_DEBUG_FLAGS_NODES

печатная информация об узлах (общий для всех парсеров)

BOOST_SPIRIT_DEBUG_FLAGS_TREES

Печать информации о деревьях-парсе и AST (общий для всех парсеров деревьев)

BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES print information about closures (general for all parsers with closures)
BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR

Распечатать информацию изesc_char_parser

BOOST_SPIRIT_DEBUG_FLAGS_SLEX print information out of the SLEX parser

BOOST_SPIRIT_DEBUG_OUT

Определите это, чтобы перенаправить распечатку диагностики отладки в другое место (например, файл или поток).[править править код]

BOOST_SPIRIT_DEBUG_TOKEN_PRINTER

BOOST_SPIRIT_DEBUG_TOKEN_PRINTERМакро позволяет переопределить способ печати символов в потоке.

ЕслиBOOST_SPIRIT_DEBUG_OUTимеет типStreamT, тип символаCharTиBOOST_SPIRIT_DEBUG_TOKEN_PRINTERопределяется какfoo, он должен быть совместим с этим использованием:

    foo(StreamT, CharT)

По умолчанию принтер требует определения оператора[StreamT, CharT]. Дополнительно, еслиCharTконвертируется в обычный тип символовchar,wchar_tилиint, он печатает управляющие символы в дружественной манере (например, когда он получает'n', он фактически печатает\иn, вместо новой строки).

BOOST_SPIRIT_DEBUG_PRINT_SOME

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

BOOST_SPIRIT_DEBUG_TRACENODE

По умолчанию все узлы парсера отслеживаются. Эта константа может быть использована для переопределения этого по умолчанию. Если это1истинно, то трассировка включена по умолчанию, если эта постоянная0ложно, трассировка отключена по умолчанию. Эта константа препроцессора устанавливается на1истиннопо умолчанию.

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

BOOST_SPIRIT_DEBUG_NODE(p)

Определите это, чтобы напечатать некоторые отладочные диагностики для парсера. Этот макро

  • Регистрирует имя парсера для отладки
  • Включает/отключает трассировку для парсера в зависимости отBOOST_SPIRIT_DEBUG_TRACENODE

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

Пост-парс: После разбора правила печатается имя правила, за которым следует заглянуть в данные в текущем положении итератора. Здесь'/'перед именем правила знаменует успешный матч, а'#'перед именем правила знаменует неудачный матч.

Ниже приведены синонимыBOOST_SPIRIT_DEBUG_NODE

  1. BOOST_SPIRIT_DEBUG_RULE
  2. BOOST_SPIRIT_DEBUG_GRAMMAR

BOOST_SPIRIT_DEBUG_TRACE_NODE(p, flag)

BOOST_SPIRIT_DEBUG_NODE. Кроме того, позволяет проводить выборочную отладку. Это полезно в ситуациях, когда мы хотим отлаживать только ручной набор узлов.

Ниже приведены синонимыBOOST_SPIRIT_DEBUG_TRACE_NODE

  1. BOOST_SPIRIT_DEBUG_TRACE_RULE
  2. BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR

BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(p, name, flag)

BOOST_SPIRIT_DEBUG_NODE. Дополнительно допускается выборочная отладка и позволяет указать имя, используемое при отладке распечатки. Это полезно в ситуациях, когда мы хотим отладить только ручной набор узлов. Имяможет быть переопределено в ситуациях, когда параметр парсера не отражает имя парсера для отладки.

Ниже приведены синонимыBOOST_SPIRIT_DEBUG_TRACE_NODE

  1. BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME
  2. BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME

Вот оригинальный калькулятор с включенными функциями отладки:

    #define BOOST_SPIRIT_DEBUG  ///$$$ DEFINE THIS BEFORE ANYTHING ELSE $$$///
    #include "boost/spirit/include/classic.hpp"
    /***/
    /*** CALCULATOR GRAMMAR DEFINITIONS HERE ***/
    BOOST_SPIRIT_DEBUG_RULE(integer);
    BOOST_SPIRIT_DEBUG_RULE(group);
    BOOST_SPIRIT_DEBUG_RULE(factor);
    BOOST_SPIRIT_DEBUG_RULE(term);
    BOOST_SPIRIT_DEBUG_RULE(expr);

Обязательно добавьте макросывнутриконструктора определения грамматики. Вот пример сеанса с калькулятором.

    Type an expression...or [q or Q] to quit
    1 + 2
    grammar(calc):	"1 + 2"
      rule(expression):	"1 + 2"
        rule(term):	"1 + 2"
          rule(factor):	"1 + 2"
            rule(integer):	"1 + 2"
    push	1
            /rule(integer):	" + 2"
          /rule(factor):	" + 2"
        /rule(term):	" + 2"
        rule(term):	"2"
          rule(factor):	"2"
            rule(integer):	"2"
    push	2
            /rule(integer):	""
          /rule(factor):	""
        /rule(term):	""
    popped 1 and 2 from the stack. pushing 3 onto the stack.
      /rule(expression):	""
    /grammar(calc):	""
    -------------------------
    Parsing succeeded
    result = 3
    -------------------------

Мы напечатали в "1 + 2". Обратите внимание, что есть две успешные ветви от верхнего правилаexpr. Красный текст генерируется семантическими действиями парсера, в то время как остальные генерируются отладкой-диагностикой наших правил. Обратите внимание, как первоецелое числоправило взяло "1", первыйтерминправило взяло "+", и, наконец, второецелое числоправило взяло "2".

Обратите внимание на особое значение первых символов, появляющихся на печатных линиях:

  • один'/'начинает строку, содержащую информацию об успешно подобранном парсерном узле (правило<>,грамматика<>илиподправило<>
  • Один'#'начинает строку, содержащую информацию о неисправном парсерном узле.
  • Один'^'начинает линию, содержащую первый элемент (возвратное значение/синтезированный атрибут) закрытия успешно подобранного парсерного узла.

Проверьтеcalc_debug.cpp, чтобы увидеть отладку в действии.



Статья Debugging раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:45:23/0.0073959827423096/1