C++ 使用复合语法解析时出现Boost.spirit分段错误

C++ 使用复合语法解析时出现Boost.spirit分段错误,c++,parsing,boost,boost-spirit,C++,Parsing,Boost,Boost Spirit,正在尝试为.fnt文件编写解析器: int main() { const auto word = qi::lexeme [ + qi::alnum ]; const auto literal = qi::lexeme[ '"' >> + ( qi::char_ - '"' ) >> '"' ]; const auto value = literal | qi::double_; const auto pair = word >>

正在尝试为.fnt文件编写解析器:

int main()
{
    const auto word = qi::lexeme [ + qi::alnum ];
    const auto literal = qi::lexeme[ '"' >> + ( qi::char_ - '"' ) >> '"' ];
    const auto value = literal | qi::double_;
    const auto pair = word >> '=' >> value;
    const auto line = word >> ( + pair ) >> qi::eol;
    const auto document = + line;

    std::ifstream in( "input.fnt" );
    in.unsetf( std::ios::skipws );
    boost::spirit::istream_iterator begin(in);
    boost::spirit::istream_iterator end;

    qi::parse( begin, end, document );
}
执行失败,在boost::spirit深度内出现分段错误。但是当我把语法改成不包含中间语法(规则?)时,它成功了

据说,At表达式模板保留对临时变量的内部引用,但在调用qi::parse()时,所有语法都存在。 有什么问题吗?如何将复合语法分解成更有意义的片段


另外,将const auto更改为#define并删除=符号时,成功:)(qi::parse()返回false,但至少返回)。

除了重复之外,还提供一些免费建议:

让我们分析一下简单的FNT示例:

info face=“Arial”size=32 bold=0 italic=0 charset=”“unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0间距=1,1轮廓=0
公共线宽=32基=26标度EW=256标度H=256页=0压缩=0字母CHNL=1红色CHNL=0绿色CHNL=0蓝色CHNL=0
字符数=0
注:

  • 使用skipper来允许不重要的空白。在这种情况下,使用
    qi::blank
    ,因为它保持
    eol
    显著性
  • 通过执行
    double%','
  • 使用BOOST_SPIRIT_调试规则
  • 为隐式词素()声明无跳过规则
  • #define BOOST_SPIRIT_DEBUG
    #include <boost/spirit/include/qi.hpp>
    #include <fstream>
    
    namespace qi = boost::spirit::qi;
    
    int main() {
        using It = boost::spirit::istream_iterator;
        qi::rule<It> 
            word    = +qi::alnum,
            literal = '"' >> *(qi::char_ - '"') >> '"';
        qi::rule<It, std::string()> 
            value   = qi::raw[literal | qi::double_ % ','];
    
        BOOST_SPIRIT_DEBUG_NODES((word)(literal)(value))
    
        const auto pair     = qi::copy(word >> '=' >> value);
        const auto line     = qi::copy(word >> ( + pair ) >> qi::eol);
        const auto document = qi::copy(+ line);
    
        std::ifstream in("input.fnt");
        in.unsetf(std::ios::skipws);
        It begin(in), end;
    
        bool ok = qi::phrase_parse(begin, end, document, qi::blank);
        std::cout << std::boolalpha << ok << '\n';
    }
    
    使用调试信息:

    
    info face=“Arial”si
    face=“Arial”大小=3
    []
    face=“Arial”大小=32
    =“Arial”大小=32 bol
    []
    “Arial”大小=32粗体
    “Arial”大小=32粗体
    大小=32粗体=0意大利
    []
    大小=32粗体=0意大利
    A,r,i,A,l
    大小=32粗体=0斜体
    =32粗体=0斜体=0
    []
    32粗体=0斜体=0 c
    32粗体=0斜体=0 c
    粗体=0斜体=0 cha
    [[3, 2]]
    粗体=0斜体=0字符
    =0斜体=0字符集=
    []
    0斜体=0字符集=”
    0斜体=0字符集=”
    斜体=0字符集=“”
    [[0]]
    斜体=0字符集=“”
    =0字符集=“UNICD”
    []
    0字符集=“unicode”
    0字符集=“unicode”
    字符集=“unicode”=
    [[0]]
    charset=”“unicode=1
    =“”unicode=1c
    []
    “”unicode=1拉伸
    “”unicode=1拉伸
    unicode=1 stretchH=
    []
    unicode=1 stretchH=
    [[", "]]
    unicode=1 stretchH=1
    =1拉伸H=100 smoo
    []
    1个拉伸高度=100斯穆特
    1个拉伸高度=100斯穆特
    拉伸H=100光滑
    [[1]]
    拉伸H=100光滑=
    =100光滑=1 aa=1 p
    []
    100光滑=1 aa=1 pa
    100光滑=1 aa=1 pa
    平滑=1 aa=1帕迪
    [[1, 0, 0]]
    平滑=1 aa=1帕丁
    =1 aa=1 padding=0,0,
    []
    1 aa=1填充=0,0,0
    1 aa=1填充=0,0,0
    aa=1填充=0,0,0,
    [[1]]
    aa=1填充=0,0,0,0
    =1填充=0,0,0,0 s
    []
    1填充=0,0,0,0 sp
    1填充=0,0,0,0 sp
    填充=0,0,0,0 spa
    [[1]]
    填充=0,0,0,0空间
    =0,0,0,0间距=1,1
    []
    0,0,0,0间距=1,1
    0,0,0,0间距=1,1
    间距=1,1轮廓
    [[0,, 0,, 0,, 0]]
    间距=1,1轮廓=
    =1,1轮廓=0\n毫米
    []
    1,1大纲=0\n常见
    1,1大纲=0\n常见
    大纲=0\n普通李
    [[1,, 1]]
    大纲=0\n普通林
    =0\n常用线宽
    []
    0\n常用线宽=
    0\n常用线宽=
    \ncommon线宽=3
    [[0]]
    \ncommon线宽=3
    公共线宽=32
    线宽=32底=
    []
    线宽=32底面=2
    =32基=26标度=2
    []
    32基=26标度=25
    32基=26标度=25
    基数=26 scaleW=256
    [[3, 2]]
    基准=26 scaleW=256秒
    =26刻度EW=256刻度
    []
    26 scaleW=256 scaleH
    26 scaleW=256 scaleH
    scaleW=256 scaleH=2
    [[2, 6]]
    scaleW=256 scaleH=25
    =256 scaleH=256页
    []
    256 scaleH=256页
    256 scaleH=256页
    scaleH=256页=0
    [[2, 5, 6]]
    scaleH=256页=0页
    =256页=0页=
    []
    256页=0压缩=0
    256页=0压缩=0
    页面=0压缩=0 al
    [[2, 5, 6]]
    页面=0包装=0 alp
    =0压缩=0阿尔法中国
    []
    0压缩=0 alphaChnl
    0压缩=0 alphaChnl
    压缩=0 alphaChnl=
    [[0]]
    压缩=0 alphaChnl=1
    =0 alphaChnl=1 redCh
    []
    0 alphaChnl=1 redChn
    0 alphaChnl=1 redChn
    alphaChnl=1 redChnl
    [[0]]
    alphaChnl=1 redChnl=
    =1 redChnl=0 grench
    []
    1 redChnl=0 greenChn
    1 redChnl=0 greenChn
    redChnl=0 greenChnl
    [[1]]
    redChnl=0 greenChnl=
    =0绿色CHNL=0蓝色C
    []
    0绿色通道=0蓝色通道
    0绿色通道=0蓝色通道
    greenChnl=0 blueChn
    [[0]]
    greenChnl=0 blueChnl
    =0 blueChnl=0\n字符串
    []
    0 blueChnl=0\n字符串c
    0 blueChnl=0\n字符串c
    blueChnl=0\n CARS公司
    [[0]]
    blueChnl=0\nchars-cou
    =0\n CHARS计数=0\n
    []
    0\n CHARS计数=0\n
    0\n CHARS计数=0\n
    \nchars计数=0\n
    [[0]]
    \nchars计数=0\n
    字符数=0\n
    计数=0\n
    []
    计数=0\n
    =0\n
    []
    0\n
    0\n
    \n
    [[0]]
    \n
    
    我以前将此链接作为副本链接,因为它是。下面是一些使解析器在一个简单的FNT文件上真正成功的提示
    true