- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 boost spirit x3 创建了一个语法。在测试我生成的解析器时,我认识到存在解析器抛出以下异常的情况:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
我不知道使用 boost spirit x3 会发生这种情况,我认为解析方法 eighter 返回 false 或抛出 boost::spirit::x3::expectation_failure
,我做错了什么语法,因为这不应该发生在这里。我上传了我的 mcve HERE ,如果您执行二进制文件,则会抛出 std::logic 错误。
例子.cpp
#include "example_def.hpp"
#include "config.hpp"
namespace client { namespace parser {
BOOST_SPIRIT_INSTANTIATE(var_dec_type, iterator_type, context_type)
}}
main.cpp
#include <iostream>
//#define SINGLE_TU
#if defined(SINGLE_TU)
#pragma message "yesdef(SINGLE_TU)"
#else
#pragma message "notdef(SINGLE_TU)"
#endif
#ifdef SINGLE_TU
#include "types_def.hpp"
#include "example_def.hpp"
#else
#include "example.hpp"
#endif
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 = boost::spirit::x3::phrase_parse(in, end, p, boost::spirit::x3::ascii::space, attr);
ret &= (in == end);
return ret;
}
int main()
{
client::ast::VariableDec attr;
std::cout << test("var foo : foo<bar, baz<bahama>>", client::var_dec() , attr);
return 0;
}
类型.cpp
#include "config.hpp"
#include "types_def.hpp"
#include <iostream>
namespace client {namespace parser {
BOOST_SPIRIT_INSTANTIATE(type_type, iterator_type, context_type);
BOOST_SPIRIT_INSTANTIATE(class_type_type, iterator_type, context_type);
#define PARSE_RULE_BODY
#if defined(PARSE_RULE_BODY)
#pragma message "yesdef(PARSE_RULE_BODY)"
//This causes the parse_rule generated by
//BOOST_SPIRIT_DEFINE for type
//to *not* be used.
#include <boost/fusion/iterator/deref.hpp>
#else
#pragma message "notdef(PARSE_RULE_BODY)"
//This causes the parse_rule generated by
//BOOST_SPIRIT_DEFINE for type
//to be used.
#endif
#define SEHE_TYPES_DEF_HPP_PASTE
#define EXPLICT_SPECIALIZATION_FROM_LINKER_ERROR_MSG
#if defined(SEHE_TYPES_DEF_HPP_PASTE)
#pragma message "yesdef(SEHE_TYPES_DEF_HPP_PASTE)"
//Source:
// The following code was copy&pasted&reformatted from lines 38-53 of:
// https://github.com/sehe/linker_error_example/blob/explicit_instantiation/types_def.hpp
// on about 2016-11-15.
// with minor modifications:
// * reformatting
// * Added body with:
// * printing first..last.
//=======================
namespace {
template <typename Seq, size_t N>
using field_at =
boost::fusion::basic_iterator
< boost::fusion::struct_iterator_tag
, boost::fusion::random_access_traversal_tag
, Seq
, N
>;
template <typename Seq, size_t N, size_t M>
using fields =
boost::fusion::iterator_range<field_at<Seq, N>, field_at<Seq, M> >;
using Attributes =
fields<client::ast::VariableDec, 1, 2>;
using Context =
x3::context
< x3::skipper_tag
, x3::char_class<boost::spirit::char_encoding::ascii, x3::space_tag> const
, x3::unused_type
>;
}
template
#ifdef PARSE_RULE_BODY
<>
#endif
bool parse_rule
< std::string::const_iterator
, Context
, Attributes
>(
decltype(type) rule,
std::string::const_iterator &first,
std::string::const_iterator const &last,
Context const &context,
Attributes &attr)
#ifndef PARSE_RULE_BODY
;
#else
{
std::cout<<"***in function="<<__func__<<"\n";
std::string::const_iterator beg=first;
std::cout<<":input=\n{";
for(; beg!=last; ++beg) std::cout<<*beg;
std::cout<<"}\n";
using required_t=type_type::attribute_type;
required_t required_v=boost::fusion::deref(attr.first);
//attr type required by parse_rule generated by:
// BOOST_SPIRIT_INSTANTIATE(type_type, iterator_type, context_type)
;
bool result=parse_rule(rule,first,last,context,required_v)
//This should call the parse_rule generated by:
// BOOST_SPIRIT_INSTANTIATE(type_type, iterator_type, context_type)
;
std::cout<<":result="<<result<<"\n";
return result;
}
#endif
#elif defined(EXPLICT_SPECIALIZATION_FROM_LINKER_ERROR_MSG)
#pragma message "yesdef(EXPLICT_SPECIALIZATION_FROM_LINKER_ERROR_MSG)"
template
#ifdef PARSE_RULE_BODY
<>
#endif
//The following simply copied&pasted from an earlier linker error
//message, and then reformatted to clarify what
//was being specialized.
bool
parse_rule
< __gnu_cxx::__normal_iterator
< char const*
, std::__cxx11::basic_string
< char
, std::char_traits<char>
, std::allocator<char>
>
>
, boost::spirit::x3::context
< boost::spirit::x3::skipper_tag
, boost::spirit::x3::char_class
< boost::spirit::char_encoding::ascii
, boost::spirit::x3::space_tag
> const
, boost::spirit::x3::unused_type
>
, boost::fusion::iterator_range
< boost::fusion::basic_iterator
< boost::fusion::struct_iterator_tag
, boost::fusion::random_access_traversal_tag
, client::ast::VariableDec
, 1
>
, boost::fusion::basic_iterator
< boost::fusion::struct_iterator_tag
, boost::fusion::random_access_traversal_tag
, client::ast::VariableDec
, 2
>
>
>
( boost::spirit::x3::rule//==decltype(type) where types from types_def.hpp:16
< client::parser::type_class//types.hpp:15
, boost::spirit::x3::variant
< client::ast::nil
, boost::spirit::x3::forward_ast
< client::ast::LambdaType
>
, boost::spirit::x3::forward_ast
< client::ast::ClassType
>
>
, false
>
, __gnu_cxx::__normal_iterator//==std::string::const_iterator
< char const*
, std::__cxx11::basic_string
< char
, std::char_traits<char>
, std::allocator<char>
>
>& first
, __gnu_cxx::__normal_iterator//==std::string::const_iterator
< char const*
, std::__cxx11::basic_string
< char
, std::char_traits<char>
, std::allocator<char>
>
> const& last
, boost::spirit::x3::context//=?Context from #if defined(SEHE_TYPES_DEF_HPP_PASTE)
< boost::spirit::x3::skipper_tag
, boost::spirit::x3::char_class
< boost::spirit::char_encoding::ascii
, boost::spirit::x3::space_tag
> const
, boost::spirit::x3::unused_type
> const& context
, boost::fusion::iterator_range//=?Attributes from #if defined(SEHE_TYPES_DEF_HPP_PASTE)
< boost::fusion::basic_iterator
< boost::fusion::struct_iterator_tag
, boost::fusion::random_access_traversal_tag
, client::ast::VariableDec
, 1
>
, boost::fusion::basic_iterator
< boost::fusion::struct_iterator_tag
, boost::fusion::random_access_traversal_tag
, client::ast::VariableDec
, 2
>
>& attr
)
#ifndef PARSE_RULE_BODY
;
#else
{
std::cout<<"***in function="<<__func__<<"\n";
std::string::const_iterator beg=first;
std::cout<<":input=\n{";
for(; beg!=last; ++beg) std::cout<<*beg;
std::cout<<"}\n";
return false;
}
#endif//PARSE_RULE_BODY
#endif//(SEHE_TYPES_DEF_HPP_PASTE)
}}
ast.hpp
//
// Created by lukas on 11.11.16.
//
#ifndef LINKER_ERROR_EXAMPLE_AST_HPP_HPP
#define LINKER_ERROR_EXAMPLE_AST_HPP_HPP
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <vector>
#include <string>
namespace client { namespace ast {
namespace x3 = boost::spirit::x3;
struct LambdaType;
struct ClassType;
struct nil{};
typedef x3::variant <
nil,
x3::forward_ast<LambdaType>,
x3::forward_ast<ClassType>
> Type;
struct LambdaType {
std::vector<Type> parameters_;
Type return_type_;
};
struct ClassType {
std::vector<std::string> name_;
std::vector<Type> template_args_;
};
struct VariableDec {
std::string _name;
Type _type;
};
}}
BOOST_FUSION_ADAPT_STRUCT(client::ast::LambdaType, parameters_, return_type_)
BOOST_FUSION_ADAPT_STRUCT(client::ast::ClassType, name_, template_args_)
BOOST_FUSION_ADAPT_STRUCT(client::ast::VariableDec, _name, _type)
#endif //LINKER_ERROR_EXAMPLE_AST_HPP_HPP
配置.hpp
#ifndef LINKER_ERROR_EXAMPLE_CONFIG_HPP
#define LINKER_ERROR_EXAMPLE_CONFIG_HPP
#include <boost/spirit/home/x3.hpp>
namespace client{
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;
}
}
#endif //LINKER_ERROR_EXAMPLE_CONFIG_HPP
example_def.hpp
#ifndef LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
#define LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
#include "ast.hpp"
#include "example.hpp"
#include "types.hpp"
namespace client { namespace parser {
#ifndef SINGLE_TU
namespace { const auto& type = client::type(); }
#endif
const var_dec_type var_dec = "var_dec";
#define EXAMPLE_DEF_LINK_ERR
#if defined(EXAMPLE_DEF_LINK_ERR)
#pragma message "yesdef(EXAMPLE_DEF_LINK_ERR)"
#else
#pragma message "notdef(EXAMPLE_DEF_LINK_ERR)"
#endif
auto const var_dec_def = x3::lexeme["var "]
> +x3::alnum
> ":"
#ifdef EXAMPLE_DEF_LINK_ERR
>> type //<- this gets linker error.
#else
> type //<- This links.
#endif
> ";";
BOOST_SPIRIT_DEFINE(
var_dec
)
}}
namespace client {
const parser::var_dec_type& var_dec()
{
return parser::var_dec;
}
}
#endif //LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
例子.hpp
#ifndef LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
#define LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
class var_dec_class {};
typedef x3::rule<var_dec_class, ast::VariableDec> var_dec_type;
BOOST_SPIRIT_DECLARE(var_dec_type)
}}
namespace client {
const parser::var_dec_type& var_dec();
}
#endif //LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
types_def.hpp
#ifndef KYLE_TYPES_DEF_HPP
#define KYLE_TYPES_DEF_HPP
#include "types.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
typedef x3::rule<struct lambda_type_class, ast::LambdaType> lambda_type_type;
const class_type_type class_type = "class_type";
const lambda_type_type lambda_type = "lambda_type";
const type_type type = "type";
auto const identifier = +x3::alnum;
auto const type_def =
(lambda_type | class_type);
auto const lambda_type_def =
("(" > -(type % ",") > ")" > "=>" > type)
| (x3::repeat(1)[class_type] >> "=>" > type);
auto const class_type_def =
(identifier % "::") >> -("<" > type % "," > ">");
BOOST_SPIRIT_DEFINE(
lambda_type,
class_type,
type
)
}}
namespace client {
const parser::class_type_type& class_type()
{
return parser::class_type;
}
const parser::type_type& type()
{
return parser::type;
}
}
#endif //KYLE_TYPES_DEF_HPP
类型.hpp
#ifndef KYLE_PARSER_TYPES_HPP
#define KYLE_PARSER_TYPES_HPP
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
struct class_type_class;
struct type_class;
typedef x3::rule<class_type_class, ast::ClassType> class_type_type;
typedef x3::rule<type_class, ast::Type> type_type;
BOOST_SPIRIT_DECLARE(class_type_type,
type_type)
}}
namespace client {
const parser::class_type_type& class_type();
const parser::type_type& type();
}
#endif
最佳答案
它抛出一个 expectation_failed 异常。
很明显,这是因为您缺少 ;
。
在清除了与旧的链接器错误解决方法相关的可怕错误之后,我只是将 example_def
表达式更改为:
auto const var_dec_def = x3::lexeme["var "] > +x3::alnum >> (":" > type) > ";";
现在,添加适当的错误处理:
int main()
{
client::ast::VariableDec attr;
std::string const input("var foo : foo<bar, baz<bahama>>;");
try {
std::cout << test(input, client::var_dec() , attr);
} catch(boost::spirit::x3::expectation_failure<std::string::const_iterator> const& e) {
std::cout << "Expected: " << e.which() << " at '" << std::string(e.where(), input.end()) << "'\n";
return 255;
}
}
打印:
1
省略尾随 ;
打印:
Expected: ';' at ''
完整演示:error-handling分支机构
CMakeLists.txt | 6 +-
example.cpp | 9 +++
example_def.hpp | 33 +--------
main.cpp | 20 ++----
types.cpp | 203 ++++----------------------------------------------------
types_def.hpp | 20 ++----
6 files changed, 38 insertions(+), 253 deletions(-)
例子.cpp
#include "example_def.hpp"
#include "config.hpp"
namespace client { namespace parser {
BOOST_SPIRIT_INSTANTIATE(var_dec_type, iterator_type, context_type)
}}
namespace client {
const parser::var_dec_type& var_dec()
{
return parser::var_dec;
}
}
main.cpp
#include <iostream>
#include "example.hpp"
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 = boost::spirit::x3::phrase_parse(in, end, p, boost::spirit::x3::ascii::space, attr);
ret &= (in == end);
return ret;
}
int main()
{
client::ast::VariableDec attr;
std::string const input("var foo : foo<bar, baz<bahama>>");
try {
std::cout << test(input, client::var_dec() , attr);
} catch(boost::spirit::x3::expectation_failure<std::string::const_iterator> const& e) {
std::cout << "Expected: " << e.which() << " at '" << std::string(e.where(), input.end()) << "'\n";
return 255;
}
}
类型.cpp
#include "config.hpp"
#include "types_def.hpp"
namespace client {namespace parser {
BOOST_SPIRIT_INSTANTIATE(type_type, iterator_type, context_type);
BOOST_SPIRIT_INSTANTIATE(class_type_type, iterator_type, context_type);
}}
namespace client {
const parser::class_type_type& class_type()
{
return parser::class_type;
}
const parser::type_type& type()
{
return parser::type;
}
}
ast.hpp
//
// Created by lukas on 11.11.16.
//
#ifndef LINKER_ERROR_EXAMPLE_AST_HPP_HPP
#define LINKER_ERROR_EXAMPLE_AST_HPP_HPP
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <vector>
#include <string>
namespace client { namespace ast {
namespace x3 = boost::spirit::x3;
struct LambdaType;
struct ClassType;
struct nil{};
typedef x3::variant <
nil,
x3::forward_ast<LambdaType>,
x3::forward_ast<ClassType>
> Type;
struct LambdaType {
std::vector<Type> parameters_;
Type return_type_;
};
struct ClassType {
std::vector<std::string> name_;
std::vector<Type> template_args_;
};
struct VariableDec {
std::string _name;
Type _type;
};
}}
BOOST_FUSION_ADAPT_STRUCT(client::ast::LambdaType, parameters_, return_type_)
BOOST_FUSION_ADAPT_STRUCT(client::ast::ClassType, name_, template_args_)
BOOST_FUSION_ADAPT_STRUCT(client::ast::VariableDec, _name, _type)
#endif //LINKER_ERROR_EXAMPLE_AST_HPP_HPP
配置.hpp
#ifndef LINKER_ERROR_EXAMPLE_CONFIG_HPP
#define LINKER_ERROR_EXAMPLE_CONFIG_HPP
#include <boost/spirit/home/x3.hpp>
namespace client{
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;
}
}
#endif //LINKER_ERROR_EXAMPLE_CONFIG_HPP
example_def.hpp
#ifndef LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
#define LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
#include "ast.hpp"
#include "example.hpp"
#include "types.hpp"
namespace client { namespace parser {
namespace { const auto& type = client::type(); }
const var_dec_type var_dec = "var_dec";
auto const var_dec_def = x3::lexeme["var "] > +x3::alnum >> (":" > type) > ";";
BOOST_SPIRIT_DEFINE(var_dec)
}}
#endif //LINKER_ERROR_EXAMPLE_EXAMPLE_DEF_HPP
例子.hpp
#ifndef LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
#define LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
class var_dec_class {};
typedef x3::rule<var_dec_class, ast::VariableDec> var_dec_type;
BOOST_SPIRIT_DECLARE(var_dec_type)
}}
namespace client {
const parser::var_dec_type& var_dec();
}
#endif //LINKER_ERROR_EXAMPLE_EXAMPLE_HPP
types_def.hpp
#ifndef KYLE_TYPES_DEF_HPP
#define KYLE_TYPES_DEF_HPP
#include "types.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
typedef x3::rule<struct lambda_type_class, ast::LambdaType> lambda_type_type;
const class_type_type class_type = "class_type";
const lambda_type_type lambda_type = "lambda_type";
const type_type type = "type";
auto const identifier = +x3::alnum;
auto const type_def =
(lambda_type | class_type);
auto const lambda_type_def =
("(" > -(type % ",") > ")" > "=>" > type)
| x3::repeat(1)[class_type] >> "=>" > type;
auto const class_type_def =
(identifier % "::") >> -("<" > type % "," > ">");
BOOST_SPIRIT_DEFINE(
lambda_type,
class_type,
type
)
}}
#endif //KYLE_TYPES_DEF_HPP
类型.hpp
#ifndef KYLE_PARSER_TYPES_HPP
#define KYLE_PARSER_TYPES_HPP
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
namespace client { namespace parser {
namespace x3 = boost::spirit::x3;
struct class_type_class;
struct type_class;
typedef x3::rule<class_type_class, ast::ClassType> class_type_type;
typedef x3::rule<type_class, ast::Type> type_type;
BOOST_SPIRIT_DECLARE(class_type_type,
type_type)
}}
namespace client {
const parser::class_type_type& class_type();
const parser::type_type& type();
}
#endif
关于c++ - Boost spirit x3 解析器在解析时抛出 std::logic_error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40667770/
最近我从旧版本的 firebase 切换到最新版本。切换后,由于错误,我无法编译我的应用程序(即使不使用 firebase 代码) third_party/java/android/android_n
c++ 标准说 logic_error 可以在运行前检测到而 runtime_error 在运行时检测。 但是它是如何工作的呢?我的问题是如何在运行前检测 logic_error。你能给我举个例子吗?
我有一个通用数组类,如果它与非原始类型一起使用,它会抛出一个 logic_error。 模板类: #include #include #include using namespace st
如果你在代码中使用 std::logic_error 异常,你会在什么情况下使用它? 最佳答案 logic_error 是这些异常的基础:domain_error、invalid_argument、l
我希望能够捕捉到不同的 logic_errors并且能够区分它们。我能否以某种方式将附加参数传递给稍后要捕获的逻辑错误。这个想法是我需要打印。现在我只是捕捉到 stof 的默认错误可以返回。 “抱歉无
我的 cs 类任务是创建两个继承自 std::logic_error 的自定义异常类:OverflowingSwimmingPoolException 和 UnderflowingSwimmingPo
我的 C++ 程序以 std::logic_error 退出,我想追踪导致它的源代码行。我该怎么做? TBH,我正在使用 gdb,使用 g++ -g 来添加调试信息。我只能得到这些消息: 此应用程序已
我正在寻找某人对 std::logic_error 用法的意见,而不是使用复杂的嵌套 if/elseif 列表返回 true/false。 我想从很多类似的函数中移动,如下面的函数 bool vali
我想根据 stdexcept 的逻辑错误创建自己的错误。我尝试了以下并面临错误,我的猜测是,这不是正确的做法。我无法在谷歌或以前的堆栈溢出问题上找到答案,请原谅我的菜鸟。 // Header clas
我使用 boost spirit x3 创建了一个语法。在测试我生成的解析器时,我认识到存在解析器抛出以下异常的情况: terminate called after throwing an insta
我已经使用一个类来编写一些代码来显示一个盒子的尺寸。我这样做是通过在 toString() 方法中输出,它似乎可以正常工作,但是当我运行该程序时,出现以下错误: Height: 1 Width: 1
我正在尝试使用 C++ 和 MongoDB 完成一些工作。到目前为止,出现了无数问题,但我都挺过来了。 然后我得到了这个: terminate called after throwing an ins
让我们看一下派生自 std::logic_error 的类: std::out_of_range 当参数超出范围时抛出。 std::length_error 当指定长度的参数超出支持的值时抛出。 st
我在这个程序中收到 std::logic_error: basic_string::_s_construct null not valid。我该如何解决?我已经尝试过 previously poste
我正在尝试实现自定义异常层次结构并允许适当的 std::* 被代码捕获。 class my_exception : public virtual std::exception { }; class m
以下是说明: 在第 10 章中,clockType 类被设计用来在程序中实现一天中的时间。除了小时、分钟和秒之外,某些应用程序可能需要您存储时区。 从类 clockType 派生类 extClockT
我最近看到,如果命令行输入不可解析,boost program_options 库会抛出 logic_error。这挑战了我对 logic_error 与 runtime_error 的假设。 我认为
我正在尝试检查输入字符串是字母数字还是大写或空。如果输入字符串在上述出现故障的字符串中,我只想返回 false/0 否则与工作正常的程序的其余部分一起工作。我的程序块有问题: std::string
我一直在尝试将 cfg 读入多重链接列表,但我收到此错误,请有人帮忙。它不断给出这个错误。我不认为有什么错误。请检查这段代码并告诉我哪里有错误导致程序崩溃并出现图片中所附的异常 #include
我不确定是什么导致了这个问题,我正在创建一个井字游戏,您可以在其中与计算机对战。 我没有尝试过任何东西,因为我不知道这个错误是什么意思。 #include #include #include #
我是一名优秀的程序员,十分优秀!