regeximpl.h
Go to the documentation of this file.
00001 #ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00002 #define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00003 
00004 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
00005 #pragma once
00006 #endif
00007 
00008 
00009 #include "stream.h"
00010 #include "stringsource.h"
00011 #include "streamcharsource.h"
00012 
00013 namespace YAML_PM
00014 {
00015         // query matches
00016         inline bool RegEx::Matches(char ch) const {
00017                 std::string str;
00018                 str += ch;
00019                 return Matches(str);
00020         }
00021         
00022         inline bool RegEx::Matches(const std::string& str) const {
00023                 return Match(str) >= 0;
00024         }
00025         
00026         inline bool RegEx::Matches(const Stream& in) const {
00027                 return Match(in) >= 0;
00028         }
00029 
00030         template <typename Source>
00031         inline bool RegEx::Matches(const Source& source) const {
00032                 return Match(source) >= 0;
00033         }
00034 
00035         // Match
00036         // . Matches the given string against this regular expression.
00037         // . Returns the number of characters matched.
00038         // . Returns -1 if no characters were matched (the reason for
00039         //   not returning zero is that we may have an empty regex
00040         //   which is ALWAYS successful at matching zero characters).
00041         // . REMEMBER that we only match from the start of the buffer!  
00042         inline int RegEx::Match(const std::string& str) const
00043         {
00044                 StringCharSource source(str.c_str(), str.size());
00045                 return Match(source);
00046         }
00047         
00048         inline int RegEx::Match(const Stream& in) const
00049         {
00050                 StreamCharSource source(in);
00051                 return Match(source);
00052         }
00053 
00054         template <typename Source>
00055         inline bool RegEx::IsValidSource(const Source& source) const
00056         {
00057                 return source;
00058         }
00059         
00060         template<>
00061         inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const
00062         {
00063                 switch(m_op) {
00064                         case REGEX_MATCH:
00065                         case REGEX_RANGE:
00066                                 return source;
00067                         default:
00068                                 return true;
00069                 }
00070         }
00071 
00072         template <typename Source>
00073         inline int RegEx::Match(const Source& source) const
00074         {
00075                 return IsValidSource(source) ? MatchUnchecked(source) : -1;
00076         }
00077         
00078         template <typename Source>
00079         inline int RegEx::MatchUnchecked(const Source& source) const
00080         {
00081                 switch(m_op) {
00082                         case REGEX_EMPTY:
00083                                 return MatchOpEmpty(source);
00084                         case REGEX_MATCH:
00085                                 return MatchOpMatch(source);
00086                         case REGEX_RANGE:
00087                                 return MatchOpRange(source);
00088                         case REGEX_OR:
00089                                 return MatchOpOr(source);
00090                         case REGEX_AND:
00091                                 return MatchOpAnd(source);
00092                         case REGEX_NOT:
00093                                 return MatchOpNot(source);
00094                         case REGEX_SEQ:
00095                                 return MatchOpSeq(source);
00096                 }
00097                 
00098                 return -1;
00099         }
00100 
00102         // Operators
00103         // Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source).
00104         //       So we do all our checks *before* we call these functions
00105         
00106         // EmptyOperator
00107         template <typename Source>
00108         inline int RegEx::MatchOpEmpty(const Source& source) const {
00109                 return source[0] == Stream::eof() ? 0 : -1;
00110         }
00111         
00112         template <>
00113         inline int RegEx::MatchOpEmpty<StringCharSource>(const StringCharSource& source) const {
00114                 return !source ? 0 : -1;  // the empty regex only is successful on the empty string
00115         }
00116 
00117         // MatchOperator
00118         template <typename Source>
00119         inline int RegEx::MatchOpMatch(const Source& source) const {
00120                 if(source[0] != m_a)
00121                         return -1;
00122                 return 1;
00123         }
00124         
00125         // RangeOperator
00126         template <typename Source>
00127         inline int RegEx::MatchOpRange(const Source& source) const {
00128                 if(m_a > source[0] || m_z < source[0])
00129                         return -1;
00130                 return 1;
00131         }
00132         
00133         // OrOperator
00134         template <typename Source>
00135         inline int RegEx::MatchOpOr(const Source& source) const {
00136                 for(std::size_t i=0;i<m_params.size();i++) {
00137                         int n = m_params[i].MatchUnchecked(source);
00138                         if(n >= 0)
00139                                 return n;
00140                 }
00141                 return -1;
00142         }
00143         
00144         // AndOperator
00145         // Note: 'AND' is a little funny, since we may be required to match things
00146         //       of different lengths. If we find a match, we return the length of
00147         //       the FIRST entry on the list.
00148         template <typename Source>
00149         inline int RegEx::MatchOpAnd(const Source& source) const {
00150                 int first = -1;
00151                 for(std::size_t i=0;i<m_params.size();i++) {
00152                         int n = m_params[i].MatchUnchecked(source);
00153                         if(n == -1)
00154                                 return -1;
00155                         if(i == 0)
00156                                 first = n;
00157                 }
00158                 return first;
00159         }
00160         
00161         // NotOperator
00162         template <typename Source>
00163         inline int RegEx::MatchOpNot(const Source& source) const {
00164                 if(m_params.empty())
00165                         return -1;
00166                 if(m_params[0].MatchUnchecked(source) >= 0)
00167                         return -1;
00168                 return 1;
00169         }
00170         
00171         // SeqOperator
00172         template <typename Source>
00173         inline int RegEx::MatchOpSeq(const Source& source) const {
00174                 int offset = 0;
00175                 for(std::size_t i=0;i<m_params.size();i++) {
00176                         int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset
00177                         if(n == -1)
00178                                 return -1;
00179                         offset += n;
00180                 }
00181                 
00182                 return offset;
00183         }
00184 }
00185 
00186 #endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66


upstream_src
Author(s):
autogenerated on Mon Oct 6 2014 10:27:42