2

我有一个 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 不需要单独的词法分析器和解析器(请参阅使用词法分析器的好处是什么?),我遵循这种做法,将前六个规则定义为qi::rule<Iterator, char()>,将后三个规则定义为qi::rule<Iterator, std::string()>。请注意,这些规则因此没有空格跳过。

另外,请注意,我试图将事物解析为varsym,而不是reservedop。我只是reservedop用来排除 varsym 规则中的东西。

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

另一个问题的答案建议定义类似

    reservedop_ %= reservedop >> !symbol

然后使用它。不过,我不确定这是否有效,而且它看起来当然不是很优雅。

在 BOOST Spirit 中执行此操作的正确方法是什么?

4

1 回答 1

2

在我看来,您混淆了词法分析和解析阶段。

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

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

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

看着

如果您想使用从“正则表达式”定义的标记,正如您的代码所建议的那样,请查看将 Spirit 与基于 Lex 的标记器一起使用:

于 2012-11-13T08:27:53.100 回答