1 #ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) ||                                            \
5     (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6      (__GNUC__ >= 4))  // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include <ios>
11 #include <string>
12 
13 #include "regex_yaml.h"
14 #include "stream.h"
15 
16 namespace YAML {
17 ////////////////////////////////////////////////////////////////////////////////
18 // Here we store a bunch of expressions for matching different parts of the
19 // file.
20 
21 namespace Exp {
22 // misc
Empty()23 inline const RegEx& Empty() {
24   static const RegEx e;
25   return e;
26 }
Space()27 inline const RegEx& Space() {
28   static const RegEx e = RegEx(' ');
29   return e;
30 }
Tab()31 inline const RegEx& Tab() {
32   static const RegEx e = RegEx('\t');
33   return e;
34 }
Blank()35 inline const RegEx& Blank() {
36   static const RegEx e = Space() | Tab();
37   return e;
38 }
Break()39 inline const RegEx& Break() {
40   static const RegEx e = RegEx('\n') | RegEx("\r\n");
41   return e;
42 }
BlankOrBreak()43 inline const RegEx& BlankOrBreak() {
44   static const RegEx e = Blank() | Break();
45   return e;
46 }
Digit()47 inline const RegEx& Digit() {
48   static const RegEx e = RegEx('0', '9');
49   return e;
50 }
Alpha()51 inline const RegEx& Alpha() {
52   static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z');
53   return e;
54 }
AlphaNumeric()55 inline const RegEx& AlphaNumeric() {
56   static const RegEx e = Alpha() | Digit();
57   return e;
58 }
Word()59 inline const RegEx& Word() {
60   static const RegEx e = AlphaNumeric() | RegEx('-');
61   return e;
62 }
Hex()63 inline const RegEx& Hex() {
64   static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f');
65   return e;
66 }
67 // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
68 // 5.1)
NotPrintable()69 inline const RegEx& NotPrintable() {
70   static const RegEx e =
71       RegEx(0) |
72       RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) |
73       RegEx(0x0E, 0x1F) |
74       (RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F')));
75   return e;
76 }
Utf8_ByteOrderMark()77 inline const RegEx& Utf8_ByteOrderMark() {
78   static const RegEx e = RegEx("\xEF\xBB\xBF");
79   return e;
80 }
81 
82 // actual tags
83 
DocStart()84 inline const RegEx& DocStart() {
85   static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
86   return e;
87 }
DocEnd()88 inline const RegEx& DocEnd() {
89   static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
90   return e;
91 }
DocIndicator()92 inline const RegEx& DocIndicator() {
93   static const RegEx e = DocStart() | DocEnd();
94   return e;
95 }
BlockEntry()96 inline const RegEx& BlockEntry() {
97   static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
98   return e;
99 }
Key()100 inline const RegEx& Key() {
101   static const RegEx e = RegEx('?') + BlankOrBreak();
102   return e;
103 }
KeyInFlow()104 inline const RegEx& KeyInFlow() {
105   static const RegEx e = RegEx('?') + BlankOrBreak();
106   return e;
107 }
Value()108 inline const RegEx& Value() {
109   static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
110   return e;
111 }
ValueInFlow()112 inline const RegEx& ValueInFlow() {
113   static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",}", REGEX_OR));
114   return e;
115 }
ValueInJSONFlow()116 inline const RegEx& ValueInJSONFlow() {
117   static const RegEx e = RegEx(':');
118   return e;
119 }
Comment()120 inline const RegEx Comment() {
121   static const RegEx e = RegEx('#');
122   return e;
123 }
Anchor()124 inline const RegEx& Anchor() {
125   static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
126   return e;
127 }
AnchorEnd()128 inline const RegEx& AnchorEnd() {
129   static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
130   return e;
131 }
URI()132 inline const RegEx& URI() {
133   static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
134                          (RegEx('%') + Hex() + Hex());
135   return e;
136 }
Tag()137 inline const RegEx& Tag() {
138   static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
139                          (RegEx('%') + Hex() + Hex());
140   return e;
141 }
142 
143 // Plain scalar rules:
144 // . Cannot start with a blank.
145 // . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
146 // . In the block context - ? : must be not be followed with a space.
147 // . In the flow context ? is illegal and : and - must not be followed with a
148 // space.
PlainScalar()149 inline const RegEx& PlainScalar() {
150   static const RegEx e =
151       !(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
152         (RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
153   return e;
154 }
PlainScalarInFlow()155 inline const RegEx& PlainScalarInFlow() {
156   static const RegEx e =
157       !(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
158         (RegEx("-:", REGEX_OR) + Blank()));
159   return e;
160 }
EndScalar()161 inline const RegEx& EndScalar() {
162   static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
163   return e;
164 }
EndScalarInFlow()165 inline const RegEx& EndScalarInFlow() {
166   static const RegEx e =
167       (RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
168       RegEx(",?[]{}", REGEX_OR);
169   return e;
170 }
171 
ScanScalarEndInFlow()172 inline const RegEx& ScanScalarEndInFlow() {
173   static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
174   return e;
175 }
176 
ScanScalarEnd()177 inline const RegEx& ScanScalarEnd() {
178   static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
179   return e;
180 }
EscSingleQuote()181 inline const RegEx& EscSingleQuote() {
182   static const RegEx e = RegEx("\'\'");
183   return e;
184 }
EscBreak()185 inline const RegEx& EscBreak() {
186   static const RegEx e = RegEx('\\') + Break();
187   return e;
188 }
189 
ChompIndicator()190 inline const RegEx& ChompIndicator() {
191   static const RegEx e = RegEx("+-", REGEX_OR);
192   return e;
193 }
Chomp()194 inline const RegEx& Chomp() {
195   static const RegEx e = (ChompIndicator() + Digit()) |
196                          (Digit() + ChompIndicator()) | ChompIndicator() |
197                          Digit();
198   return e;
199 }
200 
201 // and some functions
202 std::string Escape(Stream& in);
203 }  // namespace Exp
204 
205 namespace Keys {
206 const char Directive = '%';
207 const char FlowSeqStart = '[';
208 const char FlowSeqEnd = ']';
209 const char FlowMapStart = '{';
210 const char FlowMapEnd = '}';
211 const char FlowEntry = ',';
212 const char Alias = '*';
213 const char Anchor = '&';
214 const char Tag = '!';
215 const char LiteralScalar = '|';
216 const char FoldedScalar = '>';
217 const char VerbatimTagStart = '<';
218 const char VerbatimTagEnd = '>';
219 }  // namespace Keys
220 }  // namespace YAML
221 
222 #endif  // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
223