Parsing 如何正确解析boost-spirit中的保留词
我试图解析一系列语法:Parsing 如何正确解析boost-spirit中的保留词,parsing,boost,boost-spirit,boost-spirit-qi,Parsing,Boost,Boost Spirit,Boost Spirit Qi,我试图解析一系列语法:。例如: in float foo 其中方向可以是in、out或in\U out。通过使用qi::symbols类将方向关键字转换为枚举,我成功地解析了正确的文本 然而,当我没有正确的文本时,问题就出现了。例如: int foo 符号表解析器将删除“int”类型的“in”部分,因此结果将为: direction: in type: t name: foo 并且没有检测到错误。解析in、out和in_out保留字并确保后跟非标识符字符以使前一个文本的“int”部分失败的
in float foo
其中方向可以是in、out或in\U out。通过使用qi::symbols类将方向关键字转换为枚举,我成功地解析了正确的文本
然而,当我没有正确的文本时,问题就出现了。例如:
int foo
符号表解析器将删除“int”类型的“in”部分,因此结果将为:
direction: in
type: t
name: foo
并且没有检测到错误。解析in、out和in_out保留字并确保后跟非标识符字符以使前一个文本的“int”部分失败的最佳方法是什么
谢谢您可以使用and谓词或not谓词解析器,具体取决于您想要表达的内容。谓词解析器只检查下一个符号,但不使用它们 也就是说,您希望之后出现空白(空格或选项卡):
rule = symbol_parser >> &qi::blank;
rule = symbol_parser >> !(qi::alnum | qi::lit("_"));
也就是说,您不希望在后面有字母、数字或下划线:
rule = symbol_parser >> &qi::blank;
rule = symbol_parser >> !(qi::alnum | qi::lit("_"));
除了Mike建议的“手动”方法外,您还可以
distinct
解析器目录static const qi::rule<It, qi::unused_type(const char*)> kw
= qi::lit(qi::_r1) >> !qi::alnum;
你可以使它更方便
template <std::size_t N>
static auto kw(char const (&keyword)[N]) -> qi::rule<Iterator> {
// qi::lit has problems with char arrays, use pointer instead.
return qi::lit(+keyword) >> !qi::alnum;
}
2.使用Spirit存储库中的distinct
指令
除了Mike建议的“手动”方法外,您还可以使用Spirit存储库中的distinct
解析器指令:
intmain()
{
采用单因素检验;
使用名称空间boost::spirit;
{
使用名称空间boost::spirit::ascii;
qi:规则r;
r=distinct::关键字[“description”]>>-lit(“:”)>>distinct::关键字[“ident”];
增压测试(测试(“描述识别”,r,空格));
增压测试(测试(“描述:识别”,r,空格));
增压测试(测试(“描述:识别”,r,空格));
BOOST_测试(!TEST(“descriptionindent”,r,space));
}
返回boost::报告_错误();
}
+1而且有一些方法(在Spirit代码库中)可以实现自动化,谢谢您的回复!但我更愿意使用符号表将关键字映射到值(我将其存储为AST中的枚举)。这个方法需要我在每次检查时都编写动作语义?我可以用distinct::关键字包装符号表解析器吗?当然可以!你试过吗?而且,为了好玩,这里是kw()
符号解析器的symbols
方法:谢谢你的评论-我现在正忙于其他事情,但我会测试一下,然后再给你回复!
int main()
{
using namespace spirit_test;
using namespace boost::spirit;
{
using namespace boost::spirit::ascii;
qi::rule<char const*, space_type> r;
r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"];
BOOST_TEST(test("description ident", r, space));
BOOST_TEST(test("description:ident", r, space));
BOOST_TEST(test("description: ident", r, space));
BOOST_TEST(!test("descriptionident", r, space));
}
return boost::report_errors();
}