parser.hpp
在将语法拆分为推荐的, parser_def.hpp
,parser.cpp
文件后,我遇到了 boost spirit x3 的一种奇怪行为。我的示例语法解析了一些简单的枚举:
enum = "enum" > identifier > "{" > identifier % "," > "}
这是我的枚举语法。当我不将枚举和标识符解析器拆分为推荐的文件时,一切正常,尤其是字符串"enum {foo, bar}"
按预期抛出预期失败。这个例子可以在这里找到:未拆分的工作示例
但是当我将完全相同的语法拆分为不同的文件时,解析器会抛出
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
试图解析相同的字符串"enum {foo, bar}"
这个例子可以在这里找到:分裂奇怪的例子
ast.hpp
#pragma once #include <vector> #include <string> #include <boost/fusion/include/adapt_struct.hpp> namespace ast{ namespace x3 = boost::spirit::x3; struct Enum { std::string _name; std::vector<std::string> _elements; }; } BOOST_FUSION_ADAPT_STRUCT(ast::Enum, _name, _elements)
配置文件
#pragma once #include <boost/spirit/home/x3.hpp> namespace parser{ namespace x3 = boost::spirit::x3; typedef std::string::const_iterator iterator_type; typedef x3::phrase_parse_context<x3::ascii::space_type>::type context_type; }
枚举.cpp
#include "enum_def.hpp" #include "config.hpp" namespace parser { namespace impl { BOOST_SPIRIT_INSTANTIATE(enum_type, iterator_type, context_type) }} namespace parser { const impl::enum_type& enum_parser() { return impl::enum_parser; } }
枚举定义.hpp
#pragma once #include "identifier.hpp" #include "enum.hpp" #include "ast.hpp" namespace parser{ namespace impl{ namespace x3=boost::spirit::x3; const enum_type enum_parser = "enum"; namespace{ const auto& identifier = parser::identifier(); } auto const enum_parser_def = "enum" > identifier > "{" > identifier % "," >"}"; BOOST_SPIRIT_DEFINE(enum_parser) }}
枚举.hpp
#pragma once #include <boost/spirit/home/x3.hpp> #include "ast.hpp" namespace parser{ namespace impl{ namespace x3=boost::spirit::x3; typedef x3::rule<class enum_class, ast::Enum> enum_type; BOOST_SPIRIT_DECLARE(enum_type) }} namespace parser{ const impl::enum_type& enum_parser(); }
标识符.cpp
#include "identifier_def.hpp" #include "config.hpp" namespace parser { namespace impl { BOOST_SPIRIT_INSTANTIATE(identifier_type, iterator_type, context_type) }} namespace parser { const impl::identifier_type& identifier() { return impl::identifier; } }
标识符_def.hpp
#pragma once #include <boost/spirit/home/x3.hpp> #include "identifier.hpp" namespace parser{ namespace impl{ namespace x3=boost::spirit::x3; const identifier_type identifier = "identifier"; auto const identifier_def = x3::lexeme[ ((x3::alpha | '_') >> *(x3::alnum | '_')) ]; BOOST_SPIRIT_DEFINE(identifier) }}
标识符.hpp
#pragma once #include <boost/spirit/home/x3.hpp> namespace parser{ namespace impl{ namespace x3=boost::spirit::x3; typedef x3::rule<class identifier_class, std::string> identifier_type; BOOST_SPIRIT_DECLARE(identifier_type) }} namespace parser{ const impl::identifier_type& identifier(); }
主文件
#include <boost/spirit/home/x3.hpp> #include "ast.hpp" #include "enum.hpp" namespace x3 = boost::spirit::x3; template<typename Parser, typename Attribute> bool test(const std::string& str, Parser&& p, Attribute&& attr) { using iterator_type = std::string::const_iterator; iterator_type in = str.begin(); iterator_type end = str.end(); bool ret = x3::phrase_parse(in, end, p, x3::ascii::space, attr); ret &= (in == end); return ret; } int main(){ ast::Enum attr; test("enum foo{foo,bar}", parser::enum_parser(), attr); test("enum {foo,bar}", parser::enum_parser(), attr); }
这是一个错误,我错过了什么,还是这是一个预期的行为?
编辑:这是我的回购与一个抛出一个std::logic_error
而不是一个例子expectation_failure