Boost.Spirit.X3 如何防止token被之前的规则解析?
Boost.Spirit.X3 how to prevent token from being parsed by previous rule?
鉴于此语法:
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> (*(char_("a-zA-Z0-9\".{}=_~")))
> x3::lit("}") > x3::lit(";");
最后一个 x3::lit("}") 被 (*(char_("a-zA-Z0-9\".{}=_ ~"))) 因为它包含 "}"
有办法防止吗?比如在解析过程中给予 x3::lit("}") 更高的优先级?
我发现的唯一方法是如果 ;
之后出现,则不允许 kleene star 匹配 '}'
。
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> *(char_("a-zA-Z0-9\".{}=_~") >> !lit(';'))
> x3::lit("}") > x3::lit(";");
您始终可以编写一个像 kleene star 一样工作的自定义解析器,但可以回溯并且还需要第二个必须匹配的解析器。像这样的东西应该有用。
template <class Left, class Right>
struct backtracking : binary_parser<Left, Right, backtracking<Left, Right>>
{
using base = binary_parser<Left, Right, backtracking<Left, Right>>;
backtracking(Left const& left, Right const& right)
: base(left, right)
{
}
template<typename It, typename Ctx, typename Other>
bool parse(It& f, It l, Ctx const& ctx, Other const& other, unused_type) const
{
auto end_it = l;
while (end_it != f) {
auto save = f;
if (this->left.parse(f, end_it, ctx, other, unused)) {
if (this->right.parse(f, l, ctx, other, unused))
return true;
}
f = save;
--end_it;
}
return false;
}
};
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> backtracking(
*(char_("a-zA-Z0-9\".{}=_~")), lit("}") >> lit(";"));
鉴于此语法:
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> (*(char_("a-zA-Z0-9\".{}=_~")))
> x3::lit("}") > x3::lit(";");
最后一个 x3::lit("}") 被 (*(char_("a-zA-Z0-9\".{}=_ ~"))) 因为它包含 "}"
有办法防止吗?比如在解析过程中给予 x3::lit("}") 更高的优先级?
我发现的唯一方法是如果 ;
之后出现,则不允许 kleene star 匹配 '}'
。
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> *(char_("a-zA-Z0-9\".{}=_~") >> !lit(';'))
> x3::lit("}") > x3::lit(";");
您始终可以编写一个像 kleene star 一样工作的自定义解析器,但可以回溯并且还需要第二个必须匹配的解析器。像这样的东西应该有用。
template <class Left, class Right>
struct backtracking : binary_parser<Left, Right, backtracking<Left, Right>>
{
using base = binary_parser<Left, Right, backtracking<Left, Right>>;
backtracking(Left const& left, Right const& right)
: base(left, right)
{
}
template<typename It, typename Ctx, typename Other>
bool parse(It& f, It l, Ctx const& ctx, Other const& other, unused_type) const
{
auto end_it = l;
while (end_it != f) {
auto save = f;
if (this->left.parse(f, end_it, ctx, other, unused)) {
if (this->right.parse(f, l, ctx, other, unused))
return true;
}
f = save;
--end_it;
}
return false;
}
};
const auto grammar_def = x3::lit("start")
> x3::lit("{")
> backtracking(
*(char_("a-zA-Z0-9\".{}=_~")), lit("}") >> lit(";"));