简单语法的 Boost::Spirit::Qi 模板编译错误
Template compilation errors with Boost::Spirit::Qi for simple grammar
我正在尝试解析语法:
@ ( )
使用 Boost::Spirit::Qi。
我使用 phrase_parse
进行了解析,现在我正在创建语法 class(一次一个步骤)。
这是我在 Visual Studio 2010 年(在 Windows 7 上)的失败消息:
1>------ Build started: Project: Event_Grammar, Configuration: Debug Win32 ------
1> main.cpp
1>c:\boost_1_57_0\boost\spirit\home\qi\nonterminal\rule.hpp(304): error C2664: 'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const' : cannot convert parameter 4 from 'const boost::spirit::unused_type' to 'const boost::spirit::qi::char_class<Tag> '
1> with
1> [
1> R=bool,
1> T0=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>> &,
1> T1=const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>> &,
1> T2=boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<>> &,
1> T3=const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>> &
1> ]
1> and
1> [
1> Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1> ]
1> Reason: cannot convert from 'const boost::spirit::unused_type' to 'const boost::spirit::qi::char_class<Tag>'
1> with
1> [
1> Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\boost_1_57_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1> with
1> [
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> T1=boost::spirit::ascii::space_type,
1> T2=boost::spirit::unused_type,
1> T3=boost::spirit::unused_type,
1> T4=boost::spirit::unused_type,
1> Context=const boost::spirit::unused_type,
1> Skipper=boost::spirit::unused_type,
1> Attribute=const boost::spirit::unused_type
1> ]
1> c:\boost_1_57_0\boost\spirit\home\qi\detail\parse.hpp(46) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,const boost::spirit::unused_type,boost::spirit::unused_type,const boost::spirit::unused_type>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1> with
1> [
1> Subject=const boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> Context=const boost::spirit::unused_type,
1> Skipper=boost::spirit::unused_type,
1> Attribute=const boost::spirit::unused_type
1> ]
1> c:\boost_1_57_0\boost\spirit\home\qi\detail\parse_auto.hpp(166) : see reference to function template instantiation 'bool boost::spirit::qi::detail::parse_impl<Expr>::call<Iterator>(Iterator &,Iterator,const Expr &)' being compiled
1> with
1> [
1> Expr=Event_Grammar<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\mks_sandboxes\script_compiler_dissector\shared libraries\multiple platform\script language\src\event_grammar\src\event_parser.hpp(22) : see reference to function template instantiation 'bool boost::spirit::qi::parse<Iterator,Event_Grammar<Iterator,Skipper>>(Iterator &,Iterator,Expr &)' being compiled
1> with
1> [
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> Skipper=boost::spirit::ascii::space_type,
1> Expr=Event_Grammar<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type>
1> ]
1> c:\mks_sandboxes\script_compiler_dissector\shared libraries\multiple platform\script language\src\event_grammar\src\main.cpp(41) : see reference to function template instantiation 'bool Event_Parser<std::_String_const_iterator<_Elem,_Traits,_Alloc>>(Iterator,Iterator)' being compiled
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
main.cpp:
/*!
* \file main.cpp
* \brief This file contains code to validate the Script Compiler
* Event grammar.
* \note This project uses the Boost::Spirit library for parsing.
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include "event_parser.hpp"
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::double_;
using qi::_1;
using ascii::space;
using ascii::char_;
using phoenix::ref;
using qi::phrase_parse;
int main(void)
{
const char program_header[] =
"\n"
"Event Grammar Tester:\n"
" A program to validate the grammar for\n"
" a Script Language Event.\n"
"\n";
std::cout.write(program_header, sizeof(program_header) - 1);
const std::string parse_test_string = "@ ( )";
std::string token_names;
bool result = Event_Parser(parse_test_string.begin(), parse_test_string.end());
std::cout << "Parsing ";
if (result)
{
std::cout << "succeeded";
}
else
{
std::cout << "failed";
}
std::cout << " for statement \""
<< parse_test_string
<< "\"\n";
std::cout << "\nPaused. Press Enter to continue.\n";
std::cin.ignore(1000000, '\n');
return EXIT_SUCCESS;
}
event_parser.hpp
/*!
* \file event_parser.hpp
* \brief This file defines a parser Script Language Events, this is the root.
* \note This file should be used with Boost::Spirit parsers.
*/
#ifndef EVENT_PARSER_HPP
#define EVENT_PARSER_HPP
#include "event_grammar.hpp"
#include <string>
#include <boost/spirit/include/qi.hpp>
template <typename Iterator>
bool
Event_Parser(Iterator first, Iterator last)
{
using qi::parse;
using ascii::space;
using ascii::char_;
Event_Grammar<Iterator, ascii::space_type> parser;
bool result = parse(first, last, parser);
if (first != last)
return false;
return result;
}
#endif // EVENT_PARSER_HPP
event_grammar.hpp
/*!
* \file event_grammar.hpp
* \brief This class defines the grammar for the Script Language Events.
* \note This class uses features from Boost::Spirit.
*/
#ifndef EVENT_GRAMMAR_HPP
#define EVENT_GRAMMAR_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
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_('(') >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
#endif // EVENT_GRAMMAR_HPP
我只是在寻找解析器的通过或失败。
我正在使用 Boost 1.57.0。
我的语法结构中缺少什么?
我是否正确使用了解析器函数中的语法?
编译器错误会将您直接引导至此行:
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
对于 Spirit,阅读模板实例化跟踪中出现的块周围的注释是个好主意!
问题很明显,你需要通过船长。您正计划这样做:
bool result = qi::phrase_parse(first, last, parser, ascii::space);
/*!
* \file event_grammar.hpp
* \brief This class defines the grammar for the Script Language Events.
* \note This class uses features from Boost::Spirit.
*/
#ifndef EVENT_GRAMMAR_HPP
#define EVENT_GRAMMAR_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
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_('(') >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
#endif // EVENT_GRAMMAR_HPP
/*!
* \file event_parser.hpp
* \brief This file defines a parser Script Language Events, this is the root.
* \note This file should be used with Boost::Spirit parsers.
*/
#ifndef EVENT_PARSER_HPP
#define EVENT_PARSER_HPP
//#include "event_grammar.hpp"
#include <string>
#include <boost/spirit/include/qi.hpp>
template <typename Iterator>
bool Event_Parser(Iterator first, Iterator last)
{
using ascii::space;
using ascii::char_;
Event_Grammar<Iterator, ascii::space_type> parser;
bool result = qi::phrase_parse(first, last, parser, ascii::space);
if (first != last)
return false;
return result;
}
#endif //ndef EVENT_PARSER_HPP
/*!
* \file main.cpp
* \brief This file contains code to validate the Script Compiler
* Event grammar.
* \note This project uses the Boost::Spirit library for parsing.
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
//#include "event_parser.hpp"
using qi::double_;
using qi::_1;
using ascii::space;
using ascii::char_;
using phoenix::ref;
using qi::phrase_parse;
int main(void)
{
const char program_header[] =
"\n"
"Event Grammar Tester:\n"
" A program to validate the grammar for\n"
" a Script Language Event.\n"
"\n";
std::cout.write(program_header, sizeof(program_header) - 1);
const std::string parse_test_string = "@ ( )";
std::string token_names;
bool result = Event_Parser(parse_test_string.begin(), parse_test_string.end());
std::cout << "Parsing ";
if (result)
{
std::cout << "succeeded";
}
else
{
std::cout << "failed";
}
std::cout << " for statement \""
<< parse_test_string
<< "\"\n";
return EXIT_SUCCESS;
}
我正在尝试解析语法:
@ ( )
使用 Boost::Spirit::Qi。
我使用 phrase_parse
进行了解析,现在我正在创建语法 class(一次一个步骤)。
这是我在 Visual Studio 2010 年(在 Windows 7 上)的失败消息:
1>------ Build started: Project: Event_Grammar, Configuration: Debug Win32 ------
1> main.cpp
1>c:\boost_1_57_0\boost\spirit\home\qi\nonterminal\rule.hpp(304): error C2664: 'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const' : cannot convert parameter 4 from 'const boost::spirit::unused_type' to 'const boost::spirit::qi::char_class<Tag> '
1> with
1> [
1> R=bool,
1> T0=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>> &,
1> T1=const std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>> &,
1> T2=boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &,boost::fusion::nil_>,boost::fusion::vector0<>> &,
1> T3=const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>> &
1> ]
1> and
1> [
1> Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1> ]
1> Reason: cannot convert from 'const boost::spirit::unused_type' to 'const boost::spirit::qi::char_class<Tag>'
1> with
1> [
1> Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\boost_1_57_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1> with
1> [
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> T1=boost::spirit::ascii::space_type,
1> T2=boost::spirit::unused_type,
1> T3=boost::spirit::unused_type,
1> T4=boost::spirit::unused_type,
1> Context=const boost::spirit::unused_type,
1> Skipper=boost::spirit::unused_type,
1> Attribute=const boost::spirit::unused_type
1> ]
1> c:\boost_1_57_0\boost\spirit\home\qi\detail\parse.hpp(46) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,const boost::spirit::unused_type,boost::spirit::unused_type,const boost::spirit::unused_type>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1> with
1> [
1> Subject=const boost::spirit::qi::rule<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> Context=const boost::spirit::unused_type,
1> Skipper=boost::spirit::unused_type,
1> Attribute=const boost::spirit::unused_type
1> ]
1> c:\boost_1_57_0\boost\spirit\home\qi\detail\parse_auto.hpp(166) : see reference to function template instantiation 'bool boost::spirit::qi::detail::parse_impl<Expr>::call<Iterator>(Iterator &,Iterator,const Expr &)' being compiled
1> with
1> [
1> Expr=Event_Grammar<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\mks_sandboxes\script_compiler_dissector\shared libraries\multiple platform\script language\src\event_grammar\src\event_parser.hpp(22) : see reference to function template instantiation 'bool boost::spirit::qi::parse<Iterator,Event_Grammar<Iterator,Skipper>>(Iterator &,Iterator,Expr &)' being compiled
1> with
1> [
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,
1> Skipper=boost::spirit::ascii::space_type,
1> Expr=Event_Grammar<std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>,boost::spirit::ascii::space_type>
1> ]
1> c:\mks_sandboxes\script_compiler_dissector\shared libraries\multiple platform\script language\src\event_grammar\src\main.cpp(41) : see reference to function template instantiation 'bool Event_Parser<std::_String_const_iterator<_Elem,_Traits,_Alloc>>(Iterator,Iterator)' being compiled
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>,
1> Iterator=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
main.cpp:
/*!
* \file main.cpp
* \brief This file contains code to validate the Script Compiler
* Event grammar.
* \note This project uses the Boost::Spirit library for parsing.
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include "event_parser.hpp"
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::double_;
using qi::_1;
using ascii::space;
using ascii::char_;
using phoenix::ref;
using qi::phrase_parse;
int main(void)
{
const char program_header[] =
"\n"
"Event Grammar Tester:\n"
" A program to validate the grammar for\n"
" a Script Language Event.\n"
"\n";
std::cout.write(program_header, sizeof(program_header) - 1);
const std::string parse_test_string = "@ ( )";
std::string token_names;
bool result = Event_Parser(parse_test_string.begin(), parse_test_string.end());
std::cout << "Parsing ";
if (result)
{
std::cout << "succeeded";
}
else
{
std::cout << "failed";
}
std::cout << " for statement \""
<< parse_test_string
<< "\"\n";
std::cout << "\nPaused. Press Enter to continue.\n";
std::cin.ignore(1000000, '\n');
return EXIT_SUCCESS;
}
event_parser.hpp
/*!
* \file event_parser.hpp
* \brief This file defines a parser Script Language Events, this is the root.
* \note This file should be used with Boost::Spirit parsers.
*/
#ifndef EVENT_PARSER_HPP
#define EVENT_PARSER_HPP
#include "event_grammar.hpp"
#include <string>
#include <boost/spirit/include/qi.hpp>
template <typename Iterator>
bool
Event_Parser(Iterator first, Iterator last)
{
using qi::parse;
using ascii::space;
using ascii::char_;
Event_Grammar<Iterator, ascii::space_type> parser;
bool result = parse(first, last, parser);
if (first != last)
return false;
return result;
}
#endif // EVENT_PARSER_HPP
event_grammar.hpp
/*!
* \file event_grammar.hpp
* \brief This class defines the grammar for the Script Language Events.
* \note This class uses features from Boost::Spirit.
*/
#ifndef EVENT_GRAMMAR_HPP
#define EVENT_GRAMMAR_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
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_('(') >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
#endif // EVENT_GRAMMAR_HPP
我只是在寻找解析器的通过或失败。
我正在使用 Boost 1.57.0。
我的语法结构中缺少什么?
我是否正确使用了解析器函数中的语法?
编译器错误会将您直接引导至此行:
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
对于 Spirit,阅读模板实例化跟踪中出现的块周围的注释是个好主意!
问题很明显,你需要通过船长。您正计划这样做:
bool result = qi::phrase_parse(first, last, parser, ascii::space);
/*!
* \file event_grammar.hpp
* \brief This class defines the grammar for the Script Language Events.
* \note This class uses features from Boost::Spirit.
*/
#ifndef EVENT_GRAMMAR_HPP
#define EVENT_GRAMMAR_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
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_('(') >> char_(')')
)
;
}
boost::spirit::qi::rule<Iterator, Skipper> start;
};
#endif // EVENT_GRAMMAR_HPP
/*!
* \file event_parser.hpp
* \brief This file defines a parser Script Language Events, this is the root.
* \note This file should be used with Boost::Spirit parsers.
*/
#ifndef EVENT_PARSER_HPP
#define EVENT_PARSER_HPP
//#include "event_grammar.hpp"
#include <string>
#include <boost/spirit/include/qi.hpp>
template <typename Iterator>
bool Event_Parser(Iterator first, Iterator last)
{
using ascii::space;
using ascii::char_;
Event_Grammar<Iterator, ascii::space_type> parser;
bool result = qi::phrase_parse(first, last, parser, ascii::space);
if (first != last)
return false;
return result;
}
#endif //ndef EVENT_PARSER_HPP
/*!
* \file main.cpp
* \brief This file contains code to validate the Script Compiler
* Event grammar.
* \note This project uses the Boost::Spirit library for parsing.
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
//#include "event_parser.hpp"
using qi::double_;
using qi::_1;
using ascii::space;
using ascii::char_;
using phoenix::ref;
using qi::phrase_parse;
int main(void)
{
const char program_header[] =
"\n"
"Event Grammar Tester:\n"
" A program to validate the grammar for\n"
" a Script Language Event.\n"
"\n";
std::cout.write(program_header, sizeof(program_header) - 1);
const std::string parse_test_string = "@ ( )";
std::string token_names;
bool result = Event_Parser(parse_test_string.begin(), parse_test_string.end());
std::cout << "Parsing ";
if (result)
{
std::cout << "succeeded";
}
else
{
std::cout << "failed";
}
std::cout << " for statement \""
<< parse_test_string
<< "\"\n";
return EXIT_SUCCESS;
}