我在編寫使用另一個Qi語法的Qi語法時遇到了困難。一個類似的問題被問到here,但我也試圖使用phoenix ::構造和編譯困難。boost:spirit :: qi parser using multiple grammars and phoenix :: construct
下面是我試圖做的簡化版本。我意識到這個例子可能很容易使用BOOST_FUSION_ADAPT_STRUCT
完成,但我的實際代碼處理更復雜的對象類型,所以我希望有一種方法可以使用語義操作來完成此操作。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <cstdlib>
#include <iostream>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
// grammar for real numbers
template <typename Iterator>
struct Real : qi::grammar<Iterator, long double()>
{
qi::rule<Iterator, long double()> r;
Real() : Real::base_type(r)
{
r %= qi::long_double;
}
};
// grammar for complex numbers of the form a+bi
template <typename Iterator>
struct Complex : qi::grammar<Iterator, std::complex<long double>()>
{
qi::rule<Iterator, std::complex<long double>()> r;
Real<Iterator> real;
Complex() : Complex::base_type(r)
{
r = real [qi::_a = qi::_1] >> (qi::lit("+") | qi::lit("-"))
>> real [qi::_b = qi::_1] >> -qi::lit("*") >> qi::lit("i")
[
qi::_val = phx::construct<std::complex<long double> >(qi::_a, qi::_b)
];
}
};
int main()
{
// test real parsing
std::cout << "Parsing '3'" << std::endl;
std::string toParse = "3";
Real<std::string::iterator> real_parser;
long double real_val;
std::string::iterator beginIt = toParse.begin();
std::string::iterator endIt = toParse.end();
bool r = qi::parse(beginIt, endIt, real_parser, real_val);
if(r && beginIt == endIt)
std::cout << "Successful parse: " << real_val << std::endl;
else
std::cout << "Could not parse" << std::endl;
// test complex parsing
std::cout << "Parsing '3+4i'" << std::endl;
toParse = "3+4i";
Complex<std::string::iterator> complex_parser;
std::complex<long double> complex_val;
beginIt = toParse.begin();
endIt = toParse.end();
r = qi::parse(beginIt, endIt, complex_parser, complex_val);
if(r && beginIt == endIt)
std::cout << "Successful parse: " << real_val << std::endl;
else
std::cout << "Could not parse" << std::endl;
}
我可以在使用精神的文檔中表現出的phrase_parse方法來解析複雜,但我希望能夠輕鬆地集成複雜的語法到其它解析器(一個表達式解析器,例如)。是否有我錯過的東西可以讓我將Real和Complex對象解析爲不同的實體,同時還能夠在其他規則/語法中有效地使用它們?
之前不知怎的,錯過了這個質量答案。我很高興看到一位「專家」(哈哈)對Boost(精神)問題感興趣。歡迎來到社區,@llonesmiz – sehe 2012-09-11 07:39:33