Boost 需要字符分析器的序列和交替来合成字符串

Boost 需要字符分析器的序列和交替来合成字符串,boost,boost-spirit,boost-spirit-x3,Boost,Boost Spirit,Boost Spirit X3,在下面的测试用例中,一个alpha和一个序列的交替出现了一个很长的错误转储,基本上是说静态断言失败了:解析器需要类似元组的属性类型。直觉上,我期望整个规则生成一个字符串,但事实并非如此。我要么将交替的左侧更改为+alpha(使两侧成为向量),要么走语义动作的路径,至少对于交替中的单个字符(附加到_val)。或者,将左侧的字符更改为字符串。不管怎样,我想不出解析像这样琐碎的字符串的简单方法是什么,任何提示都值得赞赏。蒂亚 #include <iostream> #include &l

在下面的测试用例中,一个alpha和一个序列的交替出现了一个很长的错误转储,基本上是说
静态断言失败了:解析器需要类似元组的属性类型
。直觉上,我期望整个规则生成一个字符串,但事实并非如此。我要么将交替的左侧更改为
+alpha
(使两侧成为向量),要么走语义动作的路径,至少对于交替中的单个字符(附加到_val)。或者,将左侧的
字符
更改为
字符串
。不管怎样,我想不出解析像这样琐碎的字符串的简单方法是什么,任何提示都值得赞赏。蒂亚

#include <iostream>

#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;

namespace grammar {

using x3::char_;
using x3::alpha;
using x3::xdigit;

const auto x =
    x3::rule< struct x_class, std::string > { "x" } =
    char_('/') > alpha >> *(alpha | (char_('#') > xdigit));

} // namespace grammar

int main () {
    std::string input{ "/Foobar#F" }, attr;
    auto iter = input.begin ();

    if (phrase_parse (iter, input.end (), grammar::x, x3::space, attr)) {
        std::cout << attr << std::endl;
    }

    return 0;
}
#包括
#包括
名称空间x3=boost::spirit::x3;
名称空间语法{
使用x3::char\ux;
使用x3::alpha;
使用x3::xdigit;
常数自动x=
x3::rule{“x”}=
字符(“/”)>alpha>>*(alpha(“/”)>xdigit));
}//名称空间语法
int main(){
字符串输入{“/Foobar#F”},attr;
auto iter=input.begin();
if(短语解析(iter,input.end(),grammar::x,x3::space,attr)){

我也讨厌这种行为。气在这方面更自然

老实说,我并不总是知道如何“修复”它

  • 在这种情况下,您似乎可以使用
    raw[]
    ——简化语法
  • 有时它有助于避免混合使用
    运算符>
    运算符>>
以下是我为你的语法所做的:

#include <iostream>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;

namespace grammar {
    const auto x =
        x3::rule<struct x_class, std::string> { "x" } =
        x3::raw [ '/' > x3::alpha >> *(x3::alpha | ('#' > x3::xdigit)) ];
}

int main () {
    std::string input{ "/Foobar#F" }, attr;
    auto iter = input.begin ();

    if (phrase_parse (iter, input.end (), grammar::x, x3::space, attr)) {
        std::cout << attr << std::endl;
    }
}

非常感谢。我对spirit的内部细节一无所知。IIUC,这种行为在所有解析器中都是一致的,一致性是伟大的设计。但在我看来,直觉行为,即预期的行为,如果可能的话,应该出现在这里。TBH我认为这是一个(偶然的?)X3中对属性兼容性和规则传播的思考发生了根本性的变化。似乎暴露的属性类型与合成的属性类型的一致性要严格得多,我想这有助于获得更好的错误消息。我确实觉得它无意中删除了可扩展性/转换机会。如果我更好地理解了代码及其设计目标,我可能会就此提出问题。
/Foobar#F