我正在解析一些模糊结构的输入,就像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
中放置Param
或variant
。以下是其他规则(我省略了一些与此无关的规则):
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
插入到我想要的任何地方......
答案 0 :(得分:2)
好吧,所以自己做船长也不错。正如Mike M所说,它优雅地解决了这个评论问题。我在一个名为Parser
的结构中定义了我的规则,该结构使用Iterator
进行模板化。不得不做一些调整以使用船长。首先,这是在Parser
中使用我所有其他规则定义的队长:
typedef qi::rule<Iterator> Skipper;
Skipper skipper;
因此skipper
是Skipper
类型的规则。这是我的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
以外的其他规则,例如我的问题中的Skipper
和root
。留下旧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
现在评论像白色空间一样容易消失。真棒。