Giriş
Şu satırı dahil ederiz.
Metodun imzası şöyle
begin ve end iteratorlerinin backtracking yüzünden ForwardIterator olması gerekir.
Return Type
bool döner. Iterator'leri alırız.
Bu parametre olarak genelde ascii::space yani qi::space kullanılır. Açıklaması şöyle
Birinci parametre iterator, ikinci parametre iterator, üçüncü parametre grammar, dördüncü parametre skipper, diğer parametreler sonuçlardır.
Örnek
Şöyle yaparız.
Eliimizde şu generic kod olsun. Bu kod kaç tane out parametresi verilirse verilsin çalışır.
Elimizde 3 değişken olsun
Şu satırı dahil ederiz.
#include <boost/spirit/include/qi.hpp>
Kolay kullanım için şu satırları dahil ederiz.namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
İmzasıMetodun imzası şöyle
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip);
Şöyle yaparızboost::spirit::phrase_parse(begin, end, grammar, space, obj)Iterator Parametresi
begin ve end iteratorlerinin backtracking yüzünden ForwardIterator olması gerekir.
Return Type
bool döner. Iterator'leri alırız.
iterator_type iter = input.begin();
iterator_type end = input.end();
Şöyle yaparız.std::string input;
if (phrase_parse(iter, end, ...)) {
...
}
Aynı zamanda iteratorler de değişir. Açıklaması şöyleThe first iterator is passed by reference. On a successful parse, the iterator is repositioned to the rightmost position consumed by the parser. If this becomes equal to last, the we have a full match, if not then we have a partial match. A partial match happens when the parser is only able to parse a portion of the input.Şöyle yaparız.
std::cout << "Bytes left = " << std::distance(iter, end);
std::cout << (iter == end) ? "SUCCEEDED" : "FAILED";
skip parser parametresi Bu parametre olarak genelde ascii::space yani qi::space kullanılır. Açıklaması şöyle
It is a very simple parser that simply recognizes whitespace. The skip parser is the one responsible for skipping characters in between parser elements such as double_ and char_phrase_parse - out Struct
Birinci parametre iterator, ikinci parametre iterator, üçüncü parametre grammar, dördüncü parametre skipper, diğer parametreler sonuçlardır.
Örnek
Şöyle yaparız.
typedef std::string::const_iterator iterator_type;
MyParser myParser;
MyStruct myStruct;
std::string str = ...;
std::string::const_iterator begin_iter = storedString.begin();
std::string::const_iterator end_iter = storedString.end();
//Invoke the parser
bool r = phrase_parse(begin_iter, end_iter, myParser, ascii::space, myStruct);
if (r && begin_iter == end_iter)
{
std::cout << "Parsing succeeded\n";
} else {
std::cout << "Parsing failed\n";
}
phrase_parse - out param1 + out param2
Örnek
Elimizde şu girdiler olsun
Elimizde şu girdiler olsun
nam12 = 34.24
nam56 = 43.65
Şöyle yaparız.
std::string input = ...;
std::string name;
double value;
using namespace boost::spirit::qi;
if (phrase_parse(input.begin(), input.end(),
lexeme[+alnum] >> '=' >> double_, space, name, value))
std::cout << "Parsed: name = '" << name << "' and value = " << value << "\n";
}
Çıktı olarak şunu alırız.Parsed: name = 'nam12' and value = 34.24
Parsed: name = 'nam56' and value = 43.65
ÖrnekEliimizde şu generic kod olsun. Bu kod kaç tane out parametresi verilirse verilsin çalışır.
template <typename Parser,typename... Attrs>
void parse(const std::string& str, const Parser& parser, Attrs&... attrs)
{
std::string::const_iterator iter=std::begin(str), end=std::end(str);
bool result = qi::phrase_parse(iter,end,parser,qi::space,attrs...);
if(result && iter==end) {
std::cout << "Success.";
int ignore[] = {(print(attrs),0)...};
std::cout << "\n";
} else {
std::cout << "Something failed. Unparsed: \"" << std::string(iter,end) << "\"\n";
}
}
Bu generic kodu sarmalayarak çağıran kodlar olsuntemplate <typename Parser>
void parse_with_nodes(const std::string& str, const Parser& parser)
{
std::vector<std::string> nodes;
parse(str,parser,nodes);
}
template <typename Parser>
void parse_with_nodes_and_attr(const std::string& str, const Parser& parser)
{
std::vector<std::string> nodes;
std::pair<std::string,double> attr_pair;
parse(str,parser,nodes,attr_pair);
}
Elimizde şu iki gramer olsun.
qi::rule<std::string::const_iterator,std::string()> node=+qi::alnum;
qi::rule<std::string::const_iterator,std::pair<std::string,double>(),qi::space_type> attr=
+qi::alpha >> '=' >> qi::double_;
Bu gramerleri karıştırarak kullanabiliriz. Şöyle yaparız.parse_with_nodes("node1->node2", node % "->");
parse_with_nodes_and_attr("node1->node2 arrowsize=1.0", node % "->" >> attr);
parse_with_nodes("node1->node2", node >> +("->" >> node));
qi::rule<std::string::const_iterator,std::vector<std::string>(),qi::space_type>
at_least_two_nodes = node >> +("->" >> node);
parse_with_nodes_and_attr("node1->node2 arrowsize=1.0", at_least_two_nodes >> attr);
phrase_parse - out param1 + out param2 + out param3Elimizde 3 değişken olsun
int a, b;
boost::optional<int> c;
Şöyle yaparız.if (!qi::phrase_parse(s.begin(), s.end(),
qi::lit("A:") >> qi::int_ >> "B:" >> qi::int_ >> -("C:" >> qi::int_), qi::space,
a, b, c)) {...}
Hiç yorum yok:
Yorum Gönder