提升::精神::气-将规则划分为不同的类别
Boost::Spirit::Qi - Splitting rules into separate classes
我想把我的规则(生产)分成不同的类。我在Boost::Spirit::Qi中找不到任何这样做的例子。
Boost示例都显示了一个语法类中的规则。
这是我的语法:
<start> ::= @ ( <event_bool_no_param> )
<event_bool_no_param> ::= RAMPING_COMPLETED | STATE_TIMEOUT
这是我的语法课:
template <typename Iterator, typename Skipper>
struct Event_Grammar
: boost::spirit::qi::grammar<Iterator, Skipper>
{
Event_Grammar() : Event_Grammar::base_type(start)
{
using boost::spirit::ascii::char_;
using boost::spirit::qi::eps;
start =
(
char_('@') >> char_('(') >> Event_Bool_No_Param<Iterator>() >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
这是我的另一门语法课:
template <typename Iterator>
struct Event_Bool_No_Param
: qi::grammar<Iterator>
{
Event_Bool_No_Param ()
: Event_Bool_No_Param::base_type(start)
{
using qi::lexeme;
using qi::lit;
start =
lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
;
}
qi::rule<Iterator> start;
};
我收到一个未处理的异常错误,文本为"@ ( STATE_TIMEOUT )
"。
以下是最新的堆栈跟踪:
Event_Grammar.exe!boost::spirit::qi::sequence_base<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >::parse_impl<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::unused_type>(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::spirit::unused_type & attr_, boost::mpl::bool_<0> __formal) Line 88 + 0x55 bytes C++
Event_Grammar.exe!boost::spirit::qi::sequence_base<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >::parse<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::unused_type>(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::spirit::unused_type & attr_) Line 125 C++
Event_Grammar.exe!boost::spirit::qi::detail::parser_binder<boost::spirit::qi::sequence<boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::cons<boost::spirit::qi::reference<boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type> const >,boost::fusion::cons<boost::spirit::qi::literal_char<boost::spirit::char_encoding::ascii,0,0>,boost::fusion::nil_> > > > >,boost::mpl::bool_<0> >::call<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >,boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> >,boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > >(std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & first, const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> > & last, boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<void> > & context, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii> > & skipper, boost::mpl::bool_<0> __formal) Line 44 C++
这是发生异常的代码位置,function_template.hp#761:
result_type operator()(BOOST_FUNCTION_PARMS) const
{
if (this->empty())
boost::throw_exception(bad_function_call());
return get_vtable()->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
}
所以,我的问题是:
- 所有规则都需要在同一个语法类中吗
- 如何在规则中引用语法类
- 我在上面课上的错误在哪里
我正在使用:
- 提升1.57.0
- Visual Studio 2010
- Windows 7
第一个问题:
-
所有规则都需要在同一个语法类中吗?
绝对不是。Grammars只是一种将规则分组在一起并在需要时提供额外状态的机制。语法只是一个类/结构,因此它是封装语法概念的一种非常方便的设备。
-
如何在规则中引用语法类?
你需要一个语法实例。临时的会引起悲伤。
-
我在上面课上的错误在哪里?
错误在于,您在构建规则时创建了临时规则。您需要一个语法(或规则)实例,该实例将被组成其他语法和规则。
例如,以下内容:
在Coliru上直播
#include <boost/spirit/home/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::qi::ascii;
template <typename Iterator>
struct Event_Bool_No_Param : qi::grammar<Iterator>
{
Event_Bool_No_Param ()
: Event_Bool_No_Param::base_type(start)
{
using qi::lit;
start =
lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
;
}
qi::rule<Iterator> start;
};
template <typename Iterator, typename Skipper>
struct Event_Grammar : boost::spirit::qi::grammar<Iterator, Skipper>
{
Event_Grammar() : Event_Grammar::base_type(start)
{
using boost::spirit::ascii::char_;
start =
char_('@') >> char_('(') >> event_no_param >> char_(')')
;
}
qi::rule<Iterator, Skipper> start;
Event_Bool_No_Param<Iterator> event_no_param;
};
int main()
{
using iterator_t = std::string::const_iterator;
std::string input = "@ ( STATE_TIMEOUT )";
iterator_t iter = input.begin();
iterator_t end = input.end();
Event_Grammar<iterator_t,ascii::space_type> grammar;
bool ok = qi::phrase_parse( iter, end
, grammar
, ascii::space
);
return ok? 0 : 255;
}
哪个OR
至于使用哪个OR符号,|
和||
不是一回事。你很可能想要|
。
|
-是一种替代方案。
A | B | C
- 解析
A
或B
或C
||
-是顺序或运算符(顺序或)
A || B
*解析A
,然后是可选的B
或解析B
A >> -B | B
这里有两个问题,对我来说并不明显:
- 语法变量
- 使用"||"而不是"|"
语法实例
规则可以使用其他语法,但需要有其他语法的实例。
Event_Grammar
类现在看起来像:
#include "event_bool_no_param.hpp"
template <typename Iterator, typename Skipper>
struct Event_Grammar
: boost::spirit::qi::grammar<Iterator, Skipper>
{
Event_Grammar() : Event_Grammar::base_type(start)
{
using boost::spirit::ascii::char_;
using boost::spirit::qi::eps;
using qi::lit;
// Notice the identifier "grammar_bool_no_param"
// which is an instance of the grammer / rule Event_Bool_No_Param.
start =
(
char_('@') >> char_('(') >> grammar_bool_no_param >> char_(')')
)
;
}
// *** A rule or grammar needs an instance!
Event_Bool_No_Param<Iterator> grammar_bool_no_param;
boost::spirit::qi::rule<Iterator, Skipper> start;
};
正确的"OR"符号
在规则中,"OR"的符号是"||"
,而不是"|"
:
template <typename Iterator>
struct Event_Bool_No_Param
: qi::grammar<Iterator>
{
Event_Bool_No_Param ()
: Event_Bool_No_Param::base_type(start)
{
using qi::lexeme;
using qi::lit;
start =
lit("STATE_TIMEOUT") || lit("RAMPING_COMPLETED") || lit("PASSIVE_MEAS_COMPLETED")
;
}
qi::rule<Iterator> start;
};
相关文章:
- 增强精神解析器规则以检测语句中的特殊结尾
- 提升精神 QI:在元组上自动规则演绎,在替代函数中带有序列
- 精神:不能在其规则定义中使用x3::skip(skipper)[一些递归规则]
- 使用提升精神的递归 BNF 规则
- 精神X3,如何获得属性类型以匹配规则类型
- 精神 X3:本地定义的规则定义必须附加属性
- 如何在VS2017中在提升精神x3中制定递归规则
- 提升精神范围字符规则创建空字符
- 不应用提升精神解析规则
- Boost::精神与织物方法在一条规则中
- 使用“alias()”解析精神规则时访问冲突
- 可以对提升精神规则进行参数化
- 为什么这个提升::精神::气规则不起作用
- 为什么这个提升::精神::qi规则与输入不匹配
- 将属性传递给提升精神的子规则
- 促进精神规则-规则串联
- 提升::精神::气-将规则划分为不同的类别
- 在提升精神因果报应中,如何可能将属性传递给子规则
- 当一个规则使用BOOST_FUSION_ADAPT_STRUCT时,精神因果报应语法问题
- 提升::精神::QI规则减少解析错误