рдПрдХ рдмрд╛рд░, рдЬрдм рдШрд╛рд╕ рд╣рд░рд┐рдпрд╛рд▓реА рдереА рдФрд░ рдкреЗрдбрд╝ рдКрдВрдЪреЗ рдереЗ, Xenocephal рдирд╛рдо рдХрд╛ рдПрдХ рдЯреНрд░реЛрд▓ рд░рд╣рддрд╛ рдерд╛ред рд╡рд╣, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд░рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ
рдордВрдЪ рдкрд░ рдЙрд╕рд╕реЗ рдорд┐рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рдерд╛, рдЙрд╕ рд╕рдордп рдореИрдВ рдмреБрджреНрдзрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рдерд╛ред рдореБрдЭреЗ рд╡рд╣ рд╡рд┐рд╖рдп рднреА рдпрд╛рдж рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдмрд╛рддрдЪреАрдд рд╣реБрдИ рдереА, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╕рд╛рд░ рдпрд╣ рдерд╛ рдХрд┐ Xenocephal рдиреЗ рд╕рднреА рдХреЛ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдХрд┐ рд▓рд┐рд╕реНрдк (рдЕрдкрдиреЗ рдореИрдХреНрд░реЛрдВ рдХреЗ рд╕рд╛рде) рд╕рдм рдХреБрдЫ рдХрд╛ рдкреНрд░рдореБрдЦ рдерд╛, рдФрд░ C ++, рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде, рдмрд╛рдПрдВ рд╣рд╛рде рдХрд╛ рдПрдХ рджреБрд╕реНрд╕рд╛рд╣рд╕рд┐рдХ рд╕рд╛рджреГрд╢реНрдп рдерд╛ред рдпрд╣ рднреА рддрд░реНрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рд╣рд╛рд░реНрдб-рдкреНрд░реЗрд╕рд┐рдб
рдлреИрдХреНрдЯрд░рд┐рдпрд▓ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЗрд╕рдореЗрдВ рдХреБрдЫ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рдерд╛ред
рдореИрдВ, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдХреЛрдИ рдЖрдкрддреНрддрд┐ рдирд╣реАрдВ рдереА рдХрд┐ рд▓рд┐рд╕реНрдк рдореИрдХреНрд░реЛрдЬрд╝ рдирд┐рд╖реЗрдзрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╢рд╛рдВрдд рдереЗ рдФрд░ рдЙрд╕ рд╕рдордп, рдореБрдЭреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рдерд╛, рд▓реЗрдХрд┐рди рд╕реА ++ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдФрд░ рдлреИрдХреНрдЯрд░рд┐рдпрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдореЗрд░реЗ рдирд╛рдЬреБрдХ рдорд╕реНрддрд┐рд╖реНрдХ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдШреБрд╕ рдЧрдпрд╛ рдФрд░ рдореБрдЭреЗ рдЕрдВрджрд░ рд╕реЗ рдмрд╛рд╣рд░ рдкреАрдбрд╝рд╛ рджреЗрддрд╛ рд░рд╣рд╛ред рдФрд░ рдПрдХ рднрдпрд╛рдирдХ рджрд┐рди, рдореИрдВрдиреЗ рд╕реЛрдЪрд╛: "рдХреНрдпрд╛ рдирд░рдХ ??? рдЪрд▓реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИ! тАЭ
рдбреНрд░реИрдЧрди рдмреБрдХ рдкреНрд░реЗрд░рдгрд╛ рдХрд╛ рдПрдХ рдЕрдиреНрдп рд╕реНрд░реЛрдд рдерд╛ред рдХрд╛рд░реНрдп рдЬрд▓реНрджреА рдорд┐рд▓ рдЧрдпрд╛ рдерд╛ред рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ Nondeterministic State Machine (
NFA ) рдХреЛ рдПрдХ рдирд┐рд░реНрдзрд╛рд░рдХ рд░рд╛рдЬреНрдп рдорд╢реАрди (
DFA ) рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо C ++ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдЕрд▓реЗрдХреНрдЬреЗрдВрдбреНрд░реЗрд╕реНрдХреБ рдХреЗ рдЕрд╡рд┐рд╡реЗрдХреА
рдХрд╛рд░реНрдп рдиреЗ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рджреНрд░рд╡реНрдпрдорд╛рди рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА ...
рдореИрдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрджрд┐рдо рд▓реЛрдЧреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реБрдЖред рдореБрдЭреЗ рдХрд┐рд╕реА рддрд░рд╣ рдЧреНрд░рд╛рдл рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА:
template <class T, int Src, int Dst, char Chr = 0> struct Edge { enum { Source = Src, Dest = Dst, Char = Chr }; typedef T Next; static void Dump(void) {printf("%3d -%c-> %3d\n",Src,Chr,Dst);T::Dump();} };
рдЧреНрд░рд╛рдл рдХрд╛ рдЖрд░реНрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ (Src) рдФрд░ рдЕрдВрддрд┐рдо (Dst) рдХреЛрдиреЗ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЗрд╕реЗ рдкреНрд░рддреАрдХ (Chr) рджреНрд╡рд╛рд░рд╛ рдирд╛рдо рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдкрд╕реНрдХреВрд▓ (рдкрд░рд┐рд╡рд░реНрддрди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдпреБрдХреНрдд), рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдПрдХ рдЕрд╢рдХреНрдд рдЪрд░рд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИрдВред рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЕрдЧрд▓рд╛ рдкреНрд░рдХрд╛рд░ рдЗрд╕реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ред рдЗрд╕ рд╕реВрдЪреА рдореЗрдВ рдПрдХ рдЪрд╛рдк рдЬреЛрдбрд╝рдирд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреБрдирд░рд╛рд╡рд░реНрддреА рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:
struct NullType {static void Dump(void) {printf("\n");}}; template <int S, int D, int C, class T, class R> struct AddEdge; template <int S, int D, int C, class R> struct AddEdge<S,D,C,NullType,R> { typedef typename Edge<R,S,D,C> Result; }; template <int S, int D, int C, class T, class R> struct AddEdge<S,D,C,Edge<T,S,D,C>,R> { typedef typename AddEdge<S,D,C,T,R>::Result Result; }; template <int S, int D, int C, int s, int d, int c, class T, class R> struct AddEdge<S,D,C,Edge<T,s,d,c>,R> { typedef typename AddEdge<S,D,C,T,Edge<R,s,d,c> >::Result Result; };
рдЗрд╕реА рддрд░рд╣, рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╡рд┐рд▓рдп рдХрд╛ рдЖрдпреЛрдЬрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдмрддрдЦ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдХреЛрдИ рднреА, рдФрд░ рди рдХреЗрд╡рд▓ рдЙрди рдЬреЛ рдЧреНрд░рд╛рдлрд╝ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ)
рд╕рдВрд▓рдЧреНрди template <class A, class B> struct Append; template <class T> struct Append<NullType,T> { typedef T Result; }; template <int S, int D, int C, class T, class B> struct Append<Edge<T,S,D,C>,B> { typedef typename Append<T,Edge<B,S,D,C> >::Result Result; };
рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ template <class A, class B> struct Join; template <class B> struct Join<NullType,B> { typedef B Result; }; template <int N, class T, class B> struct Join<Set<N,T>,B> { typedef typename Join<T,typename AddSet<N,B,NullType>::Result>::Result Result; }; template <int S, int D, int C, class T, class B> struct Join<Edge<T,S,D,C>,B> { typedef typename Join<T,typename AddEdge<S,D,C,B,NullType>::Result>::Result Result; }; template <int N, class S, class T, class B> struct Join<StateList<N,S,T>,B> { typedef typename Join<T,typename AddState<N,S,B,NullType>::Result>::Result Result; }; template <int Src, int Dst, int a, class S, class T, class B> struct Join<StateListEx<Src,Dst,a,S,T>,B> { typedef typename Join<T,typename AddState<Dst,S,B,NullType>::Result>::Result Result; };
... рдФрд░ рд╕реВрдЪреА рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рдордирдорд╛рдирд╛ рдлрд╝рд╛рдЗрдЯрд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛:
рдирдХреНрд╢рд╛ template <class T, int V, class R, template <int,int> class F> struct Map; template <int V, class R, template <int,int> class F> struct Map<NullType,V,R,F> { typedef R Result; }; template <int N, class T, int V, class R, template <int,int> class F> struct Map<Set<N,T>,V,R,F> { typedef typename Map<T,V,Set<F<N,V>::Result,R>,F>::Result Result; }; template <class T, int S, int D, int C, int V, class R, template <int,int> class F> struct Map<Edge<T,S,D,C>,V,R,F> { typedef typename Map<T,V,Edge<R,F<S,V>::Result,F<D,V>::Result,C>,F>::Result Result; };
рдЕрдм, рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдирд╕реАрдП рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдЗрд╕ рдирд┐рд░реНрдорд╛рдг рдХреА рдмрд╣реБрдд рд╣реА рддрдХрдиреАрдХ рдХреЛ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд
рдкреБрд╕реНрддрдХ рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕ рддрдереНрдп рдХреЛ рдЙрдмрд╛рд▓рддрд╛ рд╣реИ рдХрд┐ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рдирд┐рд░реНрдорд╛рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдЕрдирд╛рдо рдЖрд░реНрдХ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВред
рдПрдХ рдирд╛рдорд╛рдВрдХрд┐рдд рдЖрд░реНрдХ рдкреНрд░рд╛рдердорд┐рдХ рд░реВрдк рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:
рд╕реА template <char Chr> struct C { typedef typename Edge<NullType,0,1,Chr> Result; enum {Count = 2}; };
рд╢реБрд░реБрдЖрддреА рдФрд░ рдЕрдВрдд рд╡рд╛рд▓реЗ рд╕рд┐рд░реЗ рдХреНрд░рдорд╢рдГ 0 рдФрд░ 1 рдЕрдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
рджреЛ рдЧреНрд░рд╛рдл рд╡реИрдХрд▓реНрдкрд┐рдХ / A | B / рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдЬреБрдбрд╝реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
рдбреА template <int X, int N> struct Add { enum { Result = X+N }; }; template <class A, class B> struct DImpl { private: typedef typename Append< typename Map<typename A::Result, 2, NullType, Add>::Result, typename Map<typename B::Result, A::Count+2, NullType, Add>::Result >::Result N0; typedef typename Edge<N0,0,2> N1; typedef typename Edge<N1,0,A::Count+2> N2; typedef typename Edge<N2,3,1> N3; public: typedef typename Edge<N3,A::Count+3,1> Result; enum {Count = A::Count+B::Count+2}; }; template <class T1, class T2, class T3 = NullType, class T4 = NullType, class T5 = NullType> struct D: public DImpl<T1, D<T2,T3,T4,T5> > {}; template <class T1, class T2> struct D<T1,T2,NullType,NullType,NullType>: public DImpl<T1,T2> {};
рдпрд╣рд╛рдВ, рд╣рдо рджреЛ рдЗрдирдкреБрдЯ рдЧреНрд░рд╛рдл (рдП рдФрд░ рдмреА) рдХреЛ рдорд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ (рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЙрдирдХреЗ рдХреЛрдиреЗ рдХрд╛ рдирд╛рдо рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдо рдКрдкрд░ рджрд┐рдП рдЧрдП рдЖрд░реЗрдЦ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЙрдиреНрд╣реЗрдВ рдЕрдирд╛рдо рддреАрд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рд╢реБрд░реБрдЖрддреА рдФрд░ рдЕрдВрдд рд╡рд╛рд▓реЗ рд╕рд┐рд░реЗ рдЕрднреА рднреА рдХреНрд░рдорд╢рдГ 0 рдФрд░ 1 рдХреЗ рд╕реВрдЪрдХ рд╣реИрдВред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд / AB / рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛ рдЧрдпрд╛ рд╣реИ:
рдП template <int X, int N> struct ConvA { enum { Result = (X==1) ? (X+N-1) : X }; }; template <int X, int N> struct ConvB { enum { Result = (X==1) ? 1 : (X+N) }; }; template <class A, class B> struct EImpl { private: typedef typename Map<typename A::Result, A::Count, NullType, ConvA>::Result A1; typedef typename Map<typename B::Result, A::Count, NullType, ConvB>::Result B1; public: typedef typename Append<A1,B1>::Result Result; enum {Count = A::Count+B::Count}; }; template <class T1, class T2, class T3 = NullType, class T4 = NullType, class T5 = NullType> struct E: public EImpl<T1, E<T2,T3,T4,T5> > {}; template <class T1, class T2> struct E<T1,T2,NullType,NullType,NullType>: public EImpl<T1,T2> {};
рдпрд╣рд╛рдВ, рдЕрддрд┐рд░рд┐рдХреНрдд рдЖрд░реНрдХреНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЧреНрд░рд╛рдл рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╢реАрд░реНрд╖ (рдмреА рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдФрд░ рдП рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо) рджреНрд╡рд╛рд░рд╛ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВред
рдХреНрд╡рд╛рдВрдЯрд┐рдлрд╛рдпрд░ / рдЯреА * / рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдмрд╕реЗ рдХрдард┐рди рдирд┐рдХрд▓рд╛:
рдХреНрдпреВ template <class T, int Min = 0, int Max = 0> struct Q { Q() {STATIC_ASSERT(Min<=Max, Q_Spec);} private: typedef typename Map<typename T::Result, T::Count, NullType, ConvA>::Result A1; typedef typename Map<typename Q<T,Min,Max-1>::Result,T::Count,NullType,ConvB>::Result B1; public: typedef typename Edge<typename Append<A1,B1>::Result,0,T::Count> Result; enum {Count = T::Count+Q<T,Min,Max-1>::Count}; }; template <class T, int N> struct Q<T,N,N> { private: typedef typename Map<typename T::Result, T::Count, NullType, ConvA>::Result A1; typedef typename Map<typename Q<T,N-1,N-1>::Result, T::Count, NullType, ConvB>::Result B1; public: typedef typename Append<A1,B1>::Result Result; enum {Count = T::Count+Q<T,N-1,N-1>::Count}; };
рдЪреВрдВрдХрд┐ рдХреНрд╡рд╛рдВрдЯрд┐рдлрд╛рдпрд░ / T * / рдФрд░ / T + / рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдУрд╡рд░рд▓реЛрдбреЗрдб рдереЗ:
рдХреНрдпреВ template <class T> struct Q<T,1,1>: public T {}; template <class T> struct Q<T,0,0> { private: typedef typename Edge<typename Map<typename T::Result,2,NullType,Add>::Result,0,2> N0; typedef typename Edge<N0,3,1> N1; typedef typename Edge<N1,3,2> N2; public: typedef typename Edge<N2,0,1> Result; enum {Count = T::Count+2}; }; template <class T> struct Q<T,1,0> { public: typedef typename Edge<typename T::Result,1,0> Result; enum {Count = T::Count}; }; template <class T> struct Q<T,0,1> { public: typedef typename Edge<typename T::Result,0,1> Result; enum {Count = T::Count}; };
рдЕрдм, рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ / (aред B) * abb / рдкреБрд╕реНрддрдХ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдПрдХ NFA рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдерд╛:
typedef E< Q< D< C<'a'>, C<'b'> > >, C<'a'>, C<'b'>, C<'b'> >::Result G;
рдпрд╣ рдЗрд╕реЗ рдбреАрдХреЗрдП рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ:
DFA enum CONSTS { MAX_FIN_STATE = 9 }; template <class Graph> class DFAImpl; template <class T, int Src, int Dst, char Chr> class DFAImpl<Edge<T,Src,Dst,Chr> >: public DFAImpl<typename T> { public: typedef typename DFAImpl<typename T>::ResultType ResultType; ResultType Parse(char C) { if ((State==Src)&&(C==Chr)) { State = Dst; if (State<MAX_FIN_STATE) { State = 0; return rtSucceed; } return rtNotCompleted; } return DFAImpl<typename T>::Parse(C); } void Dump(void) {T::Dump();} }; template <> class DFAImpl<NullType> { public: DFAImpl(): State(0) {} enum ResultType { rtNotCompleted = 0, rtSucceed = 1, rtFailed = 2 }; ResultType Parse(char C) { State = 0; return rtFailed; } protected: int State; };
рдореИрдВ рдЗрд╕ рдХреЛрдб рдХреЛ рдбрд┐рдмрдЧ рдХрд░рдиреЗ рд╕реЗ рдЬреБрдбрд╝реЗ рд╕рднреА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ (рдЬрд┐рд╕рдореЗрдВ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ рдХрд┐рд▓реЛрдореАрдЯрд░ рд▓рдВрдмреА рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреА рд▓рд╛рдЧрдд рд╣реИ), рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдиреЛрдЯ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдлреНрд░рдВрдЯ-рдПрдВрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдиреЗ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдП рдЧрдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдСрдкреНтАНрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред
рдЕрдм рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ:
typedef E< Q< D< C<'a'>, C<'b'> > >, C<'a'>, C<'b'>, C<'b'> >::Result G; typedef Convert<G,NullType>::Result R; R::Dump();
... рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдпрд╣ рд╣реИ:
1 -a-> 10 1 -b-> 11 13 -a-> 10 13 -b-> 1 10 -a-> 10 10 -b-> 13 11 -a-> 10 11 -b-> 11 0 -a-> 10 0 -b-> 11
рд╡рд╛рдВрдЫрд┐рдд рдХреЙрд▓рдо DKA рдХреЗ рдЕрдиреБрд░реВрдк:
рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╕реНрд░реЛрдд
GitHub рдкрд░ рдЕрдкрд▓реЛрдб рдХрд┐рдП рдЧрдП рд╣реИрдВред