1

我有以下代码要修改修复,但我对 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('}')];

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

4

1 回答 1

1

所以,只是为了向你展示我的意思,我已经清理了语法。

在 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[]清楚地表明规则已使用船长声明(如果没有,所有规则都是隐含的“词素”)
  • 格式化!

    • 当然,使用命名空间会有所帮助。
    • 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
于 2013-08-27T11:19:28.677 回答