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

Directives

Boost , ,

Directives

Директивы Парсера имеют форму: направление [выражение]

Директива модифицирует поведение своего замкнутого выражения, по существу декорации. Рамочная основа определяет несколько директив. Клиенты системы могут свободно определять свои собственные директивы по мере необходимости. Информация о том, как это делается, будет представлена позднее. Пока мы будем заниматься только предопределенными директивами.

lexeme_d

Выключает белое пространство. На уровне фраз парсер игнорирует белые пространства, возможно, включая комментарии. Используйте lexeme_d в ситуациях, когда мы хотим работать на уровне персонажа вместо уровня фразы. Парсеры могут быть сделаны для работы на уровне символов, включив соответствующие части в директиву lexeme_d. Например, заполните пример, представленный в Введение. Там мы пропустили определение правила целое число. Вот как он на самом деле определяется:

    integer = lexeme_d[ !(ch_p('+') | '-') >> +digit ];

Директива lexeme_d предписывает парсеру работать на уровне символов. Без него правило integer позволило бы ввести ошибочные встроенные белые пространства в вводимые ресурсы, такие как "1 2 345", которые будут рассматриваться как "12345".

as_lower_d

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

as_lower_d behavior

It is important to note that only the input is converted to lower case. Parsers enclosed inside the as_lower_d expecting upper case characters will fail to parse. Example: as_lower_d['X'] will never succeed because it expects an upper case 'X' that the as_lower_d directive will never supply.

Например, в Паскале ключевые слова и идентификаторы являются бесчувственными. Паскаль игнорирует случай букв в идентификаторах и ключевых словах. Идентификаторы Id, ID и id неразличимы в Паскале. Без директивы as_lower_d было бы неловко определить правило, которое признает это. Вот возможность:

    r = str_p("id") | "Id" | "iD" | "ID";

Теперь попробуйте сделать это с случаем нечувствительного Pascal ключевого слова "BEGIN". Директива as_lower_d делает это простым:

    r = as_lower_d["begin"];
Primitive arguments

The astute reader will notice that we did not explicitly wrap "begin" inside an str_p. Whenever appropriate, directives should be able to allow primitive types such as char, int, wchar_t, char const*, wchar_t const* and so on. Examples:

as_lower_d["hello"] // same as as_lower_d[str_p("hello")]
as_lower_d
['x'] // same as as_lower_d[ch_p('x')]

no_actions_d

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

    no_actions_d[expression]

Tweaking the Scanner Type

Как lexeme_d, as_lower_d и no_actions_d работы? Эти директивы делают свою магию, настраивая политику сканирования. Тебе не нужно знать, что это значит. Политика сканирования обсуждается позже. Однако важно отметить, что когда политика сканера настроена, результатом является другой сканер. Почему это важно отметить? правило привязано к конкретному сканеру (один или несколько сканеров, если быть точным). Если вы завершаете правило внутри lexeme_d, as_lower_d или no_actions_d, компилятор будет жаловаться на scanner mismatch, если вы не присоедините необходимый сканер к правилу.

lexeme_scanner, as_lower_scanner и no_actions_scanner являются вашими друзьями, если возникает необходимость обертывания правила внутри этих директив. Узнать об этих зверях в следующей главе на Сканнер и Парсинг.

longest_d

Альтернативы в компиляторе Spirit parser являются короткими (см. Operators). Иногда это не то, что нужно. Директива longest_d предписывает парсеру не использовать альтернативы короткого замыкания, содержащиеся в этой директиве, но вместо этого делает парсер попробовать все возможные альтернативы и выбрать один, соответствующий самой длинной части потока ввода.

Рассмотрим выравнивание целых чисел и реальных чисел:

    number = real | integer;

Число может быть реальным или целым. Эта грамматика неоднозначна. Вход "1234" потенциально должен соответствовать как реальному, так и целых чисел. Напомним, что альтернативы являются краткосрочными. Таким образом, для таких входов, как выше, реальная альтернатива всегда побеждает. Однако, если мы поменяем альтернативы:

    number = integer | real;

у нас все еще проблема. Теперь вход "123.456" будет частично сопоставлен интегратором до десятичной точки. Мы не этого хотим. Решение здесь состоит либо в том, чтобы исправить двусмысленность путем учета общих префиксов реального и целого числа, либо, если это невозможно и не желательно, использовать директиву longest_d:

    number = longest_d[ integer | real ];

shortest_d

Напротив директивы longest_d.

Multiple alternatives

The longest_d and shortest_d directives can accept two or more alternatives. Examples:

longest[ a | b | c ];
shortest
[ a | b | c | d ];

limit_d

Обеспечивает, что результат парсера ограничен заданным диапазоном min..max (включая). Если нет, то парсер терпит неудачу и возвращает "нет-матч".

Использование:

    limit_d(min, max)[expression]

Эта директива особенно полезна в сочетании с парсерами, которые делят конкретные скалярные диапазоны (например, числовые парсеры). Вот пример. Хотя числовые парсеры могут быть настроены, чтобы принять только ограниченное количество цифр (скажем, 0..2), нет способа ограничить результат диапазоном (скажем -1.0.1.0). Эта конструкция преднамеренная. Это подорвало бы дизайнерское правило Духа, что " клиент не должен платить за функции, которые она не использует ". Мы бы сохранили значения min, max в самом числовом парке, используемом или неиспользуемом. Ну, мы могли бы пройти, используя статические константы, настроенные параметром шаблона нетипа, но это неприемлемо, потому что таким образом мы можем разместить только целые числа. Как насчет реальных чисел или пользовательских определенных чисел, таких как big-ints?

Пример, время парза формы H:MM:SS:

    uint_parser<int, 10, 2, 2> uint2_p;
    r = lexeme_d
        [
                limit_d(0u, 23u)[uint2_p] >> ':'    //  Hours 00..23
            >>  limit_d(0u, 59u)[uint2_p] >> ':'    //  Minutes 00..59
            >>  limit_d(0u, 59u)[uint2_p]           //  Seconds 00..59
        ];

min_limit_d

Иногда полезно отключить только максимальный предел. Это позволит установить интервал, который не связан в одном направлении. Директива min_limit_d гарантирует, что результат парсера не меньше, чем минимум. Если нет, то парсер терпит неудачу и возвращает "нет-матч".

Использование:

    min_limit_d(min)[expression]

Пример, убедитесь, что дата не менее 1900

    min_limit_d(1900u)[uint_p]

max_limit_d

Напротив min_limit_d. Обратите внимание, что limit_d [p] эквивалентен:

    min_limit_d(min)[max_limit_d(max)[p]]


 

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




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



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


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 13:16:45/0.027682065963745/1