Initial commit
[yaffs-website] / node_modules / node-sass / src / libsass / src / prelexer.hpp
1 #ifndef SASS_PRELEXER_H
2 #define SASS_PRELEXER_H
3
4 #include <cstring>
5 #include "lexer.hpp"
6
7 namespace Sass {
8   // using namespace Lexer;
9   namespace Prelexer {
10
11     //####################################
12     // KEYWORD "REGEX" MATCHERS
13     //####################################
14
15     // Match Sass boolean keywords.
16     const char* kwd_true(const char* src);
17     const char* kwd_false(const char* src);
18     const char* kwd_only(const char* src);
19     const char* kwd_and(const char* src);
20     const char* kwd_or(const char* src);
21     const char* kwd_not(const char* src);
22     const char* kwd_eq(const char* src);
23     const char* kwd_neq(const char* src);
24     const char* kwd_gt(const char* src);
25     const char* kwd_gte(const char* src);
26     const char* kwd_lt(const char* src);
27     const char* kwd_lte(const char* src);
28
29     // Match standard control chars
30     const char* kwd_at(const char* src);
31     const char* kwd_dot(const char* src);
32     const char* kwd_comma(const char* src);
33     const char* kwd_colon(const char* src);
34     const char* kwd_slash(const char* src);
35     const char* kwd_star(const char* src);
36     const char* kwd_plus(const char* src);
37     const char* kwd_minus(const char* src);
38
39     //####################################
40     // SPECIAL "REGEX" CONSTRUCTS
41     //####################################
42
43     // Match a sequence of characters delimited by the supplied chars.
44     template <char beg, char end, bool esc>
45     const char* delimited_by(const char* src) {
46       src = exactly<beg>(src);
47       if (!src) return 0;
48       const char* stop;
49       while (1) {
50         if (!*src) return 0;
51         stop = exactly<end>(src);
52         if (stop && (!esc || *(src - 1) != '\\')) return stop;
53         src = stop ? stop : src + 1;
54       }
55     }
56
57     // skip to delimiter (mx) inside given range
58     // this will savely skip over all quoted strings
59     // recursive skip stuff delimited by start/stop
60     // first start/opener must be consumed already!
61     template<prelexer start, prelexer stop>
62     const char* skip_over_scopes(const char* src, const char* end) {
63
64       size_t level = 0;
65       bool in_squote = false;
66       bool in_dquote = false;
67       // bool in_braces = false;
68
69       while (*src) {
70
71         // check for abort condition
72         if (end && src >= end) break;
73
74         // has escaped sequence?
75         if (*src == '\\') {
76           ++ src; // skip this (and next)
77         }
78         else if (*src == '"') {
79           in_dquote = ! in_dquote;
80         }
81         else if (*src == '\'') {
82           in_squote = ! in_squote;
83         }
84         else if (in_dquote || in_squote) {
85           // take everything literally
86         }
87
88         // find another opener inside?
89         else if (const char* pos = start(src)) {
90           ++ level; // increase counter
91           src = pos - 1; // advance position
92         }
93
94         // look for the closer (maybe final, maybe not)
95         else if (const char* final = stop(src)) {
96           // only close one level?
97           if (level > 0) -- level;
98           // return position at end of stop
99           // delimiter may be multiple chars
100           else return final;
101           // advance position
102           src = final - 1;
103         }
104
105         // next
106         ++ src;
107       }
108
109       return 0;
110     }
111
112     // skip to a skip delimited by parentheses
113     // uses smart `skip_over_scopes` internally
114     const char* parenthese_scope(const char* src);
115
116     // skip to delimiter (mx) inside given range
117     // this will savely skip over all quoted strings
118     // recursive skip stuff delimited by start/stop
119     // first start/opener must be consumed already!
120     template<prelexer start, prelexer stop>
121     const char* skip_over_scopes(const char* src) {
122       return skip_over_scopes<start, stop>(src, 0);
123     }
124
125     // Match a sequence of characters delimited by the supplied chars.
126     template <prelexer start, prelexer stop>
127     const char* recursive_scopes(const char* src) {
128       // parse opener
129       src = start(src);
130       // abort if not found
131       if (!src) return 0;
132       // parse the rest until final closer
133       return skip_over_scopes<start, stop>(src);
134     }
135
136     // Match a sequence of characters delimited by the supplied strings.
137     template <const char* beg, const char* end, bool esc>
138     const char* delimited_by(const char* src) {
139       src = exactly<beg>(src);
140       if (!src) return 0;
141       const char* stop;
142       while (1) {
143         if (!*src) return 0;
144         stop = exactly<end>(src);
145         if (stop && (!esc || *(src - 1) != '\\')) return stop;
146         src = stop ? stop : src + 1;
147       }
148     }
149
150     // Tries to match a certain number of times (between the supplied interval).
151     template<prelexer mx, size_t lo, size_t hi>
152     const char* between(const char* src) {
153       for (size_t i = 0; i < lo; ++i) {
154         src = mx(src);
155         if (!src) return 0;
156       }
157       for (size_t i = lo; i <= hi; ++i) {
158         const char* new_src = mx(src);
159         if (!new_src) return src;
160         src = new_src;
161       }
162       return src;
163     }
164
165     // equivalent of STRING_REGULAR_EXPRESSIONS
166     const char* re_string_double_open(const char* src);
167     const char* re_string_double_close(const char* src);
168     const char* re_string_single_open(const char* src);
169     const char* re_string_single_close(const char* src);
170     const char* re_string_uri_open(const char* src);
171     const char* re_string_uri_close(const char* src);
172
173     // Match a line comment.
174     const char* line_comment(const char* src);
175
176     // Match a block comment.
177     const char* block_comment(const char* src);
178     // Match either.
179     const char* comment(const char* src);
180     // Match double- and single-quoted strings.
181     const char* double_quoted_string(const char* src);
182     const char* single_quoted_string(const char* src);
183     const char* quoted_string(const char* src);
184     // Match interpolants.
185     const char* interpolant(const char* src);
186     // Match number prefix ([\+\-]+)
187     const char* number_prefix(const char* src);
188
189     // Match zero plus white-space or line_comments
190     const char* optional_css_whitespace(const char* src);
191     const char* css_whitespace(const char* src);
192     // Match optional_css_whitepace plus block_comments
193     const char* optional_css_comments(const char* src);
194     const char* css_comments(const char* src);
195
196     // Match one backslash escaped char
197     const char* escape_seq(const char* src);
198
199     // Match CSS css variables.
200     const char* custom_property_name(const char* src);
201     // Match a CSS identifier.
202     const char* identifier(const char* src);
203     const char* identifier_alpha(const char* src);
204     const char* identifier_alnum(const char* src);
205     const char* strict_identifier(const char* src);
206     const char* strict_identifier_alpha(const char* src);
207     const char* strict_identifier_alnum(const char* src);
208     // Match a CSS unit identifier.
209     const char* one_unit(const char* src);
210     const char* multiple_units(const char* src);
211     const char* unit_identifier(const char* src);
212     // const char* strict_identifier_alnums(const char* src);
213     // Match reference selector.
214     const char* re_reference_combinator(const char* src);
215     const char* static_reference_combinator(const char* src);
216     const char* schema_reference_combinator(const char* src);
217
218     // Match interpolant schemas
219     const char* identifier_schema(const char* src);
220     const char* value_schema(const char* src);
221     const char* sass_value(const char* src);
222     // const char* filename(const char* src);
223     // const char* filename_schema(const char* src);
224     // const char* url_schema(const char* src);
225     // const char* url_value(const char* src);
226     const char* vendor_prefix(const char* src);
227
228     const char* re_special_directive(const char* src);
229     const char* re_prefixed_directive(const char* src);
230     const char* re_almost_any_value_token(const char* src);
231
232     // Match CSS '@' keywords.
233     const char* at_keyword(const char* src);
234     const char* kwd_import(const char* src);
235     const char* kwd_at_root(const char* src);
236     const char* kwd_with_directive(const char* src);
237     const char* kwd_without_directive(const char* src);
238     const char* kwd_media(const char* src);
239     const char* kwd_supports_directive(const char* src);
240     // const char* keyframes(const char* src);
241     // const char* keyf(const char* src);
242     const char* kwd_mixin(const char* src);
243     const char* kwd_function(const char* src);
244     const char* kwd_return_directive(const char* src);
245     const char* kwd_include_directive(const char* src);
246     const char* kwd_content_directive(const char* src);
247     const char* kwd_charset_directive(const char* src);
248     const char* kwd_extend(const char* src);
249
250     const char* unicode_seq(const char* src);
251
252     const char* kwd_if_directive(const char* src);
253     const char* kwd_else_directive(const char* src);
254     const char* elseif_directive(const char* src);
255
256     const char* kwd_for_directive(const char* src);
257     const char* kwd_from(const char* src);
258     const char* kwd_to(const char* src);
259     const char* kwd_through(const char* src);
260
261     const char* kwd_each_directive(const char* src);
262     const char* kwd_in(const char* src);
263
264     const char* kwd_while_directive(const char* src);
265
266     const char* re_nothing(const char* src);
267     const char* re_type_selector2(const char* src);
268
269     const char* re_special_fun(const char* src);
270
271     const char* kwd_warn(const char* src);
272     const char* kwd_err(const char* src);
273     const char* kwd_dbg(const char* src);
274
275     const char* kwd_null(const char* src);
276
277     const char* re_selector_list(const char* src);
278     const char* re_type_selector(const char* src);
279     const char* re_static_expression(const char* src);
280
281     // identifier that can start with hyphens
282     const char* css_identifier(const char* src);
283     const char* css_ip_identifier(const char* src);
284
285     // Match CSS type selectors
286     const char* namespace_schema(const char* src);
287     const char* namespace_prefix(const char* src);
288     const char* type_selector(const char* src);
289     const char* hyphens_and_identifier(const char* src);
290     const char* hyphens_and_name(const char* src);
291     const char* universal(const char* src);
292     // Match CSS id names.
293     const char* id_name(const char* src);
294     // Match CSS class names.
295     const char* class_name(const char* src);
296     // Attribute name in an attribute selector
297     const char* attribute_name(const char* src);
298     // Match placeholder selectors.
299     const char* placeholder(const char* src);
300     // Match CSS numeric constants.
301     const char* op(const char* src);
302     const char* sign(const char* src);
303     const char* unsigned_number(const char* src);
304     const char* number(const char* src);
305     const char* coefficient(const char* src);
306     const char* binomial(const char* src);
307     const char* percentage(const char* src);
308     const char* ampersand(const char* src);
309     const char* dimension(const char* src);
310     const char* hex(const char* src);
311     const char* hexa(const char* src);
312     const char* hex0(const char* src);
313     // const char* rgb_prefix(const char* src);
314     // Match CSS uri specifiers.
315     const char* uri_prefix(const char* src);
316     // Match CSS "!important" keyword.
317     const char* kwd_important(const char* src);
318     // Match CSS "!optional" keyword.
319     const char* kwd_optional(const char* src);
320     // Match Sass "!default" keyword.
321     const char* default_flag(const char* src);
322     const char* global_flag(const char* src);
323     // Match CSS pseudo-class/element prefixes
324     const char* pseudo_prefix(const char* src);
325     // Match CSS function call openers.
326     const char* re_functional(const char* src);
327     const char* re_pseudo_selector(const char* src);
328     const char* functional_schema(const char* src);
329     const char* pseudo_not(const char* src);
330     // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
331     const char* even(const char* src);
332     const char* odd(const char* src);
333     // Match CSS attribute-matching operators.
334     const char* exact_match(const char* src);
335     const char* class_match(const char* src);
336     const char* dash_match(const char* src);
337     const char* prefix_match(const char* src);
338     const char* suffix_match(const char* src);
339     const char* substring_match(const char* src);
340     // Match CSS combinators.
341     // const char* adjacent_to(const char* src);
342     // const char* precedes(const char* src);
343     // const char* parent_of(const char* src);
344     // const char* ancestor_of(const char* src);
345
346     // Match SCSS variable names.
347     const char* variable(const char* src);
348     const char* calc_fn_call(const char* src);
349
350     // IE stuff
351     const char* ie_progid(const char* src);
352     const char* ie_expression(const char* src);
353     const char* ie_property(const char* src);
354     const char* ie_keyword_arg(const char* src);
355     const char* ie_keyword_arg_value(const char* src);
356     const char* ie_keyword_arg_property(const char* src);
357
358     // characters that terminate parsing of a list
359     const char* list_terminator(const char* src);
360     const char* space_list_terminator(const char* src);
361
362     // match url()
363     const char* H(const char* src);
364     const char* W(const char* src);
365     // `UNICODE` makes VS sad
366     const char* UUNICODE(const char* src);
367     const char* NONASCII(const char* src);
368     const char* ESCAPE(const char* src);
369     const char* real_uri_suffix(const char* src);
370     // const char* real_uri_prefix(const char* src);
371     const char* real_uri_value(const char* src);
372
373     // Path matching functions.
374     // const char* folder(const char* src);
375     // const char* folders(const char* src);
376
377
378     const char* static_string(const char* src);
379     const char* static_component(const char* src);
380     const char* static_property(const char* src);
381     const char* static_value(const char* src);
382
383     // Utility functions for finding and counting characters in a string.
384     template<char c>
385     const char* find_first(const char* src) {
386       while (*src && *src != c) ++src;
387       return *src ? src : 0;
388     }
389     template<prelexer mx>
390     const char* find_first(const char* src) {
391       while (*src && !mx(src)) ++src;
392       return *src ? src : 0;
393     }
394     template<prelexer mx>
395     const char* find_first_in_interval(const char* beg, const char* end) {
396       bool esc = false;
397       while ((beg < end) && *beg) {
398         if (esc) esc = false;
399         else if (*beg == '\\') esc = true;
400         else if (mx(beg)) return beg;
401         ++beg;
402       }
403       return 0;
404     }
405     template<prelexer mx, prelexer skip>
406     const char* find_first_in_interval(const char* beg, const char* end) {
407       bool esc = false;
408       while ((beg < end) && *beg) {
409         if (esc) esc = false;
410         else if (*beg == '\\') esc = true;
411         else if (const char* pos = skip(beg)) beg = pos;
412         else if (mx(beg)) return beg;
413         ++beg;
414       }
415       return 0;
416     }
417     template <prelexer mx>
418     unsigned int count_interval(const char* beg, const char* end) {
419       unsigned int counter = 0;
420       bool esc = false;
421       while (beg < end && *beg) {
422         const char* p;
423         if (esc) {
424           esc = false;
425           ++beg;
426         } else if (*beg == '\\') {
427           esc = true;
428           ++beg;
429         } else if ((p = mx(beg))) {
430           ++counter;
431           beg = p;
432         }
433         else {
434           ++beg;
435         }
436       }
437       return counter;
438     }
439
440     template <size_t size, prelexer mx, prelexer pad>
441     const char* padded_token(const char* src)
442     {
443       size_t got = 0;
444       const char* pos = src;
445       while (got < size) {
446         if (!mx(pos)) break;
447         ++ pos; ++ got;
448       }
449       while (got < size) {
450         if (!pad(pos)) break;
451         ++ pos; ++ got;
452       }
453       return got ? pos : 0;
454     }
455
456     template <size_t min, size_t max, prelexer mx>
457     const char* minmax_range(const char* src)
458     {
459       size_t got = 0;
460       const char* pos = src;
461       while (got < max) {
462         if (!mx(pos)) break;
463         ++ pos; ++ got;
464       }
465       if (got < min) return 0;
466       if (got > max) return 0;
467       return pos;
468     }
469
470     template <char min, char max>
471     const char* char_range(const char* src)
472     {
473       if (*src < min) return 0;
474       if (*src > max) return 0;
475       return src + 1;
476     }
477
478   }
479 }
480
481 #endif