/*==================================================================
=  文件名  : 
=  主要功能: 
=  修改日期: 
=  作者    : shen beide
====================================================================*/

#if !defined(_LEXBASE_H)
#define _LEXBASE_H

#include "PubHeader.h"

#include "Array.h"
#include "ObArray.h"
#include "ObList.h"
#include "MemPool.h"

#define ASCII_TABLE_SIZE 256
#define MAX_LEXPARAM_ID  10

class CharSet
{
public:
    enum charset_type
    { 
        eEOF      =256,
        eLineBegin,     // 虚拟字符 ^
        eLineEnd,       // 虚拟字符 $ '\r\n'或'\n'  或buf的最后
        eWordbound,     // 虚拟字符 \b 匹配一个单词边界，也就是指单词和空格间的位置
        eNotWordbound,  // 虚拟字符 \B
        eSingleChar,
        eDot,           // . 不包含'\r\n'的所有字符
        eCharset,       // []中的字符, 只允许256个标准字符
        eNotCharset,    // 
        eCharsetStop,   // 遇到[]中的字符则终止  //###1
        eNotCharsetStop,// 
        eStringStopBefore,
        eStringStopAfter
    };

public:
    charset_type m_nCharSetMode;       
    OTSTR        m_strCharSet;     
    bool         m_bCharValSpecified;

public:
    CharSet(charset_type nCharSetMode,char* szCharSet=NULL);
   ~CharSet();

    bool inCharSet(short eChar,bool bCaseSentive=true,short eCharReverse=0);
    bool IsStringEqual(char* str,long len, bool bCaseSentive);

    charset_type GetCharSetMode()    { return m_nCharSetMode; }

    bool   Dump(OTSTR& strRet,bool bDumpState);  // DumpRule or DumpState
    static OTSTR DumpChar(short eChar,bool bInCharSet=false);

public:
    static bool isVirtualChar(short eChar);
};

class RepeatAttribute
{
public:
    enum { MAX_REPEATNUM=32000 };

    long m_nMinRepeat,m_nMaxRepeat;   // { eZeroOrMore, eRepeatN, eRepeatNM, eOneOrMore };
    bool m_bGreedMode;

public:
    RepeatAttribute(long nMinRepeat,long nMaxRepeat,bool bGreedMode);
   ~RepeatAttribute();

    bool Dump(OTSTR& strRet);
};

//////////////////////////////////////////
class LexRules;
class LexState;

class LexTransition
{
public:
    enum cond_type { CHARSET=0, SUBRULE=1, DIRECTJMP=2 };
    
    /////////////////////////////////////////
    // Condition To Next State
    cond_type        m_ConditionType;   
    void*            m_pCondition;
    RepeatAttribute* m_pRepeatAttribute;
    long             m_nReturnParamId;
    
    LexState*        m_pNextLexState;

public:
    LexTransition(LexState* pParent);
   ~LexTransition();

private:
    LexState*        m_pParentState;
};

class LexState
{
public:
    long     m_nId;
    OTSTR    m_strName;

    TObArray<LexTransition> m_TransitionList;

public:    
    LexState(long nId);
   ~LexState();

    void setName(char* szName) { m_strName=szName; }

    bool isFinalState() { return (m_TransitionList.GetSize()==0)? true:false; }
    
private:
    friend class LexRules;

    ///////////////////////////////////////////////
    bool AddTransition(CharSet*  pCharSet,     RepeatAttribute* pRepeatAttribute, LexState* pNextState);
    bool AddTransition(LexState* pSubRuleEntry,RepeatAttribute* pRepeatAttribute, LexState* pNextState, int nReturnParamId=-1);
    bool AddTransition(LexState* pNextState);
};

//////////////////////////////////////
#ifdef _DLL_PROJECT
class CLASS_EXPORT MatchNode
#else
class MatchNode
#endif
{
public:
    LexState*       m_pCurState;
    LexTransition*  m_pCurTransiton;   
    long            m_nCurRepeatN;
    long            m_nBeginLocat;
    long            m_nParam;       // used for internal data
    
public:
    MatchNode() { m_nBeginLocat=-1; m_nParam=0; }
   ~MatchNode() {};

    void operator=(const MatchNode& right);
};

#ifdef _DLL_PROJECT
class CLASS_EXPORT MatchPattern
#else
class MatchPattern
#endif
{
public:
    enum { MAX_MATCH_LEVEL=10 };
    enum { PATTERN_FAIL=-1, PATTERN_CONTINUE=0, PATTERN_ACCEPTED=1 };  // status
    
    int       m_status;
    
    long      m_nRuleId;
    Location  m_LocatFrom;      // 0-Based index of the starting position
    long      m_nLen;
    
public:
    MatchPattern(MatchPattern& Pattern);
    MatchPattern();
    virtual ~MatchPattern();
    
    void OnCreate();
    void OnDestroy();
    void Clone(MatchPattern& Pattern);
    
    bool Push(MatchNode& Node);
    bool Push(LexState* pState,LexTransition* pTransiton,long nRepeatN, long nCurLocat, long nParam=0);
    bool Pop (MatchNode* pNode=NULL);
    bool GetTop(MatchNode& Node);
    bool isEmpty();
    int  GetStackSize() { return m_nStackSize; }
    void ClearStack();
    
    void setRuleId(long Id) { m_nRuleId=Id; }
    
    void Dump(OTSTR& str);

    bool setParamLocat(long ParamId,long nbegin, long nLen);  // nLen==-1 表示len还不确定
    bool setParamLocat_len  (long ParamId,long  nLen);
    bool getParamLocat_begin(long ParamId,long& nbegin);

    bool AddParamLocat(long nbegin, long nLen);  // 无用户定义param时,系统自动分析生成
    
public:    
    long      m_nPatternId;
    
private:
    int       m_nStackSize;
    MatchNode m_MatchStack[MAX_MATCH_LEVEL+1];   

    long      m_ParamLocatList[MAX_LEXPARAM_ID+1][2];   // [2] begin,len   initial: -1,0

    friend class CLex;
};



#endif
