|
// 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 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
Stream_T::iter_type pos = stream.GetPos();
// notify of attempt to parse
Actor<Stream_T::iter_type, 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<Stream_T::iter_type, Rules_T>::OnSuccess(pos, stream.GetPos());
return true;
}
// notify of failure parsing
Actor<Stream_T::iter_type, 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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_T>& stream) {
return (match<T0>(stream) && match<T1>(stream) && match<T2>(stream));
}
};
template<typename T>
struct re_star {
// matches 0 or more times the pattern represented by T
template<typename Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_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 Elem_T>
static bool Accept(ParserInputStream<Elem_T>& stream) {
if (stream.AtEnd()) return false;
while (!match<T>(stream)) {
if (stream.AtEnd()) return false;
stream.GotoNext();
}
return true;
}
};
}
#endif // #ifndef REOPS_HPP_INCLUDED
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.