У меня есть парсер, который анализирует различные типы данных из входного файла. Я уже понял, что дух может выбирать между short и int, например:
value %= (shortIntNode | longIntNode);
с
shortIntNode %= (qi::short_ >> !qi::double_)
[qi::_val = phoenix::bind(&CreateShortIntNode, qi::_1)];
longIntNode %= (qi::int_ >> !qi::double_)
[qi::_val = phoenix::bind(&CreateLongIntNode, qi::_1)];
Я использовал этот тип правил, чтобы обнаружить двойники (из ответов Вот а также Вот). Парсер смог выбрать между int для чисел> 65535 и short для чисел <= 65535. Но для float_ и double_ он работает не так, как ожидалось. Он просто округляет эти значения, чтобы разобрать его в значение с плавающей точкой, если есть правило, подобное этому:
value %= (floatNode | doubleFloatNode);
с
floatNode %= (qi::float_)
[qi::_val = phoenix::bind(&CreateFloatNode, qi::_1)];
doubleFloatNode %= (qi::double_)
[qi::_val = phoenix::bind(&CreateDoubleFloatNode, qi::_1)];
Знаете ли вы, есть ли что-то вроде опции или какой-то другой хитрости для выбора между float_ и double_ в зависимости от диапазона типов данных?
Большое спасибо!
Лексинг может помочь. в конечном счете вы решать, а не парсер. Заказ ваших филиалов должен помочь. Смотрите также
Для похожих парсеров с Boost Spirit.
Если вы хотите выбрать между float / double, то здесь нет реального входного критерия. Я бы предложил всегда разбирать в два раза. Тем не менее, вы можете, конечно, использовать семантические действия, чтобы вызвать float для определенного размера.
Вот что делает грамматика C ++ (например,):
floatrule = lexeme [ float_ >> 'f' ];
doublerule = double_;
float_or_double = floatrule | doublerule;
Других решений пока нет …