我有一个包含以下内容的SPIRIT语法:
small %= char_("a-z");
large %= char_("A-Z");
digit %= char_("0-9");
symbol %= char_("!#$%&*+./<=>?@\\^|~:") | char_('-');
special %= char_("(),;[]`{}");
graphic %= small | large | symbol | digit | special | char_('"') | char_('\'');
dashes %= lit("--")>>*lit("-");
varsym %= ((symbol-lit(':'))>>*symbol)-reservedop-dashes;
reservedop %= string("..") | string(":") | string("::") | string("=") | string("\\") | string("|") | string("<-") | string("->") | string("@") | string("~") | string("=>");
Spirit不需要单独的词法分析器和解析器(请参阅What are the Benefits of Using a Lexer?),我已经遵循这种做法,将前六个规则定义为qi::rule<Iterator, char()>
,将最后三个规则定义为{qi::rule<Iterator, std::string()>
1}}。请注意,这些规则因此没有空白队长。
另请注意,我正在尝试将内容解析为varsym
,而不是reservedop
。我只使用reservedop
来排除varsym规则中的内容。
在varsym中排除保留字不起作用。 ==
应该是有效的varsym
,但会被忽略,因为它以=
reservedop
开头。
另一个问题的答案建议定义类似
的内容 reservedop_ %= reservedop >> !symbol
然后使用它。我不确定这是否有效,但它看起来并不优雅。
在BOOST Spirit中这样做的正确方法是什么?
答案 0 :(得分:2)
在我看来,你很困惑lexing和解析阶段。
他在varsym中排除保留字不起作用。 ==应该是一个有效的varsym,但它被忽略,因为它以=开头,这是一个reservedop。
对于显示的代码,该声明没有多大意义,因为您从未展示过如何使用规则:
rule1 = varsym | reservedop; // would parse "==" as varsym
rule2 = reservedop | varsym; // would parse "==" as reservedop
看看
qi :: graph,qi :: alpha,qi :: alnum,qi :: lower,qi :: upper etc。
Spirit Repository中的关键字和不同解析器:
如果您想使用由“正则表达式”定义的标记,就像您的代码似乎建议的那样,请查看使用Spirit和基于Lex的标记生成器: