我有一个 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()>
。请注意,因此这些规则没有空格跳过符。
另外,请注意,我正在尝试将内容解析为 varsym
,而不是 reservedop
。我只使用reservedop
排除 varsym 规则中的内容。
但排除 varsym 中的保留字不起作用。 ==
应该是有效的 varsym
但它被忽略,因为它以 =
开头这是 reservedop
.
另一个问题的答案建议定义类似的东西
reservedop_ %= reservedop >> !symbol
然后使用它。不过,我不确定这是否有效,而且它看起来肯定不是很优雅。
在 BOOST Spirit 中执行此操作的正确方法是什么?
最佳答案
在我看来,您混淆了词法分析和解析阶段。
he exclusion of reserved words in varsym doesn't work though. == should be a valid varsym but its ignored because it begins with = which is a 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 等
Spirit Repository 中的关键字和不同的解析器:
如果您想按照代码的建议使用从“正则表达式”定义的标记,请考虑将 Spirit 与基于 Lex 的标记生成器一起使用:
关于c++ - 解析标识符但排除 BOOST Spirit 中的保留字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13354391/