yaml-cpp

FORK: A YAML parser and emitter in C++
git clone https://git.neptards.moe/neptards/yaml-cpp.git
Log | Files | Refs | README | LICENSE

regeximpl.h (4944B)


      1 #ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
      2 #define REGEXIMPL_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 "stream.h"
     11 #include "streamcharsource.h"
     12 #include "stringsource.h"
     13 
     14 namespace YAML {
     15 // query matches
     16 inline bool RegEx::Matches(char ch) const {
     17   std::string str;
     18   str += ch;
     19   return Matches(str);
     20 }
     21 
     22 inline bool RegEx::Matches(const std::string& str) const {
     23   return Match(str) >= 0;
     24 }
     25 
     26 inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; }
     27 
     28 template <typename Source>
     29 inline bool RegEx::Matches(const Source& source) const {
     30   return Match(source) >= 0;
     31 }
     32 
     33 // Match
     34 // . Matches the given string against this regular expression.
     35 // . Returns the number of characters matched.
     36 // . Returns -1 if no characters were matched (the reason for
     37 //   not returning zero is that we may have an empty regex
     38 //   which is ALWAYS successful at matching zero characters).
     39 // . REMEMBER that we only match from the start of the buffer!
     40 inline int RegEx::Match(const std::string& str) const {
     41   StringCharSource source(str.c_str(), str.size());
     42   return Match(source);
     43 }
     44 
     45 inline int RegEx::Match(const Stream& in) const {
     46   StreamCharSource source(in);
     47   return Match(source);
     48 }
     49 
     50 template <typename Source>
     51 inline bool RegEx::IsValidSource(const Source& source) const {
     52   return source;
     53 }
     54 
     55 template <>
     56 inline bool RegEx::IsValidSource<StringCharSource>(
     57     const StringCharSource& source) const {
     58   switch (m_op) {
     59     case REGEX_MATCH:
     60     case REGEX_RANGE:
     61       return source;
     62     default:
     63       return true;
     64   }
     65 }
     66 
     67 template <typename Source>
     68 inline int RegEx::Match(const Source& source) const {
     69   return IsValidSource(source) ? MatchUnchecked(source) : -1;
     70 }
     71 
     72 template <typename Source>
     73 inline int RegEx::MatchUnchecked(const Source& source) const {
     74   switch (m_op) {
     75     case REGEX_EMPTY:
     76       return MatchOpEmpty(source);
     77     case REGEX_MATCH:
     78       return MatchOpMatch(source);
     79     case REGEX_RANGE:
     80       return MatchOpRange(source);
     81     case REGEX_OR:
     82       return MatchOpOr(source);
     83     case REGEX_AND:
     84       return MatchOpAnd(source);
     85     case REGEX_NOT:
     86       return MatchOpNot(source);
     87     case REGEX_SEQ:
     88       return MatchOpSeq(source);
     89   }
     90 
     91   return -1;
     92 }
     93 
     94 //////////////////////////////////////////////////////////////////////////////
     95 // Operators
     96 // Note: the convention MatchOp*<Source> is that we can assume
     97 // IsSourceValid(source).
     98 //       So we do all our checks *before* we call these functions
     99 
    100 // EmptyOperator
    101 template <typename Source>
    102 inline int RegEx::MatchOpEmpty(const Source& source) const {
    103   return source[0] == Stream::eof() ? 0 : -1;
    104 }
    105 
    106 template <>
    107 inline int RegEx::MatchOpEmpty<StringCharSource>(
    108     const StringCharSource& source) const {
    109   return !source ? 0 : -1;  // the empty regex only is successful on the empty
    110                             // string
    111 }
    112 
    113 // MatchOperator
    114 template <typename Source>
    115 inline int RegEx::MatchOpMatch(const Source& source) const {
    116   if (source[0] != m_a)
    117     return -1;
    118   return 1;
    119 }
    120 
    121 // RangeOperator
    122 template <typename Source>
    123 inline int RegEx::MatchOpRange(const Source& source) const {
    124   if (m_a > source[0] || m_z < source[0])
    125     return -1;
    126   return 1;
    127 }
    128 
    129 // OrOperator
    130 template <typename Source>
    131 inline int RegEx::MatchOpOr(const Source& source) const {
    132   for (const RegEx& param : m_params) {
    133     int n = param.MatchUnchecked(source);
    134     if (n >= 0)
    135       return n;
    136   }
    137   return -1;
    138 }
    139 
    140 // AndOperator
    141 // Note: 'AND' is a little funny, since we may be required to match things
    142 //       of different lengths. If we find a match, we return the length of
    143 //       the FIRST entry on the list.
    144 template <typename Source>
    145 inline int RegEx::MatchOpAnd(const Source& source) const {
    146   int first = -1;
    147   for (std::size_t i = 0; i < m_params.size(); i++) {
    148     int n = m_params[i].MatchUnchecked(source);
    149     if (n == -1)
    150       return -1;
    151     if (i == 0)
    152       first = n;
    153   }
    154   return first;
    155 }
    156 
    157 // NotOperator
    158 template <typename Source>
    159 inline int RegEx::MatchOpNot(const Source& source) const {
    160   if (m_params.empty())
    161     return -1;
    162   if (m_params[0].MatchUnchecked(source) >= 0)
    163     return -1;
    164   return 1;
    165 }
    166 
    167 // SeqOperator
    168 template <typename Source>
    169 inline int RegEx::MatchOpSeq(const Source& source) const {
    170   int offset = 0;
    171   for (const RegEx& param : m_params) {
    172     int n = param.Match(source + offset);  // note Match, not
    173                                            // MatchUnchecked because we
    174                                            // need to check validity after
    175                                            // the offset
    176     if (n == -1)
    177       return -1;
    178     offset += n;
    179   }
    180 
    181   return offset;
    182 }
    183 }  // namespace YAML
    184 
    185 #endif  // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66