Giriş
Şu satırı dahil ederiz.
Bu sınıfı şöyle kullanırız. Üçüncü parametre olarak geçeriz.
Şöyle yaparız.
Şöyle yaparız.
output type iterator gibi () karakterleri ile bitmelidir. Şöyle yaparız.
Elimizde şöyle bir kod olsun.
Şöyle yaparız
Şöyle yaparız. Bu rule hem attribute olarak int verir, hem de raw data'yı boost::iterator_range olarak verir.
Şöyle yaparız.
Skipper olarak ascii::space_type veya ascii::blank_type kullanılıyor. Ancak ascii::space_type bende derleme hatası verdi. ascii::blank_type sorunsuz çalışıyor.
Şu tanımlama yanlış
Şöyle yaparız.
Şöyle yaparız
Şu satırı dahil ederiz.
#include <boost/spirit/include/qi.hpp>
Kolay kullanım için şu satırı dahil ederiz.namespace qi = boost::spirit::qi;
Rule Olarak KullanımBu sınıfı şöyle kullanırız. Üçüncü parametre olarak geçeriz.
std::string out1;
int out2;
if (qi::phrase_parse(str.begin(), str.end(), r, qi::space, out1, out2))
{
...
}
Şöyle kullanırız. Üçüncü parametre olarak geçeriz.bool result = qi::parse (str.begin(), str.end(), r);
Skipper Olarak KullanımŞöyle yaparız.
using Iterator = boost::spirit::istream_iterator;
using Skipper = qi::rule<Iterator>;
Skipper block_comment, single_line_comment, skipper;
{
using namespace qi;
single_line_comment = "//" >> *(char_ - eol) >> (eol|eoi);
block_comment = ("/*" >> *(block_comment | char_ - "*/")) > "*/";
skipper = space | single_line_comment | block_comment;
}
Iterator f(std::cin >> std::noskipws), l;
std::vector<int> data;
bool ok = phrase_parse(f, l, *qi::int_, skipper, data);
Tanımlama - iteratorŞöyle yaparız.
qi::rule<std::string::const_iterator> r = qi::no_case [
qi::lit("my_cmd1") | qi::lit("my_cmd2")
];
Tanımlama - iterator + output typeoutput type iterator gibi () karakterleri ile bitmelidir. Şöyle yaparız.
qi::rule<std::string::const_iterator, std::string()> r;
Örnek - std::mapElimizde şöyle bir kod olsun.
namespace Config {
using Key = std::string;
using Value = boost::variant<int, std::string, bool>;
using Setting = std::pair<Key, Value>;
using Settings = std::map<Key, Value>;
}
namespace Parser {
using It = std::string::const_iterator;
using namespace Config;
namespace qi = boost::spirit::qi;
using Skip = qi::blank_type;
qi::rule<It, std::string()> quoted_ = "'" >> *(
"'" >> qi::char_("'") // double ''
| '\\' >> qi::char_ // any character escaped
| ~qi::char_("'") // non-quotes
) >> "'";
qi::rule<It, Key()> key_ = +qi::char_("a-zA-Z0-9_"); // for example
qi::rule<It, Value()> value_ = qi::int_ | quoted_ | qi::bool_;
qi::rule<It, Setting(), Skip> setting_ = key_ >> '(' >> value_ >> ')';
qi::rule<It, Settings()> settings_ = qi::skip(qi::blank) [*setting_];
}
Şu tarz girdiyi parse ederiz.arg1('value1') arg2('value')
Örnek - std::stringŞöyle yaparız
qi::rule<std::string::const_iterator, std::string(size_t depth)> r;
Örnek - std::pairŞöyle yaparız. Bu rule hem attribute olarak int verir, hem de raw data'yı boost::iterator_range olarak verir.
qi::rule<
std::string::iterator,
std::pair<int, boost::iterator_range<std::string::iterator>>(
qi::rule<std::string::iterator, int(bool)>&
)
> rule2 = qi::raw[
qi::lazy(phx::bind(qi::_r1,true))[at_c<0>(qi::_val)=qi::_1]
][at_c<1>(qi::_val)=qi::_1];
Örnek - std::dequeueŞöyle yaparız.
template <typename Iterator>
struct path : qi::grammar<Iterator, std::deque<std::string>()> {
path() : path::base_type(start) {
using namespace qi;
name = +(graph - char_(".][")); // not matching spaces please
qualifiedName = name % '.';
start = skip(ascii::space) ['[' >> qualifiedName >> ']'];
BOOST_SPIRIT_DEBUG_NODES((start)(qualifiedName)(name))
}
private:
qi::rule<Iterator, std::deque<std::string>(),
qi::ascii::space_type> qualifiedName;
qi::rule<Iterator, std::string()> name;
qi::rule<Iterator, std::deque<std::string>()> start;
};
Tanımlama - iterator + output type + skipperSkipper olarak ascii::space_type veya ascii::blank_type kullanılıyor. Ancak ascii::space_type bende derleme hatası verdi. ascii::blank_type sorunsuz çalışıyor.
Şu tanımlama yanlış
qi::rule<Iterator, std::string, ascii::space_type> ident;
Doğrusu şöyleqi::rule<Iterator, std::string(), ascii::space_type> ident;
alias metoduŞöyle yaparız.
template <typename Iterator = std::string::iterator,
typename Skipper = spirit::qi::space_type>
class ParserImpl : public spirit::qi::grammar<Iterator, expr(), Skipper>
{
public:
ParserImpl() : ParserImpl::base_type(expr_)
{
using namespace boost::spirit::qi;
using namespace boost::phoenix;
expr_ = props_.alias();
props_ = (
(lit("Acc") >> "(" >> int_ >> ")")[_val = construct<Acc>(_1)
);
}
spirit::qi::rule<Iterator, expr(), Skipper> props_;
spirit::qi::rule<Iterator, expr(), Skipper> expr_;
};
operator %= metoduŞöyle yaparız
r %= qi::string("(") >> *r >> qi::string(")");
Şöyle yaparız.qi::_r1_type _depth;
r %= qi::eps(_depth < 32) >>
qi::string("(") >> *r(_depth + 1) >> qi::string(")");
Hiç yorum yok:
Yorum Gönder