kokudas.egloos.com

나름노력파

포토로그 마이가든



Interpreter 패턴 프로그래밍(GOF 디자인패턴)

  어떤 언어에 대해 그언어의 문법을 위한 표현 수단을 정의하고, 그 표현 수단을 사용하여 해당 언어로 작성된 문장을 해성하는 해석기를 정의하는 패턴.

장점
  -  문법을 변경 시키거나 확장 시키는 것이 쉽다.
  - 클래스들의 구현형태가 서로 비슷하므로 클래스 구현이 쉽다.

단점
  - 새로운 작업을 추가하려면 각 클래스 마다 새로문 멤버함수를 정의해야 한다.(기존 클래스를 수정해야하는 문제가 발생할 수 있다.)

  정규적인 문법이 있다면 라이브러리 형태로 구현해 두고 사용하면 여러모로 편리함.

패턴마다 예제 소스를 어떻게 만들지 생각이 안 나긴 다 마찬가지지만 이번껀 책 예제 이외엔 도저히 떠오르지가 않는다.
그래서 이번엔 책 예제와 거의 똑같이 많들고 헝가리안 표기법 공부를 한다는 생각으로 작성했다.

/////////////////////////////////////////////////////////////////////////////////////
// 문자열 검색 트리
#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

 

class RegularExp

{

public:

        virtual~RegularExp(){};

        virtual bool Match( string szSrc ) = 0;

};

 

class CharacterExp : public RegularExp

{

        string m_szLiteral;

public:

        CharacterExp( const string i_str ) : m_szLiteral( i_str ){};

        bool Match( string i_szSrc )

        {

               string::size_type pos = i_szSrc.find( m_szLiteral );

               if( pos == string::npos )

                       return false;

               return true;

        }

        ~CharacterExp()        {}

};

 

class OrExp : public RegularExp

{

        RegularExp* m_pExp1;

        RegularExp* m_pExp2;

 

public:

        OrExp( RegularExp* pExp1 = NULL, RegularExp* pExp2 = NULL ) : m_pExp1( pExp1 ), m_pExp2( pExp2 ){};

        bool Match(string szSrc)

        {

               return ( m_pExp1->Match( szSrc ) ) || ( m_pExp2->Match(szSrc) );

        }

        ~OrExp()

        {

               if( m_pExp1 )

               {

                       delete m_pExp1;

                       m_pExp1 = NULL;

               }

               if( m_pExp2 )

               {

                       delete m_pExp2;

                       m_pExp2 = NULL;

               }

        }

};

 

 

class AndExp : public RegularExp

{

        RegularExp* m_pExp1;

        RegularExp* m_pExp2;

public:

        AndExp( RegularExp* pExp1, RegularExp* pExp2 ) : m_pExp1( pExp1 ), m_pExp2( pExp2 ){};

        bool Match( string i_szSrc )

        {

               return ( m_pExp1->Match(i_szSrc) ) && ( m_pExp2->Match(i_szSrc) );

        }

        ~AndExp()

        {

               if( m_pExp1 )

               {

                       delete m_pExp1;

                       m_pExp1 = NULL;

               }

               if( m_pExp2 )

               {

                       delete m_pExp2;

                       m_pExp2 = NULL;

               }

        }

};

 

RegularExp* CreateRegularExp(string i_szSearchStr)

{

        int iLen = i_szSearchStr.length();

        int iPos = i_szSearchStr.find_first_of( "(&|" );

 

        if( iPos >= ( iLen-1 ) )

        {

               return NULL;

        }

 

        if( i_szSearchStr[iPos] == '(' )

        {

               int iEndParenpos = 0;

               int iParenCount = 1;

               for (int i=iPos+1; i<iLen; i++)

               {

                       if ( i_szSearchStr[i] == '(' ) iParenCount++;

                       else if( i_szSearchStr[i] == ')' )    iParenCount--;

                       else    {}

 

                       if(iParenCount == 0)

                       {

                              int iNextPos = i_szSearchStr.find_first_of( "&|", i+1 );

                              if( iNextPos != -1 )

                              {

                                      RegularExp* pExp1 = CreateRegularExp( i_szSearchStr.substr( iPos+1, i-iPos-1 ) );

                                      RegularExp* pExp2 = CreateRegularExp( i_szSearchStr.substr( iNextPos+1, iLen-iNextPos-1 ) );

 

                                      if( i_szSearchStr[iNextPos] == '&' )

                                      {

                                             return new AndExp(pExp1, pExp2);

                                      }

                                      else

                                      {

                                             return new OrExp(pExp1, pExp2);

                                      }

                              }

                              else

                                      return CreateRegularExp( i_szSearchStr.substr( iPos + 1, i- iPos - 1 ) );

                       }

               }

               // 수식 에러

               return NULL;

        }

 

        else if( i_szSearchStr[iPos] == '&' )

        {

               RegularExp* pExp1 = CreateRegularExp( i_szSearchStr.substr( 0, iPos ) );

               RegularExp* pExp2 = CreateRegularExp( i_szSearchStr.substr( iPos+1, iLen-iPos-1 ) );

               return new AndExp(pExp1, pExp2);

        }

        else if( i_szSearchStr[iPos] == '|' )

        {

               RegularExp* pExp1 = CreateRegularExp( i_szSearchStr.substr( 0, iPos ) );

               RegularExp* pExp2 = CreateRegularExp( i_szSearchStr.substr( iPos+1, iLen-iPos-1 ) );

               return new OrExp(pExp1, pExp2);

        }

        else

        {

               return new CharacterExp( i_szSearchStr );

        }

 

        return NULL;

}

 

 

void main()

{

        RegularExp* pRegExp = CreateRegularExp("하하&(이건|테스트)");

 

        string szText = "이건 테스트 입니다. 하하";

 

        if ( pRegExp->Match( szText ) )

        {

               //성공

               int kkk = 0;

        }

}

//////////////////////////////////////////////////////////////////////////////////////////////


트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://kokudas.egloos.com/tb/355609 [도움말]

덧글

댓글 입력 영역