Blame src/prelexer.cpp

Packit bfcc33
#include "sass.hpp"
Packit bfcc33
#include <cctype>
Packit bfcc33
#include <iostream>
Packit bfcc33
#include <iomanip>
Packit bfcc33
#include "util.hpp"
Packit bfcc33
#include "position.hpp"
Packit bfcc33
#include "prelexer.hpp"
Packit bfcc33
#include "constants.hpp"
Packit bfcc33
Packit bfcc33
Packit bfcc33
namespace Sass {
Packit bfcc33
  // using namespace Lexer;
Packit bfcc33
  using namespace Constants;
Packit bfcc33
Packit bfcc33
  namespace Prelexer {
Packit bfcc33
Packit bfcc33
Packit bfcc33
    /*
Packit bfcc33
Packit bfcc33
        def string_re(open, close)
Packit bfcc33
          /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
Packit bfcc33
        end
Packit bfcc33
      end
Packit bfcc33
Packit bfcc33
      # A hash of regular expressions that are used for tokenizing strings.
Packit bfcc33
      #
Packit bfcc33
      # The key is a `[Symbol, Boolean]` pair.
Packit bfcc33
      # The symbol represents which style of quotation to use,
Packit bfcc33
      # while the boolean represents whether or not the string
Packit bfcc33
      # is following an interpolated segment.
Packit bfcc33
      STRING_REGULAR_EXPRESSIONS = {
Packit bfcc33
        :double => {
Packit bfcc33
          /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
Packit bfcc33
          false => string_re('"', '"'),
Packit bfcc33
          true => string_re('', '"')
Packit bfcc33
        },
Packit bfcc33
        :single => {
Packit bfcc33
          false => string_re("'", "'"),
Packit bfcc33
          true => string_re('', "'")
Packit bfcc33
        },
Packit bfcc33
        :uri => {
Packit bfcc33
          false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
Packit bfcc33
          true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
Packit bfcc33
        },
Packit bfcc33
        # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
Packit bfcc33
        # non-standard version of http://www.w3.org/TR/css3-conditional/
Packit bfcc33
        :url_prefix => {
Packit bfcc33
          false => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
Packit bfcc33
          true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
Packit bfcc33
        },
Packit bfcc33
        :domain => {
Packit bfcc33
          false => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
Packit bfcc33
          true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
Packit bfcc33
        }
Packit bfcc33
      }
Packit bfcc33
    */
Packit bfcc33
Packit bfcc33
    /*
Packit bfcc33
      /#{open}
Packit bfcc33
        (
Packit bfcc33
          \\.
Packit bfcc33
          |
Packit bfcc33
          \# (?!\{)
Packit bfcc33
          |
Packit bfcc33
          [^#{close}\\#]
Packit bfcc33
        )*
Packit bfcc33
        (#{close}|#\{)
Packit bfcc33
      /m
Packit bfcc33
      false => string_re('"', '"'),
Packit bfcc33
      true => string_re('', '"')
Packit bfcc33
    */
Packit bfcc33
    extern const char string_double_negates[] = "\"\\#";
Packit bfcc33
    const char* re_string_double_close(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        // valid chars
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // escaped char
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              any_char
Packit bfcc33
            >,
Packit bfcc33
            // non interpolate hash
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'#'>,
Packit bfcc33
              negate <
Packit bfcc33
                exactly <'{'>
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            // other valid chars
Packit bfcc33
            neg_class_char <
Packit bfcc33
              string_double_negates
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        // quoted string closer
Packit bfcc33
        // or interpolate opening
Packit bfcc33
        alternatives <
Packit bfcc33
          exactly <'"'>,
Packit bfcc33
          lookahead < exactly< hash_lbrace > >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_string_double_open(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        // quoted string opener
Packit bfcc33
        exactly <'"'>,
Packit bfcc33
        // valid chars
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // escaped char
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              any_char
Packit bfcc33
            >,
Packit bfcc33
            // non interpolate hash
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'#'>,
Packit bfcc33
              negate <
Packit bfcc33
                exactly <'{'>
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            // other valid chars
Packit bfcc33
            neg_class_char <
Packit bfcc33
              string_double_negates
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        // quoted string closer
Packit bfcc33
        // or interpolate opening
Packit bfcc33
        alternatives <
Packit bfcc33
          exactly <'"'>,
Packit bfcc33
          lookahead < exactly< hash_lbrace > >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    extern const char string_single_negates[] = "'\\#";
Packit bfcc33
    const char* re_string_single_close(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        // valid chars
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // escaped char
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              any_char
Packit bfcc33
            >,
Packit bfcc33
            // non interpolate hash
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'#'>,
Packit bfcc33
              negate <
Packit bfcc33
                exactly <'{'>
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            // other valid chars
Packit bfcc33
            neg_class_char <
Packit bfcc33
              string_single_negates
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        // quoted string closer
Packit bfcc33
        // or interpolate opening
Packit bfcc33
        alternatives <
Packit bfcc33
          exactly <'\''>,
Packit bfcc33
          lookahead < exactly< hash_lbrace > >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_string_single_open(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        // quoted string opener
Packit bfcc33
        exactly <'\''>,
Packit bfcc33
        // valid chars
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // escaped char
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              any_char
Packit bfcc33
            >,
Packit bfcc33
            // non interpolate hash
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'#'>,
Packit bfcc33
              negate <
Packit bfcc33
                exactly <'{'>
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            // other valid chars
Packit bfcc33
            neg_class_char <
Packit bfcc33
              string_single_negates
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        // quoted string closer
Packit bfcc33
        // or interpolate opening
Packit bfcc33
        alternatives <
Packit bfcc33
          exactly <'\''>,
Packit bfcc33
          lookahead < exactly< hash_lbrace > >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /*
Packit bfcc33
      :uri => {
Packit bfcc33
        false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
Packit bfcc33
        true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
Packit bfcc33
      },
Packit bfcc33
    */
Packit bfcc33
    const char* re_string_uri_close(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        non_greedy<
Packit bfcc33
          alternatives<
Packit bfcc33
            class_char< real_uri_chars >,
Packit bfcc33
            uri_character,
Packit bfcc33
            NONASCII,
Packit bfcc33
            ESCAPE
Packit bfcc33
          >,
Packit bfcc33
          alternatives<
Packit bfcc33
            sequence < optional < W >, exactly <')'> >,
Packit bfcc33
            lookahead < exactly< hash_lbrace > >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        optional <
Packit bfcc33
          sequence < optional < W >, exactly <')'> >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_string_uri_open(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <'u'>,
Packit bfcc33
        exactly <'r'>,
Packit bfcc33
        exactly <'l'>,
Packit bfcc33
        exactly <'('>,
Packit bfcc33
        W,
Packit bfcc33
        alternatives<
Packit bfcc33
          quoted_string,
Packit bfcc33
          non_greedy<
Packit bfcc33
            alternatives<
Packit bfcc33
              class_char< real_uri_chars >,
Packit bfcc33
              uri_character,
Packit bfcc33
              NONASCII,
Packit bfcc33
              ESCAPE
Packit bfcc33
            >,
Packit bfcc33
            alternatives<
Packit bfcc33
              sequence < W, exactly <')'> >,
Packit bfcc33
              exactly< hash_lbrace >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match a line comment (/.*?(?=\n|\r\n?|\Z)/.
Packit bfcc33
    const char* line_comment(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence<
Packit bfcc33
               exactly <
Packit bfcc33
                 slash_slash
Packit bfcc33
               >,
Packit bfcc33
               non_greedy<
Packit bfcc33
                 any_char,
Packit bfcc33
                 end_of_line
Packit bfcc33
               >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match a block comment.
Packit bfcc33
    const char* block_comment(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence<
Packit bfcc33
               delimited_by<
Packit bfcc33
                 slash_star,
Packit bfcc33
                 star_slash,
Packit bfcc33
                 false
Packit bfcc33
               >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
    /* not use anymore - remove?
Packit bfcc33
    const char* block_comment_prefix(const char* src) {
Packit bfcc33
      return exactly<slash_star>(src);
Packit bfcc33
    }
Packit bfcc33
    // Match either comment.
Packit bfcc33
    const char* comment(const char* src) {
Packit bfcc33
      return line_comment(src);
Packit bfcc33
    }
Packit bfcc33
    */
Packit bfcc33
Packit bfcc33
    // Match zero plus white-space or line_comments
Packit bfcc33
    const char* optional_css_whitespace(const char* src) {
Packit bfcc33
      return zero_plus< alternatives<spaces, line_comment> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* css_whitespace(const char* src) {
Packit bfcc33
      return one_plus< alternatives<spaces, line_comment> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match optional_css_whitepace plus block_comments
Packit bfcc33
    const char* optional_css_comments(const char* src) {
Packit bfcc33
      return zero_plus< alternatives<spaces, line_comment, block_comment> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* css_comments(const char* src) {
Packit bfcc33
      return one_plus< alternatives<spaces, line_comment, block_comment> >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match one backslash escaped char /\\./
Packit bfcc33
    const char* escape_seq(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence<
Packit bfcc33
        exactly<'\\'>,
Packit bfcc33
        alternatives <
Packit bfcc33
          minmax_range<
Packit bfcc33
            1, 3, xdigit
Packit bfcc33
          >,
Packit bfcc33
          any_char
Packit bfcc33
        >,
Packit bfcc33
        optional <
Packit bfcc33
          exactly <' '>
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match identifier start
Packit bfcc33
    const char* identifier_alpha(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return alternatives<
Packit bfcc33
               unicode_seq,
Packit bfcc33
               alpha,
Packit bfcc33
               unicode,
Packit bfcc33
               exactly<'-'>,
Packit bfcc33
               exactly<'_'>,
Packit bfcc33
               NONASCII,
Packit bfcc33
               ESCAPE,
Packit bfcc33
               escape_seq
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match identifier after start
Packit bfcc33
    const char* identifier_alnum(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return alternatives<
Packit bfcc33
               unicode_seq,
Packit bfcc33
               alnum,
Packit bfcc33
               unicode,
Packit bfcc33
               exactly<'-'>,
Packit bfcc33
               exactly<'_'>,
Packit bfcc33
               NONASCII,
Packit bfcc33
               ESCAPE,
Packit bfcc33
               escape_seq
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match CSS identifiers.
Packit bfcc33
    const char* strict_identifier(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence<
Packit bfcc33
               one_plus < strict_identifier_alpha >,
Packit bfcc33
               zero_plus < strict_identifier_alnum >
Packit bfcc33
               // word_boundary not needed
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match CSS identifiers.
Packit bfcc33
    const char* identifier(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence<
Packit bfcc33
               zero_plus< exactly<'-'> >,
Packit bfcc33
               one_plus < identifier_alpha >,
Packit bfcc33
               zero_plus < identifier_alnum >
Packit bfcc33
               // word_boundary not needed
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* strict_identifier_alpha(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return alternatives <
Packit bfcc33
               alpha,
Packit bfcc33
               unicode,
Packit bfcc33
               escape_seq,
Packit bfcc33
               exactly<'_'>
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* strict_identifier_alnum(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return alternatives <
Packit bfcc33
               alnum,
Packit bfcc33
               unicode,
Packit bfcc33
               escape_seq,
Packit bfcc33
               exactly<'_'>
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match a single CSS unit
Packit bfcc33
    const char* one_unit(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
               optional < exactly <'-'> >,
Packit bfcc33
               strict_identifier_alpha,
Packit bfcc33
               zero_plus < alternatives<
Packit bfcc33
                 strict_identifier_alnum,
Packit bfcc33
                 sequence <
Packit bfcc33
                   one_plus < exactly<'-'> >,
Packit bfcc33
                   strict_identifier_alpha
Packit bfcc33
                 >
Packit bfcc33
               > >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match numerator/denominator CSS units
Packit bfcc33
    const char* multiple_units(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return
Packit bfcc33
        sequence <
Packit bfcc33
          one_unit,
Packit bfcc33
          zero_plus <
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'*'>,
Packit bfcc33
              one_unit
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match complex CSS unit identifiers
Packit bfcc33
    const char* unit_identifier(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        multiple_units,
Packit bfcc33
        optional <
Packit bfcc33
          sequence <
Packit bfcc33
          exactly <'/'>,
Packit bfcc33
          negate < sequence <
Packit bfcc33
            exactly < calc_fn_kwd >,
Packit bfcc33
            exactly < '(' >
Packit bfcc33
          > >,
Packit bfcc33
          multiple_units
Packit bfcc33
        > >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* identifier_alnums(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return one_plus< identifier_alnum >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match number prefix ([\+\-]+)
Packit bfcc33
    const char* number_prefix(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
        exactly < '+' >,
Packit bfcc33
        sequence <
Packit bfcc33
          exactly < '-' >,
Packit bfcc33
          optional_css_whitespace,
Packit bfcc33
          exactly< '-' >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match interpolant schemas
Packit bfcc33
    const char* identifier_schema(const char* src) {
Packit bfcc33
Packit bfcc33
      return sequence <
Packit bfcc33
               one_plus <
Packit bfcc33
                 sequence <
Packit bfcc33
                   zero_plus <
Packit bfcc33
                     alternatives <
Packit bfcc33
                       sequence <
Packit bfcc33
                         optional <
Packit bfcc33
                           exactly <'$'>
Packit bfcc33
                         >,
Packit bfcc33
                         identifier
Packit bfcc33
                       >,
Packit bfcc33
                       exactly <'-'>
Packit bfcc33
                     >
Packit bfcc33
                   >,
Packit bfcc33
                   interpolant,
Packit bfcc33
                   zero_plus <
Packit bfcc33
                     alternatives <
Packit bfcc33
                       digits,
Packit bfcc33
                       sequence <
Packit bfcc33
                         optional <
Packit bfcc33
                           exactly <'$'>
Packit bfcc33
                         >,
Packit bfcc33
                         identifier
Packit bfcc33
                       >,
Packit bfcc33
                       quoted_string,
Packit bfcc33
                       exactly<'-'>
Packit bfcc33
                     >
Packit bfcc33
                   >
Packit bfcc33
                 >
Packit bfcc33
               >,
Packit bfcc33
               negate <
Packit bfcc33
                 exactly<'%'>
Packit bfcc33
               >
Packit bfcc33
             > (src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // interpolants can be recursive/nested
Packit bfcc33
    const char* interpolant(const char* src) {
Packit bfcc33
      return recursive_scopes< exactly<hash_lbrace>, exactly<rbrace> >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // $re_squote = /'(?:$re_itplnt|\\.|[^'])*'/
Packit bfcc33
    const char* single_quoted_string(const char* src) {
Packit bfcc33
      // match a single quoted string, while skipping interpolants
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <'\''>,
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // skip escapes
Packit bfcc33
            sequence <
Packit bfcc33
              exactly < '\\' >,
Packit bfcc33
              re_linebreak
Packit bfcc33
            >,
Packit bfcc33
            escape_seq,
Packit bfcc33
            unicode_seq,
Packit bfcc33
            // skip interpolants
Packit bfcc33
            interpolant,
Packit bfcc33
            // skip non delimiters
Packit bfcc33
            any_char_but < '\'' >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        exactly <'\''>
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // $re_dquote = /"(?:$re_itp|\\.|[^"])*"/
Packit bfcc33
    const char* double_quoted_string(const char* src) {
Packit bfcc33
      // match a single quoted string, while skipping interpolants
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <'"'>,
Packit bfcc33
        zero_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // skip escapes
Packit bfcc33
            sequence <
Packit bfcc33
              exactly < '\\' >,
Packit bfcc33
              re_linebreak
Packit bfcc33
            >,
Packit bfcc33
            escape_seq,
Packit bfcc33
            unicode_seq,
Packit bfcc33
            // skip interpolants
Packit bfcc33
            interpolant,
Packit bfcc33
            // skip non delimiters
Packit bfcc33
            any_char_but < '"' >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        exactly <'"'>
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // $re_quoted = /(?:$re_squote|$re_dquote)/
Packit bfcc33
    const char* quoted_string(const char* src) {
Packit bfcc33
      // match a quoted string, while skipping interpolants
Packit bfcc33
      return alternatives<
Packit bfcc33
        single_quoted_string,
Packit bfcc33
        double_quoted_string
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* sass_value(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
        quoted_string,
Packit bfcc33
        identifier,
Packit bfcc33
        percentage,
Packit bfcc33
        hex,
Packit bfcc33
        dimension,
Packit bfcc33
        number
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // this is basically `one_plus < sass_value >`
Packit bfcc33
    // takes care to not parse invalid combinations
Packit bfcc33
    const char* value_combinations(const char* src) {
Packit bfcc33
      // `2px-2px` is invalid combo
Packit bfcc33
      bool was_number = false;
Packit bfcc33
      const char* pos;
Packit bfcc33
      while (src) {
Packit bfcc33
        if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {
Packit bfcc33
          was_number = false;
Packit bfcc33
          src = pos;
Packit bfcc33
        } else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) {
Packit bfcc33
          was_number = true;
Packit bfcc33
          src = pos;
Packit bfcc33
        } else {
Packit bfcc33
          break;
Packit bfcc33
        }
Packit bfcc33
      }
Packit bfcc33
      return src;
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // must be at least one interpolant
Packit bfcc33
    // can be surrounded by sass values
Packit bfcc33
    // make sure to never parse (dim)(dim)
Packit bfcc33
    // since this wrongly consumes `2px-1px`
Packit bfcc33
    // `2px1px` is valid number (unit `px1px`)
Packit bfcc33
    const char* value_schema(const char* src)
Packit bfcc33
    {
Packit bfcc33
      return sequence <
Packit bfcc33
        one_plus <
Packit bfcc33
          sequence <
Packit bfcc33
            optional < value_combinations >,
Packit bfcc33
            interpolant,
Packit bfcc33
            optional < value_combinations >
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match CSS '@' keywords.
Packit bfcc33
    const char* at_keyword(const char* src) {
Packit bfcc33
      return sequence<exactly<'@'>, identifier>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /*
Packit bfcc33
        tok(%r{
Packit bfcc33
          (
Packit bfcc33
            \\.
Packit bfcc33
          |
Packit bfcc33
            (?!url\()
Packit bfcc33
            [^"'/\#!;\{\}] # "
Packit bfcc33
          |
Packit bfcc33
            /(?![\*\/])
Packit bfcc33
          |
Packit bfcc33
            \#(?!\{)
Packit bfcc33
          |
Packit bfcc33
            !(?![a-z]) # TODO: never consume "!" when issue 1126 is fixed.
Packit bfcc33
          )+
Packit bfcc33
        }xi) || tok(COMMENT) || tok(SINGLE_LINE_COMMENT) || interp_string || interp_uri ||
Packit bfcc33
                interpolation(:warn_for_color)
Packit bfcc33
    */
Packit bfcc33
    const char* re_almost_any_value_token(const char* src) {
Packit bfcc33
Packit bfcc33
      return alternatives <
Packit bfcc33
        one_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              any_char
Packit bfcc33
            >,
Packit bfcc33
            sequence <
Packit bfcc33
              negate <
Packit bfcc33
                sequence <
Packit bfcc33
                  exactly < url_kwd >,
Packit bfcc33
                  exactly <'('>
Packit bfcc33
                >
Packit bfcc33
              >,
Packit bfcc33
              neg_class_char <
Packit bfcc33
                almost_any_value_class
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'/'>,
Packit bfcc33
              negate <
Packit bfcc33
                alternatives <
Packit bfcc33
                  exactly <'/'>,
Packit bfcc33
                  exactly <'*'>
Packit bfcc33
                >
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'\\'>,
Packit bfcc33
              exactly <'#'>,
Packit bfcc33
              negate <
Packit bfcc33
                exactly <'{'>
Packit bfcc33
              >
Packit bfcc33
            >,
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'!'>,
Packit bfcc33
              negate <
Packit bfcc33
                alpha
Packit bfcc33
              >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        block_comment,
Packit bfcc33
        line_comment,
Packit bfcc33
        interpolant,
Packit bfcc33
        space,
Packit bfcc33
        sequence <
Packit bfcc33
          exactly<'u'>,
Packit bfcc33
          exactly<'r'>,
Packit bfcc33
          exactly<'l'>,
Packit bfcc33
          exactly<'('>,
Packit bfcc33
          zero_plus <
Packit bfcc33
            alternatives <
Packit bfcc33
              class_char< real_uri_chars >,
Packit bfcc33
              uri_character,
Packit bfcc33
              NONASCII,
Packit bfcc33
              ESCAPE
Packit bfcc33
            >
Packit bfcc33
          >,
Packit bfcc33
          // false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
Packit bfcc33
          // true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
Packit bfcc33
          exactly<')'>
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /*
Packit bfcc33
      DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
Packit bfcc33
        :each, :while, :if, :else, :extend, :import, :media, :charset, :content,
Packit bfcc33
        :_moz_document, :at_root, :error]
Packit bfcc33
    */
Packit bfcc33
    const char* re_special_directive(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
        word < mixin_kwd >,
Packit bfcc33
        word < include_kwd >,
Packit bfcc33
        word < function_kwd >,
Packit bfcc33
        word < return_kwd >,
Packit bfcc33
        word < debug_kwd >,
Packit bfcc33
        word < warn_kwd >,
Packit bfcc33
        word < for_kwd >,
Packit bfcc33
        word < each_kwd >,
Packit bfcc33
        word < while_kwd >,
Packit bfcc33
        word < if_kwd >,
Packit bfcc33
        word < else_kwd >,
Packit bfcc33
        word < extend_kwd >,
Packit bfcc33
        word < import_kwd >,
Packit bfcc33
        word < media_kwd >,
Packit bfcc33
        word < charset_kwd >,
Packit bfcc33
        word < content_kwd >,
Packit bfcc33
        // exactly < moz_document_kwd >,
Packit bfcc33
        word < at_root_kwd >,
Packit bfcc33
        word < error_kwd >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_prefixed_directive(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        optional <
Packit bfcc33
          sequence <
Packit bfcc33
            exactly <'-'>,
Packit bfcc33
            one_plus < alnum >,
Packit bfcc33
            exactly <'-'>
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        exactly < supports_kwd >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_reference_combinator(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        optional <
Packit bfcc33
          sequence <
Packit bfcc33
            zero_plus <
Packit bfcc33
              exactly <'-'>
Packit bfcc33
            >,
Packit bfcc33
            identifier,
Packit bfcc33
            exactly <'|'>
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        zero_plus <
Packit bfcc33
          exactly <'-'>
Packit bfcc33
        >,
Packit bfcc33
        identifier
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* static_reference_combinator(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <'/'>,
Packit bfcc33
        re_reference_combinator,
Packit bfcc33
        exactly <'/'>
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* schema_reference_combinator(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <'/'>,
Packit bfcc33
        optional <
Packit bfcc33
          sequence <
Packit bfcc33
            css_ip_identifier,
Packit bfcc33
            exactly <'|'>
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        css_ip_identifier,
Packit bfcc33
        exactly <'/'>
Packit bfcc33
      > (src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_import(const char* src) {
Packit bfcc33
      return word<import_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_at_root(const char* src) {
Packit bfcc33
      return word<at_root_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_with_directive(const char* src) {
Packit bfcc33
      return word<with_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_without_directive(const char* src) {
Packit bfcc33
      return word<without_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_media(const char* src) {
Packit bfcc33
      return word<media_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_supports_directive(const char* src) {
Packit bfcc33
      return word<supports_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_mixin(const char* src) {
Packit bfcc33
      return word<mixin_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_function(const char* src) {
Packit bfcc33
      return word<function_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_return_directive(const char* src) {
Packit bfcc33
      return word<return_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_include_directive(const char* src) {
Packit bfcc33
      return word<include_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_content_directive(const char* src) {
Packit bfcc33
      return word<content_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_charset_directive(const char* src) {
Packit bfcc33
      return word<charset_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_extend(const char* src) {
Packit bfcc33
      return word<extend_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
Packit bfcc33
    const char* kwd_if_directive(const char* src) {
Packit bfcc33
      return word<if_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_else_directive(const char* src) {
Packit bfcc33
      return word<else_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* elseif_directive(const char* src) {
Packit bfcc33
      return sequence< exactly< else_kwd >,
Packit bfcc33
                                optional_css_comments,
Packit bfcc33
                                word< if_after_else_kwd > >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_for_directive(const char* src) {
Packit bfcc33
      return word<for_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_from(const char* src) {
Packit bfcc33
      return word<from_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_to(const char* src) {
Packit bfcc33
      return word<to_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_through(const char* src) {
Packit bfcc33
      return word<through_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_each_directive(const char* src) {
Packit bfcc33
      return word<each_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_in(const char* src) {
Packit bfcc33
      return word<in_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_while_directive(const char* src) {
Packit bfcc33
      return word<while_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* name(const char* src) {
Packit bfcc33
      return one_plus< alternatives< alnum,
Packit bfcc33
                                     exactly<'-'>,
Packit bfcc33
                                     exactly<'_'>,
Packit bfcc33
                                     escape_seq > >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_warn(const char* src) {
Packit bfcc33
      return word<warn_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_err(const char* src) {
Packit bfcc33
      return word<error_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* kwd_dbg(const char* src) {
Packit bfcc33
      return word<debug_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* directive(const char* src) {
Packit bfcc33
      return sequence< exactly<'@'>, identifier >(src);
Packit bfcc33
    } */
Packit bfcc33
Packit bfcc33
    const char* kwd_null(const char* src) {
Packit bfcc33
      return word<null_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* css_identifier(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               zero_plus <
Packit bfcc33
                 exactly <'-'>
Packit bfcc33
               >,
Packit bfcc33
               identifier
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* css_ip_identifier(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               zero_plus <
Packit bfcc33
                 exactly <'-'>
Packit bfcc33
               >,
Packit bfcc33
               alternatives <
Packit bfcc33
                 identifier,
Packit bfcc33
                 interpolant
Packit bfcc33
               >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match CSS type selectors
Packit bfcc33
    const char* namespace_prefix(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               optional <
Packit bfcc33
                 alternatives <
Packit bfcc33
                   exactly <'*'>,
Packit bfcc33
                   css_identifier
Packit bfcc33
                 >
Packit bfcc33
               >,
Packit bfcc33
               exactly <'|'>,
Packit bfcc33
               negate <
Packit bfcc33
                 exactly <'='>
Packit bfcc33
               >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match CSS type selectors
Packit bfcc33
    const char* namespace_schema(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               optional <
Packit bfcc33
                 alternatives <
Packit bfcc33
                   exactly <'*'>,
Packit bfcc33
                   css_ip_identifier
Packit bfcc33
                 >
Packit bfcc33
               >,
Packit bfcc33
               exactly<'|'>,
Packit bfcc33
               negate <
Packit bfcc33
                 exactly <'='>
Packit bfcc33
               >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* hyphens_and_identifier(const char* src) {
Packit bfcc33
      return sequence< zero_plus< exactly< '-' > >, identifier_alnums >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* hyphens_and_name(const char* src) {
Packit bfcc33
      return sequence< zero_plus< exactly< '-' > >, name >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* universal(const char* src) {
Packit bfcc33
      return sequence< optional<namespace_schema>, exactly<'*'> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS id names.
Packit bfcc33
    const char* id_name(const char* src) {
Packit bfcc33
      return sequence<exactly<'#'>, identifier_alnums >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS class names.
Packit bfcc33
    const char* class_name(const char* src) {
Packit bfcc33
      return sequence<exactly<'.'>, identifier >(src);
Packit bfcc33
    }
Packit bfcc33
    // Attribute name in an attribute selector.
Packit bfcc33
    const char* attribute_name(const char* src) {
Packit bfcc33
      return alternatives< sequence< optional<namespace_schema>, identifier>,
Packit bfcc33
                           identifier >(src);
Packit bfcc33
    }
Packit bfcc33
    // match placeholder selectors
Packit bfcc33
    const char* placeholder(const char* src) {
Packit bfcc33
      return sequence<exactly<'%'>, identifier_alnums >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS numeric constants.
Packit bfcc33
Packit bfcc33
    const char* op(const char* src) {
Packit bfcc33
      return class_char<op_chars>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* sign(const char* src) {
Packit bfcc33
      return class_char<sign_chars>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* unsigned_number(const char* src) {
Packit bfcc33
      return alternatives<sequence< zero_plus<digits>,
Packit bfcc33
                                    exactly<'.'>,
Packit bfcc33
                                    one_plus<digits> >,
Packit bfcc33
                          digits>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* number(const char* src) {
Packit bfcc33
      return sequence< optional<sign>, unsigned_number>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* coefficient(const char* src) {
Packit bfcc33
      return alternatives< sequence< optional<sign>, digits >,
Packit bfcc33
                           sign >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* binomial(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               optional < sign >,
Packit bfcc33
               optional < digits >,
Packit bfcc33
               exactly <'n'>,
Packit bfcc33
               zero_plus < sequence <
Packit bfcc33
                 optional_css_whitespace, sign,
Packit bfcc33
                 optional_css_whitespace, digits
Packit bfcc33
               > >
Packit bfcc33
             >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* percentage(const char* src) {
Packit bfcc33
      return sequence< number, exactly<'%'> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* ampersand(const char* src) {
Packit bfcc33
      return exactly<'&'>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* em(const char* src) {
Packit bfcc33
      return sequence< number, exactly<em_kwd> >(src);
Packit bfcc33
    } */
Packit bfcc33
    const char* dimension(const char* src) {
Packit bfcc33
      return sequence<number, unit_identifier >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* hex(const char* src) {
Packit bfcc33
      const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
Packit bfcc33
      ptrdiff_t len = p - src;
Packit bfcc33
      return (len != 4 && len != 7) ? 0 : p;
Packit bfcc33
    }
Packit bfcc33
    const char* hexa(const char* src) {
Packit bfcc33
      const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
Packit bfcc33
      ptrdiff_t len = p - src;
Packit bfcc33
      return (len != 4 && len != 7 && len != 9) ? 0 : p;
Packit bfcc33
    }
Packit bfcc33
    const char* hex0(const char* src) {
Packit bfcc33
      const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);
Packit bfcc33
      ptrdiff_t len = p - src;
Packit bfcc33
      return (len != 5 && len != 8) ? 0 : p;
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    /* no longer used - remove?
Packit bfcc33
    const char* rgb_prefix(const char* src) {
Packit bfcc33
      return word<rgb_kwd>(src);
Packit bfcc33
    }*/
Packit bfcc33
    // Match CSS uri specifiers.
Packit bfcc33
Packit bfcc33
    const char* uri_prefix(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly <
Packit bfcc33
          url_kwd
Packit bfcc33
        >,
Packit bfcc33
        zero_plus <
Packit bfcc33
          sequence <
Packit bfcc33
            exactly <'-'>,
Packit bfcc33
            one_plus <
Packit bfcc33
              alpha
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        exactly <'('>
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // TODO: rename the following two functions
Packit bfcc33
    /* no longer used - remove?
Packit bfcc33
    const char* uri(const char* src) {
Packit bfcc33
      return sequence< exactly<url_kwd>,
Packit bfcc33
                       optional<spaces>,
Packit bfcc33
                       quoted_string,
Packit bfcc33
                       optional<spaces>,
Packit bfcc33
                       exactly<')'> >(src);
Packit bfcc33
    }*/
Packit bfcc33
    /* no longer used - remove?
Packit bfcc33
    const char* url_value(const char* src) {
Packit bfcc33
      return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
Packit bfcc33
                       one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename
Packit bfcc33
                       optional< exactly<'/'> > >(src);
Packit bfcc33
    }*/
Packit bfcc33
    /* no longer used - remove?
Packit bfcc33
    const char* url_schema(const char* src) {
Packit bfcc33
      return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
Packit bfcc33
                       filename_schema >(src); // optional trailing slash
Packit bfcc33
    }*/
Packit bfcc33
    // Match CSS "!important" keyword.
Packit bfcc33
    const char* kwd_important(const char* src) {
Packit bfcc33
      return sequence< exactly<'!'>,
Packit bfcc33
                       optional_css_whitespace,
Packit bfcc33
                       word<important_kwd> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS "!optional" keyword.
Packit bfcc33
    const char* kwd_optional(const char* src) {
Packit bfcc33
      return sequence< exactly<'!'>,
Packit bfcc33
      optional_css_whitespace,
Packit bfcc33
      word<optional_kwd> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match Sass "!default" keyword.
Packit bfcc33
    const char* default_flag(const char* src) {
Packit bfcc33
      return sequence< exactly<'!'>,
Packit bfcc33
                       optional_css_whitespace,
Packit bfcc33
                       word<default_kwd> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match Sass "!global" keyword.
Packit bfcc33
    const char* global_flag(const char* src) {
Packit bfcc33
      return sequence< exactly<'!'>,
Packit bfcc33
                       optional_css_whitespace,
Packit bfcc33
                       word<global_kwd> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS pseudo-class/element prefixes.
Packit bfcc33
    const char* pseudo_prefix(const char* src) {
Packit bfcc33
      return sequence< exactly<':'>, optional< exactly<':'> > >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS function call openers.
Packit bfcc33
    const char* functional_schema(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
               one_plus <
Packit bfcc33
                 sequence <
Packit bfcc33
                   zero_plus <
Packit bfcc33
                     alternatives <
Packit bfcc33
                       identifier,
Packit bfcc33
                       exactly <'-'>
Packit bfcc33
                     >
Packit bfcc33
                   >,
Packit bfcc33
                   one_plus <
Packit bfcc33
                     sequence <
Packit bfcc33
                       interpolant,
Packit bfcc33
                       alternatives <
Packit bfcc33
                         digits,
Packit bfcc33
                         identifier,
Packit bfcc33
                         exactly<'+'>,
Packit bfcc33
                         exactly<'-'>
Packit bfcc33
                       >
Packit bfcc33
                     >
Packit bfcc33
                   >
Packit bfcc33
                 >
Packit bfcc33
               >,
Packit bfcc33
               negate <
Packit bfcc33
                 exactly <'%'>
Packit bfcc33
               >,
Packit bfcc33
               lookahead <
Packit bfcc33
                 exactly <'('>
Packit bfcc33
               >
Packit bfcc33
             > (src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_nothing(const char* src) {
Packit bfcc33
      return src;
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_functional(const char* src) {
Packit bfcc33
      return sequence< identifier, optional < block_comment >, exactly<'('> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* re_pseudo_selector(const char* src) {
Packit bfcc33
      return sequence< identifier, optional < block_comment >, exactly<'('> >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match the CSS negation pseudo-class.
Packit bfcc33
    const char* pseudo_not(const char* src) {
Packit bfcc33
      return word< pseudo_not_kwd >(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
Packit bfcc33
    const char* even(const char* src) {
Packit bfcc33
      return word<even_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* odd(const char* src) {
Packit bfcc33
      return word<odd_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
    // Match CSS attribute-matching operators.
Packit bfcc33
    const char* exact_match(const char* src) { return exactly<'='>(src); }
Packit bfcc33
    const char* class_match(const char* src) { return exactly<tilde_equal>(src); }
Packit bfcc33
    const char* dash_match(const char* src) { return exactly<pipe_equal>(src); }
Packit bfcc33
    const char* prefix_match(const char* src) { return exactly<caret_equal>(src); }
Packit bfcc33
    const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }
Packit bfcc33
    const char* substring_match(const char* src) { return exactly<star_equal>(src); }
Packit bfcc33
    // Match CSS combinators.
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* adjacent_to(const char* src) {
Packit bfcc33
      return sequence< optional_spaces, exactly<'+'> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* precedes(const char* src) {
Packit bfcc33
      return sequence< optional_spaces, exactly<'~'> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* parent_of(const char* src) {
Packit bfcc33
      return sequence< optional_spaces, exactly<'>'> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* ancestor_of(const char* src) {
Packit bfcc33
      return sequence< spaces, negate< exactly<'{'> > >(src);
Packit bfcc33
    }*/
Packit bfcc33
Packit bfcc33
    // Match SCSS variable names.
Packit bfcc33
    const char* variable(const char* src) {
Packit bfcc33
      return sequence<exactly<'$'>, identifier>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // parse `calc`, `-a-calc` and `--b-c-calc`
Packit bfcc33
    // but do not parse `foocalc` or `foo-calc`
Packit bfcc33
    const char* calc_fn_call(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        optional < sequence <
Packit bfcc33
          hyphens,
Packit bfcc33
          one_plus < sequence <
Packit bfcc33
            strict_identifier,
Packit bfcc33
            hyphens
Packit bfcc33
          > >
Packit bfcc33
        > >,
Packit bfcc33
        exactly < calc_fn_kwd >,
Packit bfcc33
        word_boundary
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Match Sass boolean keywords.
Packit bfcc33
    const char* kwd_true(const char* src) {
Packit bfcc33
      return word<true_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_false(const char* src) {
Packit bfcc33
      return word<false_kwd>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_only(const char* src) {
Packit bfcc33
      return keyword < only_kwd >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_and(const char* src) {
Packit bfcc33
      return keyword < and_kwd >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_or(const char* src) {
Packit bfcc33
      return keyword < or_kwd >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_not(const char* src) {
Packit bfcc33
      return keyword < not_kwd >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_eq(const char* src) {
Packit bfcc33
      return exactly<eq>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_neq(const char* src) {
Packit bfcc33
      return exactly<neq>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_gt(const char* src) {
Packit bfcc33
      return exactly<gt>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_gte(const char* src) {
Packit bfcc33
      return exactly<gte>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_lt(const char* src) {
Packit bfcc33
      return exactly<lt>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* kwd_lte(const char* src) {
Packit bfcc33
      return exactly<lte>(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // match specific IE syntax
Packit bfcc33
    const char* ie_progid(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        word<progid_kwd>,
Packit bfcc33
        exactly<':'>,
Packit bfcc33
        alternatives< identifier_schema, identifier >,
Packit bfcc33
        zero_plus< sequence<
Packit bfcc33
          exactly<'.'>,
Packit bfcc33
          alternatives< identifier_schema, identifier >
Packit bfcc33
        > >,
Packit bfcc33
        zero_plus < sequence<
Packit bfcc33
          exactly<'('>,
Packit bfcc33
          optional_css_whitespace,
Packit bfcc33
          optional < sequence<
Packit bfcc33
            alternatives< variable, identifier_schema, identifier >,
Packit bfcc33
            optional_css_whitespace,
Packit bfcc33
            exactly<'='>,
Packit bfcc33
            optional_css_whitespace,
Packit bfcc33
            alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >,
Packit bfcc33
            zero_plus< sequence<
Packit bfcc33
              optional_css_whitespace,
Packit bfcc33
              exactly<','>,
Packit bfcc33
              optional_css_whitespace,
Packit bfcc33
              sequence<
Packit bfcc33
                alternatives< variable, identifier_schema, identifier >,
Packit bfcc33
                optional_css_whitespace,
Packit bfcc33
                exactly<'='>,
Packit bfcc33
                optional_css_whitespace,
Packit bfcc33
                alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
Packit bfcc33
              >
Packit bfcc33
            > >
Packit bfcc33
          > >,
Packit bfcc33
          optional_css_whitespace,
Packit bfcc33
          exactly<')'>
Packit bfcc33
        > >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* ie_expression(const char* src) {
Packit bfcc33
      return sequence < word<expression_kwd>, exactly<'('>, skip_over_scopes< exactly<'('>, exactly<')'> > >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* ie_property(const char* src) {
Packit bfcc33
      return alternatives < ie_expression, ie_progid >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // const char* ie_args(const char* src) {
Packit bfcc33
    //   return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >,
Packit bfcc33
    //                    zero_plus< sequence< optional_css_whitespace, exactly<','>, optional_css_whitespace, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
Packit bfcc33
    // }
Packit bfcc33
Packit bfcc33
    const char* ie_keyword_arg_property(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
          variable,
Packit bfcc33
          identifier_schema,
Packit bfcc33
          identifier
Packit bfcc33
        >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* ie_keyword_arg_value(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
          variable,
Packit bfcc33
          identifier_schema,
Packit bfcc33
          identifier,
Packit bfcc33
          quoted_string,
Packit bfcc33
          number,
Packit bfcc33
          hexa,
Packit bfcc33
          sequence <
Packit bfcc33
            exactly < '(' >,
Packit bfcc33
            skip_over_scopes <
Packit bfcc33
              exactly < '(' >,
Packit bfcc33
              exactly < ')' >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* ie_keyword_arg(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        ie_keyword_arg_property,
Packit bfcc33
        optional_css_whitespace,
Packit bfcc33
        exactly<'='>,
Packit bfcc33
        optional_css_whitespace,
Packit bfcc33
        ie_keyword_arg_value
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // Path matching functions.
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* folder(const char* src) {
Packit bfcc33
      return sequence< zero_plus< any_char_except<'/'> >,
Packit bfcc33
                       exactly<'/'> >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* folders(const char* src) {
Packit bfcc33
      return zero_plus< folder >(src);
Packit bfcc33
    }*/
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* chunk(const char* src) {
Packit bfcc33
      char inside_str = 0;
Packit bfcc33
      const char* p = src;
Packit bfcc33
      size_t depth = 0;
Packit bfcc33
      while (true) {
Packit bfcc33
        if (!*p) {
Packit bfcc33
          return 0;
Packit bfcc33
        }
Packit bfcc33
        else if (!inside_str && (*p == '"' || *p == '\'')) {
Packit bfcc33
          inside_str = *p;
Packit bfcc33
        }
Packit bfcc33
        else if (*p == inside_str && *(p-1) != '\\') {
Packit bfcc33
          inside_str = 0;
Packit bfcc33
        }
Packit bfcc33
        else if (*p == '(' && !inside_str) {
Packit bfcc33
          ++depth;
Packit bfcc33
        }
Packit bfcc33
        else if (*p == ')' && !inside_str) {
Packit bfcc33
          if (depth == 0) return p;
Packit bfcc33
          else            --depth;
Packit bfcc33
        }
Packit bfcc33
        ++p;
Packit bfcc33
      }
Packit bfcc33
      // unreachable
Packit bfcc33
      return 0;
Packit bfcc33
    }
Packit bfcc33
    */
Packit bfcc33
Packit bfcc33
    // follow the CSS spec more closely and see if this helps us scan URLs correctly
Packit bfcc33
    /* not used anymore - remove?
Packit bfcc33
    const char* NL(const char* src) {
Packit bfcc33
      return alternatives< exactly<'\n'>,
Packit bfcc33
                           sequence< exactly<'\r'>, exactly<'\n'> >,
Packit bfcc33
                           exactly<'\r'>,
Packit bfcc33
                           exactly<'\f'> >(src);
Packit bfcc33
    }*/
Packit bfcc33
Packit bfcc33
    const char* H(const char* src) {
Packit bfcc33
      return std::isxdigit(*src) ? src+1 : 0;
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* W(const char* src) {
Packit bfcc33
      return zero_plus< alternatives<
Packit bfcc33
        space,
Packit bfcc33
        exactly< '\t' >,
Packit bfcc33
        exactly< '\r' >,
Packit bfcc33
        exactly< '\n' >,
Packit bfcc33
        exactly< '\f' >
Packit bfcc33
      > >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* UUNICODE(const char* src) {
Packit bfcc33
      return sequence< exactly<'\\'>,
Packit bfcc33
                       between<H, 1, 6>,
Packit bfcc33
                       optional< W >
Packit bfcc33
                       >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* NONASCII(const char* src) {
Packit bfcc33
      return nonascii(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* ESCAPE(const char* src) {
Packit bfcc33
      return alternatives<
Packit bfcc33
        UUNICODE,
Packit bfcc33
        sequence<
Packit bfcc33
          exactly<'\\'>,
Packit bfcc33
          alternatives<
Packit bfcc33
            NONASCII,
Packit bfcc33
            escapable_character
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
Packit bfcc33
    // const char* real_uri_prefix(const char* src) {
Packit bfcc33
    //   return alternatives<
Packit bfcc33
    //     exactly< url_kwd >,
Packit bfcc33
    //     exactly< url_prefix_kwd >
Packit bfcc33
    //   >(src);
Packit bfcc33
    // }
Packit bfcc33
Packit bfcc33
    const char* real_uri_suffix(const char* src) {
Packit bfcc33
      return sequence< W, exactly< ')' > >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* real_uri_value(const char* src) {
Packit bfcc33
      return
Packit bfcc33
      sequence<
Packit bfcc33
        non_greedy<
Packit bfcc33
          alternatives<
Packit bfcc33
            class_char< real_uri_chars >,
Packit bfcc33
            uri_character,
Packit bfcc33
            NONASCII,
Packit bfcc33
            ESCAPE
Packit bfcc33
          >,
Packit bfcc33
          alternatives<
Packit bfcc33
            real_uri_suffix,
Packit bfcc33
            exactly< hash_lbrace >
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >
Packit bfcc33
      (src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* static_string(const char* src) {
Packit bfcc33
      const char* pos = src;
Packit bfcc33
      const char * s = quoted_string(pos);
Packit bfcc33
      Token t(pos, s);
Packit bfcc33
      const unsigned int p = count_interval< interpolant >(t.begin, t.end);
Packit bfcc33
      return (p == 0) ? t.end : 0;
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* unicode_seq(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        alternatives <
Packit bfcc33
          exactly< 'U' >,
Packit bfcc33
          exactly< 'u' >
Packit bfcc33
        >,
Packit bfcc33
        exactly< '+' >,
Packit bfcc33
        padded_token <
Packit bfcc33
          6, xdigit,
Packit bfcc33
          exactly < '?' >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* static_component(const char* src) {
Packit bfcc33
      return alternatives< identifier,
Packit bfcc33
                           static_string,
Packit bfcc33
                           percentage,
Packit bfcc33
                           hex,
Packit bfcc33
                           exactly<'|'>,
Packit bfcc33
                           // exactly<'+'>,
Packit bfcc33
                           sequence < number, unit_identifier >,
Packit bfcc33
                           number,
Packit bfcc33
                           sequence< exactly<'!'>, word<important_kwd> >
Packit bfcc33
                          >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* static_property(const char* src) {
Packit bfcc33
      return
Packit bfcc33
        sequence <
Packit bfcc33
          zero_plus<
Packit bfcc33
            sequence <
Packit bfcc33
              optional_css_comments,
Packit bfcc33
              alternatives <
Packit bfcc33
                exactly<','>,
Packit bfcc33
                exactly<'('>,
Packit bfcc33
                exactly<')'>,
Packit bfcc33
                kwd_optional,
Packit bfcc33
                quoted_string,
Packit bfcc33
                interpolant,
Packit bfcc33
                identifier,
Packit bfcc33
                percentage,
Packit bfcc33
                dimension,
Packit bfcc33
                variable,
Packit bfcc33
                alnum,
Packit bfcc33
                sequence <
Packit bfcc33
                  exactly <'\\'>,
Packit bfcc33
                  any_char
Packit bfcc33
                >
Packit bfcc33
              >
Packit bfcc33
            >
Packit bfcc33
          >,
Packit bfcc33
          lookahead <
Packit bfcc33
            sequence <
Packit bfcc33
              optional_css_comments,
Packit bfcc33
              alternatives <
Packit bfcc33
                exactly <';'>,
Packit bfcc33
                exactly <'}'>,
Packit bfcc33
                end_of_file
Packit bfcc33
              >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* static_value(const char* src) {
Packit bfcc33
      return sequence< sequence<
Packit bfcc33
                         static_component,
Packit bfcc33
                         zero_plus< identifier >
Packit bfcc33
                       >,
Packit bfcc33
                       zero_plus < sequence<
Packit bfcc33
                                     alternatives<
Packit bfcc33
                                       sequence< optional_spaces, alternatives<
Packit bfcc33
                                         exactly < '/' >,
Packit bfcc33
                                         exactly < ',' >,
Packit bfcc33
                                         exactly < ' ' >
Packit bfcc33
                                       >, optional_spaces >,
Packit bfcc33
                                       spaces
Packit bfcc33
                                     >,
Packit bfcc33
                                     static_component
Packit bfcc33
                       > >,
Packit bfcc33
                       zero_plus < spaces >,
Packit bfcc33
                       alternatives< exactly<';'>, exactly<'}'> >
Packit bfcc33
                      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* parenthese_scope(const char* src) {
Packit bfcc33
      return sequence <
Packit bfcc33
        exactly < '(' >,
Packit bfcc33
        skip_over_scopes <
Packit bfcc33
          exactly < '(' >,
Packit bfcc33
          exactly < ')' >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* re_selector_list(const char* src) {
Packit bfcc33
      return alternatives <
Packit bfcc33
        // partial bem selector
Packit bfcc33
        sequence <
Packit bfcc33
          ampersand,
Packit bfcc33
          one_plus <
Packit bfcc33
            exactly < '-' >
Packit bfcc33
          >,
Packit bfcc33
          word_boundary,
Packit bfcc33
          optional_spaces
Packit bfcc33
        >,
Packit bfcc33
        // main selector matching
Packit bfcc33
        one_plus <
Packit bfcc33
          alternatives <
Packit bfcc33
            // consume whitespace and comments
Packit bfcc33
            spaces, block_comment, line_comment,
Packit bfcc33
            // match `/deep/` selector (pass-trough)
Packit bfcc33
            // there is no functionality for it yet
Packit bfcc33
            schema_reference_combinator,
Packit bfcc33
            // match selector ops /[*&%,\[\]]/
Packit bfcc33
            class_char < selector_lookahead_ops >,
Packit bfcc33
            // match selector combinators /[>+~]/
Packit bfcc33
            class_char < selector_combinator_ops >,
Packit bfcc33
            // match pseudo selectors
Packit bfcc33
            sequence <
Packit bfcc33
              exactly <'('>,
Packit bfcc33
              optional_spaces,
Packit bfcc33
              optional <re_selector_list>,
Packit bfcc33
              optional_spaces,
Packit bfcc33
              exactly <')'>
Packit bfcc33
            >,
Packit bfcc33
            // match attribute compare operators
Packit bfcc33
            alternatives <
Packit bfcc33
              exact_match, class_match, dash_match,
Packit bfcc33
              prefix_match, suffix_match, substring_match
Packit bfcc33
            >,
Packit bfcc33
            // main selector match
Packit bfcc33
            sequence <
Packit bfcc33
              // allow namespace prefix
Packit bfcc33
              optional < namespace_schema >,
Packit bfcc33
              // modifiers prefixes
Packit bfcc33
              alternatives <
Packit bfcc33
                sequence <
Packit bfcc33
                  exactly <'#'>,
Packit bfcc33
                  // not for interpolation
Packit bfcc33
                  negate < exactly <'{'> >
Packit bfcc33
                >,
Packit bfcc33
                // class match
Packit bfcc33
                exactly <'.'>,
Packit bfcc33
                // single or double colon
Packit bfcc33
                sequence <
Packit bfcc33
                  optional < pseudo_prefix >,
Packit bfcc33
                  // fix libsass issue 2376
Packit bfcc33
                  negate < exactly < url_kwd > >
Packit bfcc33
                >
Packit bfcc33
              >,
Packit bfcc33
              // accept hypens in token
Packit bfcc33
              one_plus < sequence <
Packit bfcc33
                // can start with hyphens
Packit bfcc33
                zero_plus <
Packit bfcc33
                  sequence <
Packit bfcc33
                    exactly <'-'>,
Packit bfcc33
                    optional_spaces
Packit bfcc33
                  >
Packit bfcc33
                >,
Packit bfcc33
                // now the main token
Packit bfcc33
                alternatives <
Packit bfcc33
                  kwd_optional,
Packit bfcc33
                  exactly <'*'>,
Packit bfcc33
                  quoted_string,
Packit bfcc33
                  interpolant,
Packit bfcc33
                  identifier,
Packit bfcc33
                  variable,
Packit bfcc33
                  percentage,
Packit bfcc33
                  binomial,
Packit bfcc33
                  dimension,
Packit bfcc33
                  alnum
Packit bfcc33
                >
Packit bfcc33
              > >,
Packit bfcc33
              // can also end with hyphens
Packit bfcc33
              zero_plus < exactly<'-'> >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    const char* type_selector(const char* src) {
Packit bfcc33
      return sequence< optional<namespace_schema>, identifier>(src);
Packit bfcc33
    }
Packit bfcc33
    const char* re_type_selector(const char* src) {
Packit bfcc33
      return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* re_type_selector2(const char* src) {
Packit bfcc33
      return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src);
Packit bfcc33
    }
Packit bfcc33
    const char* re_static_expression(const char* src) {
Packit bfcc33
      return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
    // lexer special_fn: these functions cannot be overloaded
Packit bfcc33
    // (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
Packit bfcc33
    const char* re_special_fun(const char* src) {
Packit bfcc33
Packit bfcc33
      // match this first as we test prefix hyphens
Packit bfcc33
      if (const char* calc = calc_fn_call(src)) {
Packit bfcc33
        return calc;
Packit bfcc33
      }
Packit bfcc33
Packit bfcc33
      return sequence <
Packit bfcc33
        optional <
Packit bfcc33
          sequence <
Packit bfcc33
            exactly <'-'>,
Packit bfcc33
            one_plus <
Packit bfcc33
              alternatives <
Packit bfcc33
                alpha,
Packit bfcc33
                exactly <'+'>,
Packit bfcc33
                exactly <'-'>
Packit bfcc33
              >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >,
Packit bfcc33
        alternatives <
Packit bfcc33
          word < expression_kwd >,
Packit bfcc33
          sequence <
Packit bfcc33
            sequence <
Packit bfcc33
              exactly < progid_kwd >,
Packit bfcc33
              exactly <':'>
Packit bfcc33
            >,
Packit bfcc33
            zero_plus <
Packit bfcc33
              alternatives <
Packit bfcc33
                char_range <'a', 'z'>,
Packit bfcc33
                exactly <'.'>
Packit bfcc33
              >
Packit bfcc33
            >
Packit bfcc33
          >
Packit bfcc33
        >
Packit bfcc33
      >(src);
Packit bfcc33
    }
Packit bfcc33
Packit bfcc33
  }
Packit bfcc33
}