Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <boost/config/warning_disable.hpp>
- #include <boost/spirit/include/qi.hpp>
- #include <boost/spirit/include/phoenix.hpp>
- #include "url_parser.hpp"
- namespace qi = boost::spirit::qi;
- BOOST_FUSION_ADAPT_STRUCT(
- KV,
- (std::string, k)
- (std::string, v)
- )
- BOOST_FUSION_ADAPT_STRUCT(
- URL,
- (std::string, schema)
- (std::string, host)
- (std::string, username)
- (std::string, password)
- (std::optional<int>, port)
- (std::string, path)
- (std::vector<KV>, query)
- (std::string, fragment)
- )
- template <typename Iterator>
- struct uri_grammer : qi::grammar<Iterator, URL()>
- {
- typedef unsigned long ulong;
- uri_grammer() : uri_grammer::base_type(url)
- {
- using namespace boost::phoenix;
- url = schema [ at_c<0>(qi::_val) = qi::_1 ]
- >> "://" -( username [ at_c<2>(qi::_val) = qi::_1 ] >> -( ':' >> password [ at_c<3>(qi::_val) = qi::_1 ] ) >> '@' )
- >> (
- ( qi::lit('[') >> ipv6host [ at_c<1>(qi::_val) = qi::_1 ] >> qi::lit(']') )
- |
- host [ at_c<1>(qi::_val) = qi::_1 ]
- )
- >> -(qi::lit(':') >> qi::int_ [ at_c<4>(qi::_val) = qi::_1 ] )
- >> -(path [ at_c<5>(qi::_val) = qi::_1 ] >> -('?' >> query[ at_c<6>(qi::_val) = qi::_1 ]))
- >> -('#' >> fragment [ at_c<7>(qi::_val) = qi::_1 ]);
- host = qi::lexeme[ +(qi::char_ - '/' - ':') ] ;
- ipv6host = qi::lexeme[ +(qi::char_("0123456789abcdefABCDEF:")) ];
- username = qi::lexeme[ +(qi::char_ - ':' - '@') ];
- password = qi::lexeme[ +(qi::char_ - '@') ];
- schema = qi::lexeme[ +(qi::char_ - ':' - '/') ];
- path = qi::lexeme[ +(qi::char_ - '?' - '#') ];
- query = pair >> *((qi::lit(';') | '&') >> pair);
- pair = key >> -('=' >> value);
- key = qi::lexeme[ +(qi::char_ - '=' - '#') ];
- value = qi::lexeme[ *(qi::char_ - '&' - '#') ];
- fragment = qi::lexeme[ +(qi::char_) ];
- };
- qi::rule<Iterator, URL()> url;
- qi::rule<Iterator, std::string()> schema, host, ipv6host, path;
- qi::rule<Iterator, std::string()> username, password;
- qi::rule<Iterator, std::vector<KV>()> query;
- qi::rule<Iterator, KV()> pair;
- qi::rule<Iterator, std::string()> key, value;
- qi::rule<Iterator, std::string()> fragment;
- };
- URL parse_url(const std::string_view& url)
- {
- URL ast;
- uri_grammer<std::string_view::const_iterator> gramer;
- auto first = url.begin();
- bool r = boost::spirit::qi::parse(first, url.end(), gramer, ast);
- return ast;
- }
Add Comment
Please, Sign In to add comment