精神齐:完全无视某些规则的输出

时间:2014-02-18 17:55:14

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

我正在解析一些模糊结构的输入,就像C-ish代码一样。像这样:

Name0
{
 Name1
 {
  //A COMMENT!!

  Param0 *= 2
  Param2 = "lol"
 }
}

部分内容是评论,我想完全忽略它(并且它不起作用)。我认为有两件事是node,命名范围(category规则),如Name0 {}和值param规则),如Param0 *= 2 ...然后有comment。我试过像这样设置:

typedef boost::variant<boost::recursive_wrapper<Category>, Param> Node;

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

因此,node规则会在Category中放置Paramvariant。以下是其他规则(我省略了一些与此无关的规则):

qi::rule<Iterator> comment; //comment has no return type

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

他们的实际代码:

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

param %=
 tagstring
 >> operators
 >> value;

category %=
 tagstring
 >> '{'
 >> *node
 > '}';

node %= comment | category | param;

comment设置为使用=而不是%=,并且它没有返回类型。但是,评论最终会在我的输出Category中创建null Node s,无论它们出现在哪里。我已尝试将comment移出node规则,然后转移到此category

category %=
 tagstring
 >> '{'
 >> *(comment | node)
 > '}';

以及其他各种事情,但那些空条目不断涌现。我必须让comment输出一个字符串并将std::string放在我的Node variant中,只是为了抓住它们,但这会影响我在其他部分评论的能力我的规则(除非我实际上在每个位置都抓住了字符串)。

如何完全忽略comment,并且不会以任何方式显示在任何输出中?

编辑:您认为omit会这样做,但似乎没有改变任何内容......

编辑2:引用this SO answer,我有一个不稳定的解决方案:

node %= category | param;

category %=
 tagstring
 >> '{'
 >> *comment >> *(node >> *comment)
 > '}';

但是,我想尝试将评论粘贴到各种地方(tagstring{之间,在我未知的root规则之间的根category之间等等)。有比这更简单的方法吗?我希望可以通过一个简单的>> commentwrapper插入到我想要的任何地方......

1 个答案:

答案 0 :(得分:2)

好吧,所以自己做船长也不错。正如Mike M所说,它优雅地解决了这个评论问题。我在一个名为Parser的结构中定义了我的规则,该结构使用Iterator进行模板化。不得不做一些调整以使用船长。首先,这是在Parser中使用我所有其他规则定义的队长:

typedef qi::rule<Iterator> Skipper;
Skipper skipper;

因此skipperSkipper类型的规则。这是我的Parser结构最初的样子,它使用类型为ascii::space的{​​{1}}规则作为其船长,它与ascii::space_type的{​​{1}}类型不同{ {1}}基于!

qi::rule<Iterator>

因此规则模板中的每个skipper实例都必须替换为struct Parser : qi::grammar<Iterator, std::vector<Category>(), ascii::space_type> { qi::rule<Iterator, std::vector<Category>(), ascii::space_type> root; ... !这包括此处显示的ascii::space_type以外的其他规则,例如我的问题中的Skipperroot。留下旧param的任何遗留物会产生神秘的编译错误。

category

原始队长只是ascii::space_type,我现在可以选择struct Parser : qi::grammar<Iterator, std::vector<Category>(), qi::rule<Iterator>> { typedef qi::rule<Iterator> Skipper; Skipper skipper; qi::rule<Iterator, std::vector<Category>(), Skipper> root; ... space。没有旧功能(空间跳过)丢失。

space

然后需要从使用comment的旧版本调整skipper = space | comment; 来电:

phrase_parse

ascii::space

现在评论像白色空间一样容易消失。真棒。