- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想用boost spirit来解析一个可以有多种类型的值;例如像这样的东西:
singleValueToBeParsed %= (double_ | int_ | bool_ | genericString);
genericString %= +(char_("a-zA-Z"));
解析为 int 或 double 的情况似乎相当简单:
Parse int or double using boost spirit (longest_d)
..但我不确定如何扩展它以合并其他类型,包括通用字符串和 bool 值..
有什么想法吗?
谢谢,
本。
编辑:所以根据答案,我更新了我的语法如下:
genericString %= +(char_("a-zA-Z"));
intRule %= int_;
doubleRule %= (&int_ >> (double_ >> 'f'))
| (!int_ >> double_ >> -lit('f'));
boolRule %= bool_;
其中每个 qi 规则都有一个 string、int、double 或 bool 迭代器
那么我有一个规则
add %= string("add") >> '('
>> (intRule | doubleRule | genericString) >> ','
>> (intRule | doubleRule | genericString) >> ','
>> genericString
>> ')' >> ';';
期望采用语法 add(5, 6.1, result);或添加(a,b,结果);但到目前为止,如果前两个参数是整数,它只是解析。
注意添加规则指定为:
qi::rule<Iterator, Function(), ascii::space_type> add;
函数指定为:
typedef boost::any DirectValue;
struct Function
{
//
// name of the Function; will always be a string
//
std::string name;
//
// the function parameters which can be initialized to any type
//
DirectValue paramA;
DirectValue paramB;
DirectValue paramC;
DirectValue paramD;
DirectValue paramE;
};
BOOST_FUSION_ADAPT_STRUCT(
Function,
(std::string, name)
(DirectValue, paramA)
(DirectValue, paramB)
(DirectValue, paramC)
(DirectValue, paramD)
(DirectValue, paramE)
)
编辑 2:
现在可以正确解析了。参见 http://liveworkspace.org/code/3asg0X%247由 llonesmiz 友情提供。干杯。
最佳答案
这是一个有趣的练习。
当然,一切都取决于输入语法,您可以方便地指定。
但是,为了演示,让我们假设一个(非常)松散地基于 C++ 文字的文字语法,我们可以提出以下内容来解析十进制(有符号)整数值、浮点值、 bool 文字和简单的字符串文字:
typedef boost::variant<
double, unsigned int,
long, unsigned long, int,
bool, std::string> attr_t;
// ...
start =
(
// number formats with mandatory suffixes first
ulong_rule | uint_rule | long_rule |
// then those (optionally) without suffix
double_rule | int_rule |
// and the simple, unambiguous cases
bool_rule | string_rule
);
double_rule =
(&int_ >> (double_ >> 'f')) // if it could be an int, the suffix is required
| (!int_ >> double_ >> -lit('f')) // otherwise, optional
;
int_rule = int_;
uint_rule = uint_ >> 'u' ;
long_rule = long_ >> 'l' ;
ulong_rule = ulong_ >> "ul" ;
bool_rule = bool_;
string_rule = '"' >> *~char_('"') >> '"';
查看测试用例输出的链接现场演示: http://liveworkspace.org/code/goPNP
注意 只有一个测试输入(“无效”)应该会失败。其余部分应解析为文字,可选择留下未解析的剩余输入。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
typedef boost::variant<double, unsigned int, long, unsigned long, int, bool, std::string> attr_t;
template <typename It, typename Skipper = qi::space_type>
struct parser : qi::grammar<It, attr_t(), Skipper>
{
parser() : parser::base_type(start)
{
using namespace qi;
start =
(
// number formats with mandatory suffixes first
ulong_rule | uint_rule | long_rule |
// then those (optionally) without suffix
double_rule | int_rule |
// and the simple, unambiguous cases
bool_rule | string_rule
);
double_rule =
(&int_ >> (double_ >> 'f')) // if it could be an int, the suffix is required
| (!int_ >> double_ >> -lit('f')) // otherwise, optional
;
int_rule = int_;
uint_rule = uint_ >> 'u' ;
long_rule = long_ >> 'l' ;
ulong_rule = ulong_ >> "ul" ;
bool_rule = bool_;
string_rule = '"' >> *~char_('"') >> '"';
BOOST_SPIRIT_DEBUG_NODE(start);
BOOST_SPIRIT_DEBUG_NODE(double_rule);
BOOST_SPIRIT_DEBUG_NODE(ulong_rule);
BOOST_SPIRIT_DEBUG_NODE(long_rule);
BOOST_SPIRIT_DEBUG_NODE(uint_rule);
BOOST_SPIRIT_DEBUG_NODE(int_rule);
BOOST_SPIRIT_DEBUG_NODE(bool_rule);
BOOST_SPIRIT_DEBUG_NODE(string_rule);
}
private:
qi::rule<It, attr_t(), Skipper> start;
// no skippers in here (important):
qi::rule<It, double()> double_rule;
qi::rule<It, int()> int_rule;
qi::rule<It, unsigned int()> uint_rule;
qi::rule<It, long()> long_rule;
qi::rule<It, unsigned long()> ulong_rule;
qi::rule<It, bool()> bool_rule;
qi::rule<It, std::string()> string_rule;
};
struct effective_type : boost::static_visitor<std::string> {
template <typename T>
std::string operator()(T const& v) const {
return typeid(v).name();
}
};
bool testcase(const std::string& input)
{
typedef std::string::const_iterator It;
auto f(begin(input)), l(end(input));
parser<It, qi::space_type> p;
attr_t data;
try
{
std::cout << "parsing '" << input << "': ";
bool ok = qi::phrase_parse(f,l,p,qi::space,data);
if (ok)
{
std::cout << "success\n";
std::cout << "parsed data: " << karma::format_delimited(karma::auto_, ' ', data) << "\n";
std::cout << "effective typeid: " << boost::apply_visitor(effective_type(), data) << "\n";
}
else std::cout << "failed at '" << std::string(f,l) << "'\n";
if (f!=l) std::cout << "trailing unparsed: '" << std::string(f,l) << "'\n";
std::cout << "------\n\n";
return ok;
} catch(const qi::expectation_failure<It>& e)
{
std::string frag(e.first, e.last);
std::cout << e.what() << "'" << frag << "'\n";
}
return false;
}
int main()
{
for (auto const& s : std::vector<std::string> {
"1.3f",
"0.f",
"0.",
"0f",
"0", // int will be preferred
"1u",
"1ul",
"1l",
"1",
"false",
"true",
"\"hello world\"",
// interesting cases
"invalid",
"4.5e+7f",
"-inf",
"-nan",
"42 is the answer", // 'is the answer' is simply left unparsed, it's up to the surrounding grammar/caller
" 0\n ", // whitespace is fine
"42\n.0", // but not considered as part of a literal
})
{
testcase(s);
}
}
关于c++ - 使用boost::spirit解析多种类型的单值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15212671/
我想对请求JSON进行解码,该请求JSON的值可以是单个字符串或数组(列表)。 我知道如何分别解析。但我正在寻找一种具有动态解码器来解析两者的方法。 JSON中的value字段就是我正在谈论的情况 单
这个问题在这里已经有了答案: Single result from database using mysqli (6 个答案) 关闭 3 年前。 我正在尝试编写一个函数,该函数将使用 mysqli
这个问题已经有答案了: Single result from database using mysqli (6 个回答) 已关闭 3 年前。 我正在尝试编写一个函数,该函数将使用 mysqli 检查数
在 MySQL 中这样做是不是很糟糕: SELECT ... WHERE foo IN ('bar') 而不是这个... SELECT ... WHERE foo = 'bar' ...鉴于此动态生成
这个问题在这里已经有了答案: Single result from database using mysqli (6 个答案) 关闭 2 年前。 我正在尝试编写一个函数,该函数将使用 mysqli
在我的 BehaviorSubject 中,address 元素有 2 个属性。在此如何单独更新单个属性? 这是我的尝试: myAddress:any = { "plot":32, "
例如,给定输入: { "values": ["APPLE", "PEAR", "BANANA"] } 对所需输出进行排序后: { "values": ["APPLE", "BANANA", "
在执行检查多个值的原始 SQL 时,我在使用 SQLAlchemy 时遇到了问题。 my_sess.execute( "SELECT * FROM table WHERE `key`=
我正在尝试在 mysql 存储过程中进行计数,但无法获得正确的语法 help1 delimiter// create procedure get_count_workmen_type(
是否可以在具有单个值的张量上运行 map_fn? 以下工作: import tensorflow as tf a = tf.constant(1.0, shape=[3]) tf.map_fn(lam
我正在寻找一种方法来查找总内存和正在使用的内存的单个熟值输出。 gwmi Win32_OperatingSystem | select TotalVisibleMemorySize, FreePhys
我是一名优秀的程序员,十分优秀!