File: uri.hpp

package info (click to toggle)
tao-json 0.0%2Bgit20200604.f357d72-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 8,900 kB
  • sloc: cpp: 48,129; makefile: 55
file content (106 lines) | stat: -rw-r--r-- 5,042 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright (c) 2014-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_JSON_PEGTL_CONTRIB_URI_HPP
#define TAO_JSON_PEGTL_CONTRIB_URI_HPP

#include <cstdint>

#include "../ascii.hpp"
#include "../config.hpp"
#include "../rules.hpp"
#include "../utf8.hpp"

#include "abnf.hpp"
#include "integer.hpp"

namespace TAO_JSON_PEGTL_NAMESPACE::uri
{
   // URI grammar according to RFC 3986.

   // This grammar is a direct PEG translation of the original URI grammar.
   // It should be considered experimental -- in case of any issues, in particular
   // missing rules for attached actions, please contact the developers.

   // Note that this grammar has multiple top-level rules.

   using dot = one< '.' >;
   using colon = one< ':' >;

   // clang-format off
   struct dec_octet : maximum_rule< std::uint8_t > {};

   struct IPv4address : seq< dec_octet, dot, dec_octet, dot, dec_octet, dot, dec_octet > {};

   struct h16 : rep_min_max< 1, 4, abnf::HEXDIG > {};
   struct ls32 : sor< seq< h16, colon, h16 >, IPv4address > {};

   struct dcolon : two< ':' > {};

   struct IPv6address : sor< seq<                                               rep< 6, h16, colon >, ls32 >,
                             seq<                                       dcolon, rep< 5, h16, colon >, ls32 >,
                             seq< opt< h16                           >, dcolon, rep< 4, h16, colon >, ls32 >,
                             seq< opt< h16,     opt<    colon, h16 > >, dcolon, rep< 3, h16, colon >, ls32 >,
                             seq< opt< h16, rep_opt< 2, colon, h16 > >, dcolon, rep< 2, h16, colon >, ls32 >,
                             seq< opt< h16, rep_opt< 3, colon, h16 > >, dcolon,         h16, colon,   ls32 >,
                             seq< opt< h16, rep_opt< 4, colon, h16 > >, dcolon,                       ls32 >,
                             seq< opt< h16, rep_opt< 5, colon, h16 > >, dcolon,                       h16  >,
                             seq< opt< h16, rep_opt< 6, colon, h16 > >, dcolon                             > > {};

   struct gen_delims : one< ':', '/', '?', '#', '[', ']', '@' > {};
   struct sub_delims : one< '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' > {};

   struct unreserved : sor< abnf::ALPHA, abnf::DIGIT, one< '-', '.', '_', '~' > > {};
   struct reserved : sor< gen_delims, sub_delims > {};

   struct IPvFuture : if_must< one< 'v', 'V' >, plus< abnf::HEXDIG >, dot, plus< sor< unreserved, sub_delims, colon > > > {};

   struct IP_literal : if_must< one< '[' >, sor< IPvFuture, IPv6address >, one< ']' > > {};

   struct pct_encoded : if_must< one< '%' >, abnf::HEXDIG, abnf::HEXDIG > {};
   struct pchar : sor< unreserved, pct_encoded, sub_delims, one< ':', '@' > > {};

   struct query : star< sor< pchar, one< '/', '?' > > > {};
   struct fragment : star< sor< pchar, one< '/', '?' > > > {};

   struct segment : star< pchar > {};
   struct segment_nz : plus< pchar > {};
   struct segment_nz_nc : plus< sor< unreserved, pct_encoded, sub_delims, one< '@' > > > {}; // non-zero-length segment without any colon ":"

   struct path_abempty : star< one< '/' >, segment > {};
   struct path_absolute : seq< one< '/' >, opt< segment_nz, star< one< '/' >, segment > > > {};
   struct path_noscheme : seq< segment_nz_nc, star< one< '/' >, segment > > {};
   struct path_rootless : seq< segment_nz, star< one< '/' >, segment > > {};
   struct path_empty : success {};

   struct path : sor< path_noscheme,     // begins with a non-colon segment
                      path_rootless,     // begins with a segment
                      path_absolute,     // begins with "/" but not "//"
                      path_abempty > {}; // begins with "/" or is empty

   struct reg_name : star< sor< unreserved, pct_encoded, sub_delims > > {};

   struct port : star< abnf::DIGIT > {};
   struct host : sor< IP_literal, IPv4address, reg_name > {};
   struct userinfo : star< sor< unreserved, pct_encoded, sub_delims, colon > > {};
   struct opt_userinfo : opt< userinfo, one< '@' > > {};
   struct authority : seq< opt_userinfo, host, opt< colon, port > > {};

   struct scheme : seq< abnf::ALPHA, star< sor< abnf::ALPHA, abnf::DIGIT, one< '+', '-', '.' > > > > {};

   using dslash = two< '/' >;
   using opt_query = opt_must< one< '?' >, query >;
   using opt_fragment = opt_must< one< '#' >, fragment >;

   struct hier_part : sor< if_must< dslash, authority, path_abempty >, path_rootless, path_absolute, path_empty > {};
   struct relative_part : sor< if_must< dslash, authority, path_abempty >, path_noscheme, path_absolute, path_empty > {};
   struct relative_ref : seq< relative_part, opt_query, opt_fragment > {};

   struct URI : seq< scheme, one< ':' >, hier_part, opt_query, opt_fragment > {};
   struct URI_reference : sor< URI, relative_ref > {};
   struct absolute_URI : seq< scheme, one< ':' >, hier_part, opt_query > {};
   // clang-format on

}  // namespace TAO_JSON_PEGTL_NAMESPACE::uri

#endif