我有以下代码要修改,但是我对Boost-spirit完全陌生。
我知道RE是精打细算的,但不知道该怎么做。

这是解析器。

Parser() : Parser::base_type(root)
{
    braces  = lit('{') >> *(iso8859_1::space) >> lit('}');
    str     = lexeme[lit('"') >> raw[*(~iso8859_1::char_('"'))] >> lit('"')];
    tolleaf = raw[+(~iso8859_1::char_("\"{}= \t\r\n"))];
    leaf    = raw[+(iso8859_1::alnum | iso8859_1::char_("-._:"))];
    taglist = lit('{') >> omit[*(iso8859_1::space)] >> lexeme[( ( str | skip[tolleaf] ) % *(iso8859_1::space) )] >> omit[*(iso8859_1::space)] >> lit('}');
    object  = raw[lit('{') >> *(root) >> *(iso8859_1::space) >> lit('}')];
    objlist = raw[lit('{') >> *( *(iso8859_1::space) >> object[&pushObj] ) >> *(iso8859_1::space) >> lit('}')];
    assign  = raw[(*(iso8859_1::space) >> ( leaf[&setLHS] | str[&setLHS]) >> *(iso8859_1::space) >> lit('=')
        >> *(iso8859_1::space)
        >> ( leaf[&setRHSleaf] | str[&setRHSleaf] | taglist[&setRHStaglist] | objlist[&setRHSobjlist] | object[&setRHSobject] )
        >> *(iso8859_1::space))];
    root    = +(assign | braces);

    str.name("str");
    leaf.name("leaf");
    taglist.name("taglist");
    object.name("object");
    objlist.name("objlist");
    assign.name("assign");
    braces.name("braces");
    root.name("root");

}

这是我尝试解析的格式:
employees=
{
{
    province_pop_id=
    {
    province_id=1
    index=0
    type=9
    }
    count=1750
}

{
    province_pop_id=
    {
    province_id=1
    index=1
    type=9
    }
    count=34
}
}

问题是双{{。如果我只有一个
blahblah=
{
    value=
    {
        2
    }
}

它工作正常。

我知道
 objlist = raw[lit('{') >> *( *(iso8859_1::space) >> object[&pushObj] ) >> *(iso8859_1::space) >> lit('}')];

必须更改,但我不确定如何更改。

最佳答案

因此,为了向您展示我的意思,我整理了语法。

看到它 Live on Coliru

Parser() : Parser::base_type(root)
{
    using namespace qi::iso8859_1;

    braces  =
        '{' >> qi::eps >> '}'
        ;
    str     = qi::lexeme [
             '"'
          >> *~char_('"')
          >> '"'
        ]
        ;
    tolleaf = qi::lexeme [
            +(~char_("\"{}= \t\r\n"))
        ]
        ;
    leaf    = qi::lexeme [
            +(alnum | char_("-._:"))
        ]
        ;
    taglist =
           '{'
        >> -str % tolleaf
        >> '}'
        ;
    object  =
             '{'
          >> *root
          >> '}'
        ;
    objlist =
             '{'
          >> *object
          >> '}'
        ;
    assign  =
             (leaf | str)
          >> '='
          >> (leaf | str | taglist | objlist | object)
        ;
    root    =
        +(assign | braces)
        ;

    BOOST_SPIRIT_DEBUG_NODES((root)(braces)(str)(tolleaf)(leaf)(taglist)(objlist)(object)(assign));
}

它包含了很多令人惊讶的东西
  • 冗余空白检查,而船长已执行此
  • skip[]lexeme[]的存在清楚地表明,已使用Skipper声明了规则(如果未声明,则所有规则隐式地为“lexemes”)
  • 格式化!
  • 当然,使用 namespace 会有所帮助。
  • qi::lit仅在存在歧义或需要重载时才需要
  • 许多冗余()
  • 一行中的所有内容都会导致难以理解的规则。所提出的布局还使得仅通过注释一些行
  • 即可更轻松地选择性地调试编译问题。
  • BOOST_SPIRIT_DEBUG *宏用于调试。参见完整工作示例
  • 下方的输出

    注意我没有看过实际的语法。看起来这也可以改进,但是我没有时间尝试去理解预期的语法。但是,您可以看到它解析了您在问题中显示的代码段:

    完整代码
    #define BOOST_SPIRIT_DEBUG
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    
    namespace qi        = boost::spirit::qi;
    
    template <typename It, typename Skipper = qi::iso8859_1::space_type>
        struct Parser : qi::grammar<It, Skipper>
    {
        Parser() : Parser::base_type(root)
        {
            using namespace qi::iso8859_1;
    
            braces  =
                '{' >> qi::eps >> '}'
                ;
            str     = qi::lexeme [
                     '"'
                  >> *~char_('"')
                  >> '"'
                ]
                ;
            tolleaf = qi::lexeme [
                    +(~char_("\"{}= \t\r\n"))
                ]
                ;
            leaf    = qi::lexeme [
                    +(alnum | char_("-._:"))
                ]
                ;
            taglist =
                   '{'
                >> -str % tolleaf
                >> '}'
                ;
            object  =
                     '{'
                  >> *root
                  >> '}'
                ;
            objlist =
                     '{'
                  >> *object
                  >> '}'
                ;
            assign  =
                     (leaf | str)
                  >> '='
                  >> (leaf | str | taglist | objlist | object)
                ;
            root    =
                +(assign | braces)
                ;
    
            BOOST_SPIRIT_DEBUG_NODES((root)(braces)(str)(tolleaf)(leaf)(taglist)(objlist)(object)(assign));
        }
    
      private:
        qi::rule<It, Skipper> root, braces, str, tolleaf, leaf, taglist, objlist, object, assign;
    };
    
    int main()
    {
        typedef boost::spirit::istream_iterator It;
        std::cin.unsetf(std::ios::skipws);
        It f(std::cin), l;
    
        namespace iso8859_1 = qi::iso8859_1;
        Parser<It, iso8859_1::space_type> p;
    
        try
        {
            bool ok = qi::phrase_parse(f,l,p,iso8859_1::space);
            if (ok)   std::cout << "parse success\n";
            else      std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
    
            if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
            return ok;
        } catch(const qi::expectation_failure<It>& e)
        {
            std::string frag(e.first, e.last);
            std::cerr << e.what() << "'" << frag << "'\n";
        }
    
        return false;
    }
    

    输出量

    这是BOOST_SPIRIT_DEBUG打印的内容:

    <root>
      <try>employees=\n{\n{\n    p</try>
      <assign>
        <try>employees=\n{\n{\n    p</try>
        <leaf>
          <try>employees=\n{\n{\n    p</try>
          <success>=\n{\n{\n    province_p</success>
          <attributes>[]</attributes>
        </leaf>
        <leaf>
          <try>\n{\n{\n    province_po</try>
          <fail/>
        </leaf>
        <str>
          <try>{\n{\n    province_pop</try>
          <fail/>
        </str>
        <taglist>
          <try>{\n{\n    province_pop</try>
          <str>
            <try>\n{\n    province_pop_</try>
            <fail/>
          </str>
          <tolleaf>
            <try>{\n    province_pop_i</try>
            <fail/>
          </tolleaf>
          <fail/>
        </taglist>
        <objlist>
          <try>{\n{\n    province_pop</try>
          <object>
            <try>\n{\n    province_pop_</try>
            <root>
              <try>\n    province_pop_id</try>
              <assign>
                <try>\n    province_pop_id</try>
                <leaf>
                  <try>\n    province_pop_id</try>
                  <success>=\n    {\n    province</success>
                  <attributes>[]</attributes>
                </leaf>
                <leaf>
                  <try>\n    {\n    province_</try>
                  <fail/>
                </leaf>
                <str>
                  <try>{\n    province_id=1\n</try>
                  <fail/>
                </str>
                <taglist>
                  <try>{\n    province_id=1\n</try>
                  <str>
                    <try>\n    province_id=1\n </try>
                    <fail/>
                  </str>
                  <tolleaf>
                    <try>province_id=1\n    in</try>
                    <success>=1\n    index=0\n    t</success>
                    <attributes>[]</attributes>
                  </tolleaf>
                  <str>
                    <try>=1\n    index=0\n    t</try>
                    <fail/>
                  </str>
                  <tolleaf>
                    <try>=1\n    index=0\n    t</try>
                    <fail/>
                  </tolleaf>
                  <fail/>
                </taglist>
                <objlist>
                  <try>{\n    province_id=1\n</try>
                  <object>
                    <try>\n    province_id=1\n </try>
                    <fail/>
                  </object>
                  <fail/>
                </objlist>
                <object>
                  <try>{\n    province_id=1\n</try>
                  <root>
                    <try>\n    province_id=1\n </try>
                    <assign>
                      <try>\n    province_id=1\n </try>
                      <leaf>
                        <try>\n    province_id=1\n </try>
                        <success>=1\n    index=0\n    t</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>1\n    index=0\n    ty</try>
                        <success>\n    index=0\n    typ</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    index=0\n    typ</success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    index=0\n    typ</try>
                      <leaf>
                        <try>\n    index=0\n    typ</try>
                        <success>=0\n    type=9\n    }\n</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>0\n    type=9\n    }\n </try>
                        <success>\n    type=9\n    }\n  </success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    type=9\n    }\n  </success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    type=9\n    }\n  </try>
                      <leaf>
                        <try>\n    type=9\n    }\n  </try>
                        <success>=9\n    }\n    count=1</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>9\n    }\n    count=17</try>
                        <success>\n    }\n    count=175</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    }\n    count=175</success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    }\n    count=175</try>
                      <leaf>
                        <try>\n    }\n    count=175</try>
                        <fail/>
                      </leaf>
                      <str>
                        <try>}\n    count=1750\n}\n\n</try>
                        <fail/>
                      </str>
                      <fail/>
                    </assign>
                    <braces>
                      <try>\n    }\n    count=175</try>
                      <fail/>
                    </braces>
                    <success>\n    }\n    count=175</success>
                    <attributes>[]</attributes>
                  </root>
                  <root>
                    <try>\n    }\n    count=175</try>
                    <assign>
                      <try>\n    }\n    count=175</try>
                      <leaf>
                        <try>\n    }\n    count=175</try>
                        <fail/>
                      </leaf>
                      <str>
                        <try>}\n    count=1750\n}\n\n</try>
                        <fail/>
                      </str>
                      <fail/>
                    </assign>
                    <braces>
                      <try>\n    }\n    count=175</try>
                      <fail/>
                    </braces>
                    <fail/>
                  </root>
                  <success>\n    count=1750\n}\n\n{</success>
                  <attributes>[]</attributes>
                </object>
                <success>\n    count=1750\n}\n\n{</success>
                <attributes>[]</attributes>
              </assign>
              <assign>
                <try>\n    count=1750\n}\n\n{</try>
                <leaf>
                  <try>\n    count=1750\n}\n\n{</try>
                  <success>=1750\n}\n\n{\n    provi</success>
                  <attributes>[]</attributes>
                </leaf>
                <leaf>
                  <try>1750\n}\n\n{\n    provin</try>
                  <success>\n}\n\n{\n    province_p</success>
                  <attributes>[]</attributes>
                </leaf>
                <success>\n}\n\n{\n    province_p</success>
                <attributes>[]</attributes>
              </assign>
              <assign>
                <try>\n}\n\n{\n    province_p</try>
                <leaf>
                  <try>\n}\n\n{\n    province_p</try>
                  <fail/>
                </leaf>
                <str>
                  <try>}\n\n{\n    province_po</try>
                  <fail/>
                </str>
                <fail/>
              </assign>
              <braces>
                <try>\n}\n\n{\n    province_p</try>
                <fail/>
              </braces>
              <success>\n}\n\n{\n    province_p</success>
              <attributes>[]</attributes>
            </root>
            <root>
              <try>\n}\n\n{\n    province_p</try>
              <assign>
                <try>\n}\n\n{\n    province_p</try>
                <leaf>
                  <try>\n}\n\n{\n    province_p</try>
                  <fail/>
                </leaf>
                <str>
                  <try>}\n\n{\n    province_po</try>
                  <fail/>
                </str>
                <fail/>
              </assign>
              <braces>
                <try>\n}\n\n{\n    province_p</try>
                <fail/>
              </braces>
              <fail/>
            </root>
            <success>\n\n{\n    province_pop</success>
            <attributes>[]</attributes>
          </object>
          <object>
            <try>\n\n{\n    province_pop</try>
            <root>
              <try>\n    province_pop_id</try>
              <assign>
                <try>\n    province_pop_id</try>
                <leaf>
                  <try>\n    province_pop_id</try>
                  <success>=\n    {\n    province</success>
                  <attributes>[]</attributes>
                </leaf>
                <leaf>
                  <try>\n    {\n    province_</try>
                  <fail/>
                </leaf>
                <str>
                  <try>{\n    province_id=1\n</try>
                  <fail/>
                </str>
                <taglist>
                  <try>{\n    province_id=1\n</try>
                  <str>
                    <try>\n    province_id=1\n </try>
                    <fail/>
                  </str>
                  <tolleaf>
                    <try>province_id=1\n    in</try>
                    <success>=1\n    index=1\n    t</success>
                    <attributes>[]</attributes>
                  </tolleaf>
                  <str>
                    <try>=1\n    index=1\n    t</try>
                    <fail/>
                  </str>
                  <tolleaf>
                    <try>=1\n    index=1\n    t</try>
                    <fail/>
                  </tolleaf>
                  <fail/>
                </taglist>
                <objlist>
                  <try>{\n    province_id=1\n</try>
                  <object>
                    <try>\n    province_id=1\n </try>
                    <fail/>
                  </object>
                  <fail/>
                </objlist>
                <object>
                  <try>{\n    province_id=1\n</try>
                  <root>
                    <try>\n    province_id=1\n </try>
                    <assign>
                      <try>\n    province_id=1\n </try>
                      <leaf>
                        <try>\n    province_id=1\n </try>
                        <success>=1\n    index=1\n    t</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>1\n    index=1\n    ty</try>
                        <success>\n    index=1\n    typ</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    index=1\n    typ</success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    index=1\n    typ</try>
                      <leaf>
                        <try>\n    index=1\n    typ</try>
                        <success>=1\n    type=9\n    }\n</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>1\n    type=9\n    }\n </try>
                        <success>\n    type=9\n    }\n  </success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    type=9\n    }\n  </success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    type=9\n    }\n  </try>
                      <leaf>
                        <try>\n    type=9\n    }\n  </try>
                        <success>=9\n    }\n    count=3</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <leaf>
                        <try>9\n    }\n    count=34</try>
                        <success>\n    }\n    count=34\n</success>
                        <attributes>[]</attributes>
                      </leaf>
                      <success>\n    }\n    count=34\n</success>
                      <attributes>[]</attributes>
                    </assign>
                    <assign>
                      <try>\n    }\n    count=34\n</try>
                      <leaf>
                        <try>\n    }\n    count=34\n</try>
                        <fail/>
                      </leaf>
                      <str>
                        <try>}\n    count=34\n}\n}\n</try>
                        <fail/>
                      </str>
                      <fail/>
                    </assign>
                    <braces>
                      <try>\n    }\n    count=34\n</try>
                      <fail/>
                    </braces>
                    <success>\n    }\n    count=34\n</success>
                    <attributes>[]</attributes>
                  </root>
                  <root>
                    <try>\n    }\n    count=34\n</try>
                    <assign>
                      <try>\n    }\n    count=34\n</try>
                      <leaf>
                        <try>\n    }\n    count=34\n</try>
                        <fail/>
                      </leaf>
                      <str>
                        <try>}\n    count=34\n}\n}\n</try>
                        <fail/>
                      </str>
                      <fail/>
                    </assign>
                    <braces>
                      <try>\n    }\n    count=34\n</try>
                      <fail/>
                    </braces>
                    <fail/>
                  </root>
                  <success>\n    count=34\n}\n}\n</success>
                  <attributes>[]</attributes>
                </object>
                <success>\n    count=34\n}\n}\n</success>
                <attributes>[]</attributes>
              </assign>
              <assign>
                <try>\n    count=34\n}\n}\n</try>
                <leaf>
                  <try>\n    count=34\n}\n}\n</try>
                  <success>=34\n}\n}\n</success>
                  <attributes>[]</attributes>
                </leaf>
                <leaf>
                  <try>34\n}\n}\n</try>
                  <success>\n}\n}\n</success>
                  <attributes>[]</attributes>
                </leaf>
                <success>\n}\n}\n</success>
                <attributes>[]</attributes>
              </assign>
              <assign>
                <try>\n}\n}\n</try>
                <leaf>
                  <try>\n}\n}\n</try>
                  <fail/>
                </leaf>
                <str>
                  <try>}\n}\n</try>
                  <fail/>
                </str>
                <fail/>
              </assign>
              <braces>
                <try>\n}\n}\n</try>
                <fail/>
              </braces>
              <success>\n}\n}\n</success>
              <attributes>[]</attributes>
            </root>
            <root>
              <try>\n}\n}\n</try>
              <assign>
                <try>\n}\n}\n</try>
                <leaf>
                  <try>\n}\n}\n</try>
                  <fail/>
                </leaf>
                <str>
                  <try>}\n}\n</try>
                  <fail/>
                </str>
                <fail/>
              </assign>
              <braces>
                <try>\n}\n}\n</try>
                <fail/>
              </braces>
              <fail/>
            </root>
            <success>\n}\n</success>
            <attributes>[]</attributes>
          </object>
          <object>
            <try>\n}\n</try>
            <fail/>
          </object>
          <success>\n</success>
          <attributes>[]</attributes>
        </objlist>
        <success>\n</success>
        <attributes>[]</attributes>
      </assign>
      <assign>
        <try>\n</try>
        <leaf>
          <try>\n</try>
          <fail/>
        </leaf>
        <str>
          <try></try>
          <fail/>
        </str>
        <fail/>
      </assign>
      <braces>
        <try>\n</try>
        <fail/>
      </braces>
      <success>\n</success>
      <attributes>[]</attributes>
    </root>
    parse success
    

    关于c++ - Boost Spirit像语法一样解析XML,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18453062/

    10-16 04:39