Guest User

Untitled

a guest
Dec 16th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.27 KB | None | 0 0
  1. #include <boost/config/warning_disable.hpp>
  2. #include <boost/spirit/include/qi.hpp>
  3. #include <boost/spirit/include/phoenix.hpp>
  4.  
  5. #include "url_parser.hpp"
  6.  
  7. namespace qi = boost::spirit::qi;
  8.  
  9. BOOST_FUSION_ADAPT_STRUCT(
  10. KV,
  11. (std::string, k)
  12. (std::string, v)
  13. )
  14.  
  15. BOOST_FUSION_ADAPT_STRUCT(
  16. URL,
  17. (std::string, schema)
  18. (std::string, host)
  19. (std::string, username)
  20. (std::string, password)
  21. (std::optional<int>, port)
  22. (std::string, path)
  23. (std::vector<KV>, query)
  24. (std::string, fragment)
  25. )
  26.  
  27. template <typename Iterator>
  28. struct uri_grammer : qi::grammar<Iterator, URL()>
  29. {
  30. typedef unsigned long ulong;
  31. uri_grammer() : uri_grammer::base_type(url)
  32. {
  33. using namespace boost::phoenix;
  34.  
  35. url = schema [ at_c<0>(qi::_val) = qi::_1 ]
  36. >> "://" -( username [ at_c<2>(qi::_val) = qi::_1 ] >> -( ':' >> password [ at_c<3>(qi::_val) = qi::_1 ] ) >> '@' )
  37. >> (
  38. ( qi::lit('[') >> ipv6host [ at_c<1>(qi::_val) = qi::_1 ] >> qi::lit(']') )
  39. |
  40. host [ at_c<1>(qi::_val) = qi::_1 ]
  41. )
  42. >> -(qi::lit(':') >> qi::int_ [ at_c<4>(qi::_val) = qi::_1 ] )
  43. >> -(path [ at_c<5>(qi::_val) = qi::_1 ] >> -('?' >> query[ at_c<6>(qi::_val) = qi::_1 ]))
  44. >> -('#' >> fragment [ at_c<7>(qi::_val) = qi::_1 ]);
  45.  
  46. host = qi::lexeme[ +(qi::char_ - '/' - ':') ] ;
  47.  
  48. ipv6host = qi::lexeme[ +(qi::char_("0123456789abcdefABCDEF:")) ];
  49.  
  50. username = qi::lexeme[ +(qi::char_ - ':' - '@') ];
  51. password = qi::lexeme[ +(qi::char_ - '@') ];
  52.  
  53. schema = qi::lexeme[ +(qi::char_ - ':' - '/') ];
  54.  
  55. path = qi::lexeme[ +(qi::char_ - '?' - '#') ];
  56.  
  57. query = pair >> *((qi::lit(';') | '&') >> pair);
  58. pair = key >> -('=' >> value);
  59. key = qi::lexeme[ +(qi::char_ - '=' - '#') ];
  60. value = qi::lexeme[ *(qi::char_ - '&' - '#') ];
  61.  
  62. fragment = qi::lexeme[ +(qi::char_) ];
  63.  
  64. };
  65.  
  66. qi::rule<Iterator, URL()> url;
  67. qi::rule<Iterator, std::string()> schema, host, ipv6host, path;
  68.  
  69. qi::rule<Iterator, std::string()> username, password;
  70.  
  71. qi::rule<Iterator, std::vector<KV>()> query;
  72. qi::rule<Iterator, KV()> pair;
  73. qi::rule<Iterator, std::string()> key, value;
  74.  
  75. qi::rule<Iterator, std::string()> fragment;
  76. };
  77.  
  78. URL parse_url(const std::string_view& url)
  79. {
  80. URL ast;
  81.  
  82. uri_grammer<std::string_view::const_iterator> gramer;
  83.  
  84. auto first = url.begin();
  85.  
  86. bool r = boost::spirit::qi::parse(first, url.end(), gramer, ast);
  87.  
  88. return ast;
  89. }
Add Comment
Please, Sign In to add comment