Spirit Qi解析问题与简单的C风格结构化输入

时间:2014-02-17 17:51:16

标签: c++ parsing boost boost-spirit boost-spirit-qi

我正在尝试为一些使用熟悉且非常简单的“C风格”格式的游戏数据设置基本解析器。基本上,命名支撑“结构”然后将参数和嵌套的“结构”放在里面。它会解析这样的事情:

Name0
{
 Name1
 {
  Param0 *= 2
  Param2 = "lol"
 }
 Param0 = 1
 Param1 = "test"

 Name2 { }
}

Name3 {
 Param0 = "test"
}

然而,即使是“Test {}”的简单输入测试,它也是失败的,更不用说像上面的例子那样先进了。结构设置为使用融合,这似乎是直截了当的,我怀疑这是问题。我目前没有使用一些规则,并且我的大部分规则都未经过测试,因为它在category中尝试第一个root规则时失败了。这是我在输入“Test {}”时遇到的错误:

Error! Expecting <sequence>"{"<node> here: ""

这是Parser类:

 template<typename Iterator>
 struct Parser : qi::grammar<Iterator, std::vector<Category>(), ascii::space_type>
 {
  qi::rule<Iterator, std::vector<Category>(), ascii::space_type> root;

  qi::rule<Iterator, Category(), ascii::space_type> category;
  qi::rule<Iterator, Param(), ascii::space_type> param;

  qi::rule<Iterator, Node(), ascii::space_type> node;

  qi::rule<Iterator, Value(), ascii::space_type> value;

  qi::rule<Iterator, char()> escape;
  qi::rule<Iterator, std::string()> quotedstring;
  qi::rule<Iterator, std::string()> normalstring;

  qi::rule<Iterator> comment;
  qi::rule<Iterator> commentblock;

  Parser() : Parser::base_type(root, "root")
  {
   using namespace qi;

   using ascii::char_;

   using phoenix::construct;
   using phoenix::val;

   escape %= '\\' > char_("\\\"");
   quotedstring %= '"' >> *((char_ - '"') | escape) > '"';
   normalstring %= *(char_ - qi::eol);

   comment = "//" >> *(char_ - qi::eol);
   commentblock = "/*" >> *(char_ - "*/") > "*/";

   node %= category | param; //comment? comment block? holding off for now

   value %= normalstring | float_;

   param %=
    lexeme[+(char_ - operators)]
    > operators
    > value
    > qi::eol;

   category %=
    lexeme[+(char_ - '{')] //won't this grab all whitespace around the tag too?
    > '{'
    >> *node
    > '}';

    root %= *category;

    root.name("root");

    category.name("category");
    param.name("param");

    node.name("node");

    value.name("value");

    escape.name("escape");
    quotedstring.name("quotedstring");
    normalstring.name("normalstring");

    comment.name("comment");
    commentblock.name("commentblock");

    debug(root);
    debug(category);
    debug(param);
    debug(node);
    debug(value);
    debug(escape);
    debug(quotedstring);
    debug(normalstring);
    debug(comment);
    debug(commentblock);

    on_error<fail>
     (
     root,
     std::cout
     << val("Error! Expecting ")
     << _4
     << val(" here: \"")
     << construct<std::string>(_3, _2)
     << val("\"")
     << std::endl
     );
  }
 };

一个无关的事情,是否可以在on_successon_error调用中使用C ++ 11 lambdas?我查看了on_error函数,似乎将其参数模板化为规则类型,这意味着必须为每个规则类型(基本上每个规则)定义一个lambda。那是对的吗?太糟糕了,那些凤凰lambdas是如此不透明,我不知道如何拉出一个行号并把它放在一个结构中。

编辑:

这是operators表:

 struct Operators : qi::symbols<char, Operator>
 {
  Operators()
  {
   add
    ("=", Operator::equal)
    ("+=", Operator::plusequal)
    ("-=", Operator::minusequal)
    ("*=", Operator::timesequal)
    ("/=", Operator::divideequal)
    ;
  }
 } operators;

1 个答案:

答案 0 :(得分:2)

operators未给出。

我猜您的node规则会使结束}失败,因此catagory规则无法成功。