解析标识符,但不包括BOOST Spirit中的保留字

时间:2012-11-13 01:31:51

标签: c++ parsing boost boost-spirit

我有一个包含以下内容的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中这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

在我看来,你很困惑lexing和解析阶段。

  

他在varsym中排除保留字不起作用。 ==应该是一个有效的varsym,但它被忽略,因为它以=开头,这是一个reservedop。

对于显示的代码,该声明没有多大意义,因为您从未展示过如何使用规则:

 rule1 = varsym | reservedop; // would parse "==" as varsym
 rule2 = reservedop | varsym; // would parse "==" as reservedop

看看

如果您想使用由“正则表达式”定义的标记,就像您的代码似乎建议的那样,请查看使用Spirit和基于Lex的标记生成器:

相关问题