完成你想要的東西的方法是專精assign_to_attribute_from_iterators
。您可以找到一個自定義類型here的示例。如果您在令牌定義中使用double
作爲屬性,則spirit在內部使用qi::double_
來解析該值。 (你可以找到here雙重和其他基本類型的專業化)。
傻的例子中我定義real
令牌作爲任何不是一個,
或;
顯示的double
S中解析。
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace mpl = boost::mpl;
template <typename Lexer>
struct my_lexer : lex::lexer<Lexer>
{
my_lexer()
{
real = "[^,;]*"; //anything that is not a , or ; is a real number
this->self=lex::token_def<lex::omit>(',')| ';';
this->self.add(real);
}
lex::token_def<double> real;
};
int main()
{
// the token type needs to know the iterator type of the underlying
// input and the set of used token value types
typedef lex::lexertl::token<std::string::iterator,
mpl::vector<double> > token_type;
// use actor_lexer<> here if your token definitions have semantic
// actions
typedef lex::lexertl::lexer<token_type> lexer_type;
// this is the iterator exposed by the lexer, we use this for parsing
typedef lexer_type::iterator_type iterator_type;
// create a lexer instance
std::string input("3.4,2,.4,4.,infinity,NaN,-3.8,1e2,1.5E3;");
std::string::iterator s = input.begin();
my_lexer<lexer_type> lex;
iterator_type b = lex.begin(s, input.end());
// use the embedded token_def as a parser, it exposes its token value type
// as its parser attribute type
std::vector<double> result;
qi::rule<iterator_type,double()> number= lex.real;
qi::rule<iterator_type,std::vector<double>()> sequence= number >> *(',' >> number) >> ';';
BOOST_SPIRIT_DEBUG_NODE(number);
BOOST_SPIRIT_DEBUG_NODE(sequence);
if (!qi::parse(b, lex.end(), sequence, result))
{
std::cerr << "Parsing failed!" << std::endl;
return -1;
}
std::cout << "Parsing succeeded:" << std::endl;
for(auto& n : result)
std::cout << n << std::endl;
return 0;
}
編輯:我用正則表達式的經驗非常少,但我相信,定義等同於評論鏈接的語法令牌(我認爲應該有fractional_constant >> -exponent_part
,而不是fractional_constant >> !exponent_part
)會:
template <typename Lexer>
struct my_lexer : lex::lexer<Lexer>
{
my_lexer()
{
this->self.add_pattern("SIGN","[\\+\\-]");
this->self.add_pattern("NAN","(1\\.0#)?(?i:nan)(\\([^\\)]\\))?");
this->self.add_pattern("INF","(?i:inf(inity)?)");
this->self.add_pattern("DIGIT","[0-9]");
this->self.add_pattern("FRACT_CONST","{DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.?");
this->self.add_pattern("EXP","[eE]{SIGN}?{DIGIT}+");
real = "{SIGN}?({NAN}|{INF}|{FRACT_CONST}{EXP}?|{DIGIT}+{EXP})";
this->self=lex::token_def<lex::omit>(',')| ';';
this->self.add(real);
}
lex::token_def<double> real;
};
謝謝!這真是太棒了!圖書館非常靈活,它在最令人意想不到的情況下爲您提前思考。我印象深刻...... – Orient
如何正確表達[語法](http://www.boost.org/doc/libs/1_52_0/libs/spirit/doc/html/spirit/qi/reference/numeric/real。 html#spirit.qi.reference.numeric.real._code__phrase_role__identifier__realpolicies__phrase ___ code_)通過相應的正則表達式?匹配他所有的案例。 – Orient
@Dukales我已經添加了我認爲應該是基於該語法的令牌定義。它在我的「愚蠢的例子」中起作用。 – 2013-01-12 12:51:18