Boost Spirit x3:解析分隔字符串
Boost Spirit x3: parse delimited string
我正在用 Spirit X3 编写另一个无聊的计算器解析器,我遇到了一个问题:我定义了 2 个文字,"cos" 和 "cosh",每个都期望后跟一个数字。我写的规则是:
const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = (COS_TAG > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];
(我知道语义动作不是首选方式,但我很懒惰)。
现在,解析 "cosh 3.5" 时的问题是:
expectation failure: expecting value here "cosh 3.5"
----------------------------------------------^-----
看起来解析器很急于使用第一个标记而不检查另一个标记。我已经通过使用这样的差异运算符使其工作:
const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = ((x3::lit(COS_TAG) - COSH_TAG) > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];
有没有更好的方法?
因此,不是分隔字符串,而是检查标记边界。
Qi 存储库为此提供了 distinct
,我想我可能已经在 X3 代码库中看过一次。会找的。
不管怎样,为了now/older versions/your的理解,这里有一些实现的方法:
重新排序分支,如果你在 cos
之前匹配 cosh
你会得到你想要的行为,因为贪婪
对您的标识符做出更笼统的断言:
auto kw = [](auto p) {
return x3::lexeme [ x3::as_parser(p) >> !x3::char_("a-zA-Z0-9_") ];
};
现在您可以使用 kw(COSH)
而不是 lit(COSH)
并确保它不匹配 coshida
.
我正在用 Spirit X3 编写另一个无聊的计算器解析器,我遇到了一个问题:我定义了 2 个文字,"cos" 和 "cosh",每个都期望后跟一个数字。我写的规则是:
const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = (COS_TAG > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];
(我知道语义动作不是首选方式,但我很懒惰)。 现在,解析 "cosh 3.5" 时的问题是:
expectation failure: expecting value here "cosh 3.5"
----------------------------------------------^-----
看起来解析器很急于使用第一个标记而不检查另一个标记。我已经通过使用这样的差异运算符使其工作:
const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = ((x3::lit(COS_TAG) - COSH_TAG) > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];
有没有更好的方法?
因此,不是分隔字符串,而是检查标记边界。
Qi 存储库为此提供了 distinct
,我想我可能已经在 X3 代码库中看过一次。会找的。
不管怎样,为了now/older versions/your的理解,这里有一些实现的方法:
重新排序分支,如果你在
cos
之前匹配cosh
你会得到你想要的行为,因为贪婪对您的标识符做出更笼统的断言:
auto kw = [](auto p) { return x3::lexeme [ x3::as_parser(p) >> !x3::char_("a-zA-Z0-9_") ]; };
现在您可以使用
kw(COSH)
而不是lit(COSH)
并确保它不匹配coshida
.