📄 re_ops.hpp
字号:
// released into the public domain
// by Christopher Diggins 2004
// http://www.cdiggins.com
#ifndef REOPS_HPP_INCLUDED
#define REOPS_HPP_INCLUDED
#include "parser_input_stream.hpp"
namespace yard {
// in order execute semantic actions, this class simply needs to be specialized by the user
// for the Rules_T type
template < typename Iter_T, typename Rules_T >
struct Actor {
static void OnBefore(Iter_T pos) { }
static void OnSuccess(Iter_T begin, Iter_T end) { }
static void OnFailure(Iter_T pos) { }
};
//This template function can be compile well but run badly in vc6.0 .It reveals the bugs that vc6.0 does not
//overload normal function depending on exlicit template argument chinahardbone@yahoo.com
#if 0
// this function attempts to match the pattern, but failing it backs the stream up to before failing
template < typename Rules_T, typename Stream_T >
bool match(Stream_T & stream) {
// store stream position
// typename Stream_T::iter_type pos = stream.GetPos();
const char * pos = stream.GetPos();
// notify of attempt to parse
//Actor<typename Stream_T::iter_type, Rules_T>::OnBefore(pos);
Actor < const char *, Rules_T >::OnBefore(pos);
// try to match
if (Rules_T::Accept(stream)) {
// if successful trigger action ( this either goes to the default implementation at semantic_actions.hpp
// or it calls a user defined actor ( this is done through specialization )
// Actor<typename Stream_T::iter_type, Rules_T>::OnSuccess(pos, stream.GetPos());
Actor < const char *, Rules_T >::OnSuccess(pos, stream.GetPos());
return true;
}
// notify of failure parsing
// Actor<typename Stream_T::iter_type, Rules_T>::OnFailure(stream.GetPos());
Actor < const char *, Rules_T >::OnFailure(stream.GetPos());
// restore stream position
stream.SetPos(pos);
return false;
};
#endif
//The best way to retain the original interface of match template function is changing match as a template class
template < typename Rules_T >
struct match {
template < typename Stream_T >
bool operator() (Stream_T & stream) {
//re check chinahardbone@yahoo.com 2005/02/16
if (stream.AtEnd()) return false;
// store stream position
// typename Stream_T::iter_type pos = stream.GetPos();
const char * pos = stream.GetPos();
// notify of attempt to parse
//Actor<typename Stream_T::iter_type, Rules_T>::OnBefore(pos);
Actor < const char *, Rules_T >::OnBefore(pos);
// try to match
if (Rules_T::Accept(stream)) {
// if successful trigger action ( this either goes to the default implementation at semantic_actions.hpp
// or it calls a user defined actor ( this is done through specialization )
// Actor<typename Stream_T::iter_type, Rules_T>::OnSuccess(pos, stream.GetPos());
Actor < const char *, Rules_T >::OnSuccess(pos, stream.GetPos());
return true;
}
// notify of failure parsing
// Actor<typename Stream_T::iter_type, Rules_T>::OnFailure(stream.GetPos());
Actor < const char *, Rules_T >::OnFailure(stream.GetPos());
// restore stream position
stream.SetPos(pos);
return false;
}
};
template < typename T0, typename T1 >
struct re_or {
// attempts to match T0, failing that it attempt to match T1
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return (match < T0 > () (stream) || match < T1 > () (stream));
}
};
template < typename T0, typename T1, typename T2 >
struct re_or3 {
// attempts to match T0, failing that it attempt to match T1
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return (match < T0 > () (stream) || match < T1 > () (stream) || match < T2 > () (stream));
}
};
template < typename T0, typename T1 >
struct re_and {
// matches T0 then T1
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return (match < T0 > () (stream) && match < T1 > () (stream));
}
};
template < typename T0, typename T1, typename T2 >
struct re_and3 {
// matches T0 then T1
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return (match < T0 > () (stream) && match < T1 > () (stream) && match < T2 > () (stream));
}
};
template < typename T0, typename T1, typename T2, typename T3 >
struct re_and4 {
// matches T0 then T1
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return (match < T0 > () (stream) && match < T1 > () (stream) && match < T2 > () (stream) &&
match < T3 > () (stream));
}
};
template < typename T >
struct re_star {
// matches 0 or more times the pattern represented by T
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
while (match < T > () (stream)) { }
return true;
}
};
template < typename T >
struct re_plus {
// matches 1 or more times the pattern represented by T
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
if (match < T > () (stream)) {
while (match < T > () (stream)) { }
return true;
}
else {
return false;
}
}
};
template < typename T >
struct re_opt {
// matches 0 or 1 times the pattern represented by T
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
match < T > () (stream);
return true;
}
};
template < typename T, unsigned int N >
struct re_repeat {
// matches exactly N times the pattern represented by T
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
for (int i = 0; i < N; ++i) {
if (!match < T > () (stream)) {
return false;
}
}
return true;
}
};
template < typename T >
struct re_until {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
if (stream.AtEnd()) return false;
while (!match < T > () (stream)) {
if (stream.AtEnd()) return false;
stream.GotoNext();
}
return true;
}
};
/**
* The class re_not<typename T> emulate the regular expression operator ^. The accept function should always return true.
* IF NOT THEN GONEXT, RETURNT TRUE.
*/
template < typename T >
struct re_not {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return !match < T > () (stream);
}
};
/** Exclusive or (XOR) */
template < typename T0, typename T1 >
struct re_XOR {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
if (stream.AtEnd()) return true;
bool a, b;
a = match < T0 > () (stream);
b = match < T1 > () (stream);
return (a != b);
}
};
template < typename TRule >
struct Control_Probe {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
Stream_T::iter_type itbegin = stream.GetPos();
bool ret;
ret = match < TRule > () (stream);
stream.SetPos(itbegin);
return ret;
}
};
template < int number >
struct Control_GoTo {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
Stream_T::iter_type itbegin = stream.GetPos();
stream.SetPos(itbegin + number);
return true;
}
};
/** LeftIndenty and RightIndenty > 0 if the renge in the behind of current position */
template < typename Rules_T, int LeftIndenty, int RightIndenty >
struct Control_RangeMatch {
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
//adjust the indenty position
Stream_T::iter_type beginPos;
int leftDiff;
Stream_T::iter_type endPos;
int rightDiff;
leftDiff = (stream.GetPos() - stream.getBeginPos());
rightDiff = (stream.getEndPos() - stream.GetPos());
beginPos = stream.GetPos() + ((leftDiff < 0) ? leftDiff : LeftIndenty);
endPos = stream.GetPos() + ((rightDiff < 0) ? rightDiff : RightIndenty);
ParserInputStream < char > input(beginPos, endPos);
return Rules_T::Accept(input);
}
};
/** Nest rule */
template < typename T0, typename T1 >
class re_NestRule {
public:
template < typename Stream_T >
static bool Accept(Stream_T & stream) {
return MatchHelp::Accept(stream);
}
private:
struct MatchHelp;
/** match ... */
struct Help1 : public re_until < re_or < Control_Probe < T0 >, Control_Probe < T1 > > > { };
/** match ...[...]... */
struct Help2 : public re_and3 < //
Help1, MatchHelp, Help1 > { };
struct MatchHelp : public re_and3 < T0, re_star < Help2 >, re_until < T1 > > { };
};
}
#endif // #ifndef REOPS_HPP_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -