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

Error Handling

Boost , ,

Error Handling

Механизм обработки исключений C++ идеально подходит для обработки ошибок в рамках. Представьте себе полный парсер как лабиринт. На каждой ветви вход диктует, куда мы повернем. При неправильном подходе мы можем зайти в тупик. Если мы когда-нибудь достигнем его, это будет пустой тратой времени, чтобы вернуться туда, откуда мы пришли. Вместо этого мы поставляем охрану в стратегические точки. Помимо определенного пункта, мы помещаем парсерные утверждения в места, куда не разрешается идти.

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

Parser Errors

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

    template <typename ErrorDescrT, typename IteratorT = char const*>
    class parser_error 
    {
    public:
        parser_error(IteratorT where, ErrorDescrT descriptor);
        IteratorT where;
        ErrorDescrT descriptor;
    };

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

Семантические действия могут свободно отбрасывать парсерные исключения, когда это необходимо. Функция полезностиthrow_может быть вызвана. Эта функция создает и выбрасываетparser_errorзаданный итератор и дескриптор ошибок:

    template <typename ErrorDescrT, typename IteratorT>
    void throw_(IteratorT where, ErrorDescrT descriptor);

Parser Assertions

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

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

Examples

    enum Errors
    {
        program_expected,
        begin_expected,
        end_expected
    };
    assertion<Errors> expect_program(program_expected);
    assertion<Errors> expect_begin(begin_expected);
    assertion<Errors> expect_end(end_expected);

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

The assertive_parser

Actually, the expression expect_end(str_p("end"))creates an assertive_parser object. An assertive_parser is a parser that throws an exception in response to a parsing failure. The assertive_parser throws a parser_error exception rather than returning an unsuccessful match to signal that the parser failed to match the input. During parsing, parsers are given an iterator of type IteratorT. This is combined with the error descriptor type ErrorDescrT of the assertion (in this case enum Errors). Both are used to create a parser_error<Errors, IteratorT> which is then thrown to signal the exception.

Преддекларированный объект утвержденияexpect_endможет теперь использоваться в грамматике в качестве оберток вокруг парсеров. Например:

    expect_end(str_p("end"))

Это приведет к исключению, если он не увидит "end" из ввода.

The Guard

Охранаиспользуется для улавливания определенного типаparser_error. Продолжим наш предыдущий пример:

    guard<Errors> my_guard;

Ошибки, в этом примере тип дескриптора ошибок, который мы хотим обнаружить. Это тот же список, что и выше.my_guardтеперь можно использовать в грамматическом заявлении:

    my_guard(p)[error_handler]

гдеp— выражение, оценивающее парсер. Где-то внутрирпарсер может бросить парсерное исключение.error_handler- обработчик ошибок, который может быть функцией или функтором, совместимым с интерфейсом:

    error_status<T>
    f(ScannerT const& scan, ErrorT error);

Когда сканирование указывает на состояние сканера до разбора и ошибки, возникает ошибка. Обработчику разрешается перемещать положение сканера по своему усмотрению, возможно, в попытке выполнить коррекцию ошибок. Затем обработчик должен вернуть объектerror_status.

The fallback_parser

The expression my_guard(expr, error_handler)creates a fallback_parser object. The fallback_parser handles parser_error exceptions of a specific type. Since my_guard is declared as guard<Errors>, the fallback_parser catches Errors specific parser errors: parser_error<Errors, IteratorT>. The class sets up a try block. When an exception is caught, the catch block then calls the error_handler.

error_status<T>

    template <typename T = nil_t>
    struct error_status
    {
        enum result_t { fail, retry, accept, rethrow };
        error_status(
            result_t result = fail, 
            int length      = -1, 
            T const& value  = T());
        
        result_t    result;
        int         length;
        T           value;
    };

ГдеT- тип атрибута, совместимый с атрибутом соответствияfallback_parser's Subject (по умолчаниюnil_t). Классerror_statusсообщает о результате обработчика ошибок. Этот результат может быть одним из:

error_status result
fail quit and fail. Return a no_match
retry attempt error recovery, possibly moving the scanner
accept force success returning a matching length, moving the scanner appropriately and returning an attribute value
rethrow rethrows the error

См.error_handling.cppдля компилируемого примера. Это часть духовного распределения.



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




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



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


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 07:46:17/0.008526086807251/1