#ifndef __ZGL_LANGUAGE__
#define __ZGL_LANGUAGE__

#include <sys/types.h>
// #include <sys/mman.h>
#include <sys/stat.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
#include <iconv.h>
#include <errno.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>

using namespace std;

#define IF_PRINT                 0

#define MAX_NAME_SZ              128
#define MAX_STR_SZ               1024
#define RES_NODE_SIZE            16384   // 16k

#define SUCCESS_TEXT_PATH_NUM    2021    // 保存Tree，Line分支
#define FAIL_TEXT_PATH_NUM       2021

#define TYPE_ANY       1
#define TYPE_B         2
#define TYPE_T         3
#define TYPE_N         4
#define TYPE_BLANK     5
#define TYPE_CONT      6
#define TYPE_PATH      7
#define TYPE_EXPR      8
#define TYPE_STR       9

// 缩进解析类型:
#define INDENT_NULL                 0  // 解析无缩进，转换无缩进
#define INDENT_COMPILER             1  // 解析有缩进，转换无缩进
#define INDENT_TRANSLATOR           2  // 解析无缩进，转换有缩进
#define INDENT_COMPILER_TRANSLATOR  3  // 解析有缩进，转换有缩进

// 与上一行缩进相比
#define CMP_INDENT_SAME       0   // 与上一行缩进相比 相同
#define CMP_INDENT_ADD        1   // 与上一行缩进相比 增加
#define CMP_INDENT_SUB        2   // 与上一行缩进相比 减少
// #define CMP_INDENT_BLANK      3   // 空行 
#define CMP_INDENT_ERROR      4   // 与上一行缩进相比 错误

// TreeCplLevel/TreeTranLevel 属性 iAttrFlag
// Cpl 和 Tran 共用属性
#define ATTR_STRING                     0b10000000000000000000000000000000   // 一整段字符串进行匹配，不会自动分割单词匹配，Cpl部分配置STRING用途不大
// Cpl 专用属性
#define ATTR_SKIP_INDENT                0b00000000000000000000000000000001   // 忽略缩进
#define ATTR_CAN_SKIP                   0b00000000000000000000000000000010   // 节点是否可不解析
#define ATTR_NEXT_LINE                  0b00000000000000000000000000000100   // 
#define ATTR_NEXT_LINES                 0b00000000000000000000000000001000   // 
#define ATTR_NOT_EXPR_END               0b00000000000000000000000000010000   // 此节点不作为表达式结束符
#define ATTR_CONT_MATCH_RULE            0b00000000000000000000000000100000   // 常量字符串匹配规则，先按STR规则提取字符串，再比较常量，避免出现匹配成功一个单词前几位的情况
// Tran 专用属性
#define ATTR_EXPR                       0b00000000000000000000000000000001   // 表达式
#define ATTR_IF_SOME_WITH_UP            0b00000000000000000000000000000010   // 字段值同上行
#define ATTR_IF_NOT_SOME_WITH_UP        0b00000000000000000000000000000100   // 字段值不同上行
#define ATTR_IF_SOME_WITH_DOWN          0b00000000000000000000000000001000   // 字段值同下行
#define ATTR_IF_NOT_SOME_WITH_DOWN      0b00000000000000000000000000010000   // 字段值不同下行
#define ATTR_HIDE                       0b00000000000000000000000000100000   // 隐藏输出打印
#define ATTR_SKIP_C_EXPR                0b00000000000000000000000001000000   // 忽略表达式，不执行

// 注释类型
#define TYPE_COMMENT_1_LINE_START          1         // 独立单行注释
#define TYPE_COMMENT_1_LINE_END            2         // 行尾单行注释
#define TYPE_COMMENT_N_LINE_START          3         // 独立多行注释
#define TYPE_COMMENT_N_LINE_END            4         // 行尾多行注释


struct stSckHead
{
    char *before;
    char *next;
};

struct stStack
{
    unsigned int iType;
    unsigned int iLineNum;
};

struct stLogic
{
    char *pLgStr;
    void *pLgVal;
    char cType;
    char cFlg;
    unsigned int iLen;
};

struct stPoolHead
{
    char *before;
    char *next;
};

struct stString
{
    char *pStr;
    unsigned int iStrLen;

    char cFlag;
    unsigned int iNum;

    void *pp;

    struct stString *next;
};
// Like struct stString
// 表达式解析后序列化链表
#define TYPE_POINTER   1000000000
struct stExprInfo
{
    char *pStr;
    unsigned int iStrLen;  // 1、字符串长度；2、指针类型 TYPE_POINTER

    char cType;            // 节点类型
    unsigned int iLevel;   // 函数嵌套层级

    struct stExprInfo * before;
    struct stExprInfo * next;
};
// Like struct stString
// 表达式执行后结果保存链表头
struct stExprRetHead
{
    char *pName;              // 链表名称
    unsigned int iNameLen;

    char cType;           // 无用
    unsigned int iNum;    // 无用

    void * pExprRetList;

    struct stExprRetHead * next;
};
// Like struct stString
// 表达式执行后结果保存链表: key-value
struct stExprRet4KeyValue
{
    char * pKey;
    unsigned int iKeyLen;

    char c;             // 无用
    unsigned int i;     // 无用

    struct stCompileInfo * pCompileInfo;

    struct stExprRet4KeyValue * next;   // Head
};
// Like struct stString
// 表达式执行后结果保存链表: list
struct stExprRet4List
{
    struct stExprRet4List * pTail;

    unsigned int x;         // 无用
    char c;                 // 无用
    unsigned int i;         // 无用

    struct stCompileInfo * pCompileInfo;

    struct stExprRet4List * next;   // Head
};
// Like struct stString
// 解析部分，每一行的缩进信息
struct stIndent
{
    char * pStr;                // 缩进内容头
    unsigned int iStrLen;       // 缩进内容长度

    // char cFirstNodeOfOnePathFlag;    // 是否长路径头的节点：Y, N
    // char cFirstNodeOfOneTree;        // 是否树的首节点：Y, N
    char cLastNodeOfBeforeTree;        // 是否树的首节点：Y, N
    unsigned int iEtcIdnNum;         // 配置文件 |/\ 后面的缩进空格累加数

    struct stIndent * before;
    struct stIndent * next;
};

struct stStrLevel
{
    unsigned int iMinLen;
    unsigned int iMaxLen;

    bool mMap[129];  // 128个ASCII码，第129个为中文...

    struct stStrLevel *next;
};

struct stStr
{
    char *pName;
    unsigned int iNameLen;

    unsigned int iMinLen;
    unsigned int iMaxLen;

    struct stStrLevel *pstStrLevelList;
    struct stString * pNoKeyWord;

    struct stStr *next;
};

struct stLineLevel
{
    unsigned int iLineNum;             // 行号

    struct stString * pContentList;    // 操作符内容
    struct stString * pTranPartList;   // 转换语法
    unsigned int iPriority;            // __OPR__优先级, ELE行号

    struct stLineLevel *next;
};

struct stLine
{
    char *pName;
    unsigned int iNameLen;

    // char mKwEle[4];   // 0: __NAME__ , 1: __FLOAT__, 2: __INT__
    struct stLineLevel *pstStrEleList;
    struct stLineLevel *pstEleList;
    struct stLineLevel *pstContEleList;

    struct stLineLevel *pstOprList;
    struct stLineLevel *pstBefList;
    struct stLineLevel *pstAftList;

    char *pSplit;
    unsigned int iSplitLen;

    char *pSplit4Tran;
    unsigned int iSplitLen4Tran;

/*****************************************/
    // ( )
    char *pSubLeft;
    unsigned int iSubLeftLen;
    char *pSubRight;
    unsigned int iSubRightLen;
/*****************************************/

    struct stLine *next;
};

struct stTreeCplLevel
{
    char *pPathY;

    char *pOtherName;
    unsigned int iOtherNameLen;

    unsigned int iPriority;    // 解析位置优先级

    unsigned int iAttrFlag;         // 属性标识
    struct stExprInfo * pAttrExpr;  // 属性表达式
	struct stStr * pStr4MatchRule;  // 用户检查常量的STR匹配规则
	
	// 用户检查常量的STR匹配规则
	// char *pAttr4StrMatchRule;
	// unsigned int iAttr4StrMatchRuleLen;

    char cSplitFlag;    // | / \ or +

    char *pKeyword;
    unsigned int iKeywordLen;

    char cType;

    unsigned int iLineNum;

    unsigned int iIndent;  // 缩进

    struct stTreeCplLevel * next;
};

struct stTreeTranLevel
{
    bool isFirstNodeOfNewTran;

    char *pPathY;

    char *pOtherName;
    unsigned int iOtherNameLen;
    char cOtherNameType;             // 正常:0  by():b  byv():v

    unsigned int iAttrFlag;          // @ 属性标识
    struct stExprInfo * pAttrExpr;   // 属性表达式
    struct stExprInfo * pValueExpr;  // 值表达式

    char cSplitFlag;                 // | / \ or +

    char * pIndentHead;
    unsigned int iIndentLen;

    char * pKeyword;
    unsigned int iKeywordLen;

    unsigned int iLineNum;

    struct stTreeTranLevel * next;
};

struct stTree
{
    char cType;    // SUB_TREE : 't', TREE : 'T'
    char *pName;
    unsigned int iNameLen;

    unsigned int iPriority;    // 解析位置优先级

    unsigned int iPathMaxX;
    
    struct stTreeCplLevel *pstTreeCplLevels;

    struct stTreeTranLevel *pstTreeTranLevels;

    struct stTree *next;
};

struct stPath
{
    struct stTreeCplLevel *pOneTreeCplLevel;
    struct stTreeTranLevel *pOneTreeTranLevel;

    struct stPath *nextNode;
    struct stPath *next;
};

struct stPathHead
{
    struct stTree *pTree;
    unsigned int iPathY;

    struct stPath *pPathList;
    struct stPath *pTranPathList;

    struct stPathHead *next;
};

struct stCplInfo4Tree
{
    char *pNull;
    unsigned int iPathY;          // 路径序号

    char *pOtherName;             // 路径节点别名
    unsigned int iOtherNameLen;   // 路径节点别名长度

    char *pValue;                 // 值
    unsigned int iValueLen;       // 值长度
};
struct stCplInfo4Line
{
    char *pLeftParm;              // 左参数
    unsigned int iLeftParmLen;    // 左参数长度

    struct stString *pOpr;        // 运算符
    unsigned int iOprPriority;    // 运算符优先级

    char *pRightParm;             // 右参数
    unsigned int iRightParmLen;   // 右参数长度
};
// stCompileInfo 的 mType 下标 
#define IDX_OBJ                   0
#define IDX_TREE_LV_TYPE          1
#define IDX_LEFT_PARM             1
// #define IDX_RIGHT_PARM      2
#define IDX_TREE_LEVEL_TYPE       3
struct stCompileInfo
{
    unsigned int iLoopCount4ShortPath;   // 短路径循环解析次数，转换逻辑有用

    unsigned int iLineNum;        // 脚本行号

    char * pLineHead;             // 行头
    unsigned int iLineHeadKgf;    // 行前空格数

    char mType[4];                // 类型集合
    char *pStrType;               // __DEF_STR__ 具体类型
    unsigned int iStrTypeLen;     // __DEF_STR__ 具体类型长度

    char * pObjName;              // 对象名称
    unsigned int iObjNameLen;     // 对象名称长度

    unsigned int iPriority;       // 解析位置或运算符的优先级

    char *pVal1;
    unsigned int iValLen1;
    char *pVal2;
    unsigned int iValLen2;
    char *pVal3;
    unsigned int iValLen3;

    struct stExprInfo * pAttrExpr;
    struct stString * pTranPartList4Line;  // 行转换规则

    // 注释信息 或 模糊解析时跳过的代码段
    // 跳过的代码段只会挂载在 pstCompileInfoHead 节点，
    // 和注释信息挂载的节点不会冲突
    struct stString * pComments_PassCode;

    struct stCompileInfo * pFork;
    struct stCompileInfo * next;
};

struct stLastTextInfo4Expr
{
    char * pTextBf;
    char * pLineHeadBf;
    unsigned int iLineHeadKgfBf;
    unsigned int iLineNumBf;
    char cCmpIndentFlagBf;
};

class CZGLanguage
{
public:

    CZGLanguage();
    ~CZGLanguage();

    bool initStart();
    bool readSynFile(char *srcFile);
    bool compileCodeFile(char cRunTypeParm, char *srcFile, char *outputFile);
    bool initEnd();

    bool printStrForDebug(const char *pHead, char *pStr, unsigned int iLen);

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

    bool askKxjs();

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

    template <typename T>
    bool initPool(char **pool, T **nodeSrc, unsigned int iBeginNum, unsigned int iExpNum, unsigned int *iPoolBeginNum, unsigned int *iPoolExpNum)
    {
        (*iPoolBeginNum) = iBeginNum;
        (*iPoolExpNum) = iExpNum;
    
        (*pool) = (char *)malloc( iBeginNum * sizeof(T) + sizeof(struct stPoolHead) );
    
        if((*pool) == NULL)
            return false;
    
        struct stPoolHead *pHead = (struct stPoolHead *)(*pool);
        pHead->before = NULL;
        pHead->next = NULL;
        T *pPool = (T *)((*pool) + sizeof(struct stPoolHead) );
        *nodeSrc = pPool;
        for(int i=1; i<iBeginNum; i++)
        {
            pPool->next = pPool + 1;
            pPool ++ ;
        }
        pPool->next = NULL;
        return true;
    }
    
    template <typename T>
    bool addPool(char **pool, T **nodeSrc, unsigned int iNum)
    {
// printf("addPool !!!!!!!!!!! [%d][%d]\n", iNum, iNum * sizeof(T));

        struct stPoolHead *pHead = (struct stPoolHead *)(*pool);
        pHead->next = (char *)malloc( iNum * sizeof(T) + sizeof(struct stPoolHead) );
    
        if(pHead->next == NULL)
            return false;
        struct stPoolHead *pNextHead = (struct stPoolHead *)pHead->next;
        pNextHead->before = (char *)pHead;
        pNextHead->next = NULL;
        (*pool) = pHead->next;
    
        T *pPool = (T *)((*pool) + sizeof(struct stPoolHead) );
        *nodeSrc = pPool;
        for(int i=1; i<iNum; i++)
        {
            pPool->next = pPool + 1;
            pPool ++ ;
        }
        pPool->next = NULL;
        return true;
    }
    
    bool dropPool(char *pool)
    {
        struct stPoolHead *pHead = (struct stPoolHead *)pool;
        while(pHead->before !=  NULL) {
            pHead = (struct stPoolHead *)pHead->before;
            free(pHead->next);
        }
        free(pHead);
        return true;
    }
    
    template <typename T>
    T *getNode(char **pool, T **nodeSrc, unsigned int iNum)
    {
        if((*nodeSrc) == NULL)
        {
            if( ! addPool<T>(pool, nodeSrc, iNum) )
                return NULL;
        }
        T *retNode = *nodeSrc;
        *nodeSrc = (*nodeSrc)->next;
        return retNode;
    }
    
    template <typename T>
    bool freeNode(T **oneNode, T **nodeSrc)
    {
        (*oneNode)->next = (*nodeSrc);
        *nodeSrc = (*oneNode);
        *oneNode = NULL;
        return true;
    }
    
    template <typename T>
    bool freeList(T **list, T **nodeSrc)
    {
        T *pTmp = (*list);
        while(pTmp->next != NULL)
            pTmp = pTmp->next;

        pTmp->next = (*nodeSrc);
        *nodeSrc = *list;
        *list = NULL;
        return true;
    }
    
    template <typename R>
    bool freeMat(R **mat, R **rNodeSrc)
    {
        //freeMatVal<X, T>(&((*mat)->value), xNodeSrc, tNodeSrc);
        free((*mat)->pVal);
        freeNode<R>(mat, rNodeSrc);
        return true;
    }
    
    // ????·¨oˉêy?￡°?
    template <typename T>
    bool initSck(char **sck, T **sckSrc, unsigned int iNum, unsigned int *iSckNum, unsigned int *iSckUabNum)
    {
        (*iSckNum) = iNum;
        (*iSckUabNum) = iNum;
        (*sck) = (char *)malloc( iNum * sizeof(T) + sizeof(struct stSckHead) );
        if((*sck) == NULL)
            return false;
        struct stSckHead *pHead = (struct stSckHead *)(*sck);
        pHead->before = NULL;
        pHead->next = NULL;
        *sckSrc = (T *)(pHead + 1) - 1; // !! Go back to -1 index
        return true;
    }    

    template <typename T>
    bool addSck(char **sck, T **sckSrc, unsigned int iNum, unsigned int *iSckUabNum)
    {
        struct stSckHead *pHead = (struct stSckHead *)(*sck);
        pHead->next = (char *)malloc( iNum * sizeof(T) + sizeof(struct stSckHead) );
    
        if(pHead->next == NULL)
            return false;
    
        struct stSckHead *pNextHead = (struct stSckHead *)pHead->next;
        pNextHead->before = (char *)pHead;
        pNextHead->next = NULL;
        (*sck) = pHead->next;
        *sckSrc = (T *)(pNextHead + 1) - 1;
        (*iSckUabNum) = iNum;
        return true;
    }

    bool dropSck(char *sck)
    {
        struct stSckHead *pHead = (struct stSckHead *)sck;
        while(pHead->before != NULL) {
            pHead = (struct stSckHead *)pHead->before;
            free(pHead->next);
        }
        free(pHead);
        return true;
    }

    template <typename T>
    bool pushSck(char **sck, T **sckSrc, unsigned int iSckNum, unsigned int *iSckUabNum)
    {
        if( (*iSckUabNum) == 0 )
        {
            struct stSckHead *pHead = (struct stSckHead *)(*sck);
            if(pHead->next == NULL) {
                if( ! addSck<T>(sck, sckSrc, iSckNum, iSckUabNum) )
                    return NULL;
            } else {
                (*sck) = pHead->next;
                (*sckSrc) = (T *)((*sck) + sizeof(struct stSckHead)) - 1;
                (*iSckUabNum) = iSckNum;
            }
        }
        (*sckSrc) ++ ;
        memset((*sckSrc), 0x00, sizeof(T));
        (*iSckUabNum) -- ;
        return true;
    }

    template <typename T>
    bool popSck(char **sck, unsigned int iSckNum, unsigned int *iSckUabNum, T **sckSrc)
    {
        (*iSckUabNum) ++ ;
        if( (*iSckUabNum) == iSckNum ) {
            struct stSckHead *pHead = (struct stSckHead *)(*sck);
            if(pHead->next != NULL)
            {
                free(pHead->next);
                pHead->next = NULL;
            }
            if(  pHead->before != NULL ) {
                (*sck) = pHead->before;
                (*sckSrc) = (T *)( pHead->before + sizeof(struct stSckHead) );
                (*sckSrc) = (*sckSrc) + iSckNum - 1;
                (*iSckUabNum) = 0;
            } else
                (*sckSrc) -- ;
        } else
            (*sckSrc) -- ;
        return true;
    }

    template <typename T>
    T *goBackSck(unsigned int iStep, char *sck, unsigned int iSckNum, unsigned int iSckUabNum, T *sckSrc)
    {
        iSckUabNum = iSckUabNum + iStep + 1;
        if( iSckUabNum > iSckNum )
        {
            unsigned int iCount = iSckUabNum / iSckNum;
            struct stSckHead *pHead = (struct stSckHead *)sck;
            for(unsigned int iLoop = 0; iLoop<iCount; iLoop++)
            {
                pHead = (struct stSckHead *)pHead->before;
            }
            iStep = iSckUabNum % iSckNum;
            if( iStep != 0 )
                iStep = iSckNum - iStep;
            return ( (T *)(pHead + 1) + iStep );
        } else
            return (sckSrc - iStep);
    }

    unsigned int countUsedSck(char *sck, unsigned int iSckNum, unsigned int iSckUabNum )
    {
        unsigned int iCount = 0;
        struct stSckHead *pHead = (struct stSckHead *)sck;
        while(pHead->before != NULL)
        {
            iCount ++ ;
            pHead = (struct stSckHead *)pHead->before;
        }
        return (iCount * iSckNum + iSckNum - iSckUabNum);
    }

    bool isSckUsed(char *sck, unsigned int iSckNum, unsigned int iSckUabNum )
    {
        if( iSckNum-iSckUabNum > 0 || ((struct stSckHead *)sck)->before != NULL )
            return true;
        else
            return false;
    }


private:

    struct stLastTextInfo4Expr mLastTextInfo4Expr;

    bool doWithFh();
    bool passKgf();
    bool passKgf_Comment();
    bool retErrInfo(const char *errInfo);
    bool retErrInfo4CodeFile(const char *errInfo);
    bool retWarnInfo4CodeFile(const char *warnInfo);

    // int iCfgFd;
	FILE * pCfgFd;
    unsigned int iCfgFileSize;
    void *pCfgMmp;

    // int iCplFd;
	FILE * pCplFd;
    unsigned int iCplFileSize;
    void *pCplMmp;

    char *pLineHead;
    unsigned int iLineNum;
    unsigned int iLineHeadKgf;
    unsigned int iOneTabLen;
    unsigned int iLineNumBf4Tran;

    // struct stString * pstIndentHead;
    // struct stString * pstIndentTail;
    struct stIndent * pstIndentHead;
    struct stIndent * pstIndentTail;

    char *pText;
    char *pTextBfGoBack;  // 保存能解析到的pText最远文本地址
    char *pText4FuzzyStart;
    char *pText4FuzzyEnd;
    unsigned int iLineNum4FuzzyStart;
    unsigned int iLineNum4FuzzyEnd;
    unsigned int iStep4TypeCont;

    char *retStr;
    char *pLgStr;
    unsigned short iLgStrLen;

    struct stStr *pstStrList;
    struct stLine *pstLineList;
    struct stTree *pstTreeList;
    struct stPathHead *pstPathHeadList;

    // 自定义属性组，将多个属性合并到一个组里，可以减少 @ 后面的属性名称数量
    struct stString *pstAttrGroupList;

    // logic sck
    char *logicSck;
    struct stLogic *logicSckHead;
    unsigned int iLogicSckNum;
    unsigned int iLogicSckUabNum;

    bool initLogicSck(unsigned int iNum);
    bool addLogicSck(unsigned int iNum);
    bool dropLogicSck();
    bool pushLogicSck();
    bool popLogicSck();
    struct stLogic *goBackLogicSck(unsigned int iStep);
    unsigned int countUsedLogicSck();
    bool isLogicSckUsed();

    // stack sck char *stackSck;
    char *stackSck;
    struct stStack *stackSckHead;
    unsigned int iStackSckNum;
    unsigned int iStackSckUabNum;

    bool initStackSck(unsigned int iNum);
    bool addStackSck(unsigned int iNum);
    bool dropStackSck();
    bool pushStackSck();
    bool popStackSck();
    struct stStack *goBackStackSck(unsigned int iStep);
    unsigned int countUsedStackSck();
    bool isStackSckUsed();

    // string pool funtion
    char *stringPool;
    unsigned int iStringBeginNum;
    unsigned int iStringExpNum;

    struct stString *stringNodeSrc;
    bool initStringPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addStringPool(unsigned int iNum);
    bool dropStringPool();
    struct stString *getStringNode();
    bool freeStringNode(struct stString **oneNode);
    bool freeStringList(struct stString **list);

    bool freeExprInfoNode(struct stExprInfo **oneNode);
    bool freeExprInfoList(struct stExprInfo **list);

    bool freeIndentNode(struct stIndent **oneNode);
    bool freeIndentList(struct stIndent **list);

    // str pool funtion
    char *strPool;
    unsigned int iStrBeginNum;
    unsigned int iStrExpNum;

    struct stStr *strNodeSrc;
    bool initStrPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addStrPool(unsigned int iNum);
    bool dropStrPool();
    struct stStr *getStrNode();
    bool freeStrNode(struct stStr **oneNode);
    bool freeStrList(struct stStr **list);

    // strLevel pool funtion
    char *strLevelPool;
    unsigned int iStrLevelBeginNum;
    unsigned int iStrLevelExpNum;

    struct stStrLevel *strLevelNodeSrc;
    bool initStrLevelPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addStrLevelPool(unsigned int iNum);
    bool dropStrLevelPool();
    struct stStrLevel *getStrLevelNode();
    bool freeStrLevelNode(struct stStrLevel **oneNode);
    bool freeStrLevelList(struct stStrLevel **list);

    // lineLevel pool funtion
    char *lineLevelPool;
    unsigned int iLineLevelBeginNum;
    unsigned int iLineLevelExpNum;

    struct stLineLevel *lineLevelNodeSrc;
    bool initLineLevelPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addLineLevelPool(unsigned int iNum);
    bool dropLineLevelPool();
    struct stLineLevel *getLineLevelNode();
    bool freeLineLevelNode(struct stLineLevel **oneNode);
    bool freeLineLevelList(struct stLineLevel **list);

    // line pool funtion
    char *linePool;
    unsigned int iLineBeginNum;
    unsigned int iLineExpNum;

    struct stLine *lineNodeSrc;
    bool initLinePool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addLinePool(unsigned int iNum);
    bool dropLinePool();
    struct stLine *getLineNode();
    bool freeLineNode(struct stLine **oneNode);
    bool freeLineList(struct stLine **list);

    // treeLevel pool funtion
    char *treeCplLevelPool;
    unsigned int iTreeCplLevelBeginNum;
    unsigned int iTreeCplLevelExpNum;

    struct stTreeCplLevel *treeCplLevelNodeSrc;
    bool initTreeCplLevelPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addTreeCplLevelPool(unsigned int iNum);
    bool dropTreeCplLevelPool();
    struct stTreeCplLevel *getTreeCplLevelNode();
    bool freeTreeCplLevelNode(struct stTreeCplLevel **oneNode);
    bool freeTreeCplLevelList(struct stTreeCplLevel **list);

    // treeTranLevel pool funtion
    char *treeTranLevelPool;
    unsigned int iTreeTranLevelBeginNum;
    unsigned int iTreeTranLevelExpNum;

    struct stTreeTranLevel *treeTranLevelNodeSrc;
    bool initTreeTranLevelPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addTreeTranLevelPool(unsigned int iNum);
    bool dropTreeTranLevelPool();
    struct stTreeTranLevel *getTreeTranLevelNode();
    bool freeTreeTranLevelNode(struct stTreeTranLevel **oneNode);
    bool freeTreeTranLevelList(struct stTreeTranLevel **list);

    // tree pool funtion
    char *treePool;
    unsigned int iTreeBeginNum;
    unsigned int iTreeExpNum;

    struct stTree *treeNodeSrc;
    bool initTreePool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addTreePool(unsigned int iNum);
    bool dropTreePool();
    struct stTree *getTreeNode();
    bool freeTreeNode(struct stTree **oneNode);
    bool freeTreeList(struct stTree **list);

    // path pool funtion
    char *pathPool;
    unsigned int iPathBeginNum;
    unsigned int iPathExpNum;

    struct stPath *pathNodeSrc;
    bool initPathPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addPathPool(unsigned int iNum);
    bool dropPathPool();
    struct stPath *getPathNode();
    bool freePathNode(struct stPath **oneNode);
    bool freePathList(struct stPath **list);

    // pathHead pool funtion
    char *pathHeadPool;
    unsigned int iPathHeadBeginNum;
    unsigned int iPathHeadExpNum;

    struct stPathHead *pathHeadNodeSrc;
    bool initPathHeadPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addPathHeadPool(unsigned int iNum);
    bool dropPathHeadPool();
    struct stPathHead *getPathHeadNode();
    bool freePathHeadNode(struct stPathHead **oneNode);
    bool freePathHeadList(struct stPathHead **list);

    // compileInfo pool funtion
    char *compileInfoPool;
    unsigned int iCompileInfoBeginNum;
    unsigned int iCompileInfoExpNum;

    struct stCompileInfo *compileInfoNodeSrc;
    bool initCompileInfoPool(unsigned int iBeginNum, unsigned int iExpNum);
    bool addCompileInfoPool(unsigned int iNum);
    bool dropCompileInfoPool();
    struct stCompileInfo *getCompileInfoNode();
    bool freeCompileInfoNode(struct stCompileInfo **oneNode);
    bool freeCompileInfoList(struct stCompileInfo **list);

    // Get the code file size
    unsigned long getFileSize(char *fileName);

    bool isCaseSensitive;     // 是否区分大小写
    bool isFuzzy;             // 是否模糊解析

    bool isTryKeepComment;    // 是否转换时尝试保留注释
    struct stString *pstCommentList; // 注释内容列表，每节点是独立1或多行注释
    struct stString *pstCommentListTail;

    bool isDebug;                       // 是否Debug模式
    struct stString * pstDebugLimit;    // Debug模式下的打印范围
    bool readDebugLimit();
    bool inDebugLimit(char *pName, unsigned int iNameLen, unsigned int iPathY);

    // 缩进解析类型: 
    // INDENT_NULL         : 解析无缩进，转换无缩进
    // INDENT_COMPILER     : 解析有缩进，转换无缩进
    // INDENT_TRANSLATOR   : 解析无缩进，转换有缩进
    // INDENT_COMPILER_TRANSLATOR : 解析有缩进，转换有缩进
    char cIndentType;

    // 新行缩进对比标识
    // CMP_INDENT_SAME       0   // 与上一行缩进相比 相同
    // CMP_INDENT_ADD        1   // 与上一行缩进相比 增加
    // CMP_INDENT_SUB        2   // 与上一行缩进相比 减少
    // CMP_INDENT_NULL       3   // 空行
    // CMP_INDENT_ERROR      4   // 与上一行缩进相比 错误
    char cCmpIndentFlag;

    // 用于解析部分
    // 下钻时缩进空格数的累加
    struct stString * pstIndentSum4GoNextTree4Cpl;
    struct stString * pstIndentSum4GoNextTree4Cpl4GoBack;
    // 忽略缩进的树下钻次数累计
    unsigned int iCount4SkipIndentTree;

    // 单行注释
    char * pLineComment;
    unsigned int iLineCommentLen;

    char * pLineComment4Tran;
    unsigned int iLineCommentLen4Tran;

    // 多行注释
    char * pLinesCommentStart;
    unsigned int iLinesCommentStartLen;
    char * pLinesCommentEnd;
    unsigned int iLinesCommentEndLen;

    char * pLinesCommentStart4Tran;
    unsigned int iLinesCommentStartLen4Tran;
    char * pLinesCommentEnd4Tran;
    unsigned int iLinesCommentEndLen4Tran;

    // 是否遇到注释，并跳过
    bool isComment();

    struct stString * pstIndentList4TranList;

    bool isLetter();
    bool isName();
    bool getCmpStr();
    bool isVisible();
    bool getVisibleStr();
    bool getInt();
    bool cmpStr(const char *pSrc, char *pTar, unsigned int iLen);

    bool isKeyword(char *pStr, unsigned int iStrLen);
    struct stStr * findStrName(char *pStr, unsigned int iStrLen);
    struct stLine * findLineName(char *pStr, unsigned int iStrLen);
    struct stTree * findTreeName(char *pStr, unsigned int iStrLen);
    struct stString * findAttrGroupName(char *pStr, unsigned int iStrLen);

    bool createNewStr();
    bool readTranPartOfLineLevel(char * pTmp, struct stLineLevel *pThisLineLevel, char cLineLevelType);
    bool createNewLine();
    bool readTranPartOfTree(struct stTree *pThisTree);
    bool createNewTree(char cDefType, unsigned int iPriority);
    bool createNewAttrGroup();

    struct stExprInfo * createOneExprInfo();

    bool completeAllDefInfo();
	// 根据类型，给并行节点排序
    bool orderByCkwflag4TreeLevel();

    bool makeCplTree2Paths();
    bool makeTranTree2Paths();
    bool printOnePath(struct stPath *pPath, unsigned int iPathY);

    struct stString *pTreeNameList4Check;
    bool checkCplTreeInfLoop(char *pTreeName, unsigned int iTreeNameLen);
    bool checkEndOfLine_Any(struct stPathHead *pThisPathHead, struct stPath *pPath, unsigned int iPathY);
    bool checkCplTreePaths();

    bool makeSynTree();

    //////////////////////////////////////////////
    // zgl_language.cpp
    //////////////////////////////////////////////

    char cRunType;

    FILE *pfOpf; // output file

    char cTreeLevelType;
    char cSplitFlag;
    char cSplitFlag4Tran4BfGoDown;   // 下钻前的 cSplitFlag，方便第一个节点分行判断

    struct stString *pPathHeadList4Any;
    struct stString *pPathHeadList4B;
    struct stString *pPathHeadList4T;
    struct stString *pPathHeadList4N;
    struct stString *pPathHeadList4Blank;
    struct stString *pPathHeadList4Cont;
    struct stString *pPathHeadList4Tree;
    struct stString *pPathHeadList4Line;
    struct stString *pPathHeadList4Str;

    bool makePathHeadListByType();

    // unsigned int iSubLineCount;  // ( )
    struct stString * pstSubLineCountList;   // ( )   每个行对象里的括号统计
    bool isCanSplitHere4LineCpl(char *pp);
    unsigned int getStrObjLen(struct stStr *pStrObj, char *pp);

    bool checkLineEnd(struct stPath *pLineEnd, unsigned int iPathY);

    bool doWithLRkh4Line(struct stLine *pLineNode);

    // doWithOneLineNode 函数嵌套深度
    unsigned int iDoWithOneLineNodeCount;
    bool doWithOneLineNode(
         struct stLine *pLineNode
       , struct stPath *pLineEnd
       , unsigned int iPathY
    );

    bool printOneLineCompileInfo(struct stCompileInfo *pLineCompileInfo);

    /*****************************************************************
    解析流程：
    compileTextByTree : pTextSave,iLineNumSave,iSeqSave
        compileOnePath : Tree下一段完整路径 : isFisrtNodeOfOnePath=true
            findFisrtNodeOfOneShortPath : 将上面完整路径进行分割成若干段子路径，调用一次只处理一个循环
                go2NodesOfOneShortPath :  对子路径节点进行验证解析
                    compileTextByTree : 遇到 TREE 节点，需要递归
                    doWithOneLineNode : pTextSave,iLineNumSave,iSeqSave
                        compileTextByTree : 遇到TREE节点，需要递归
    *****************************************************************/

    unsigned int iSeq;
    unsigned int iObjId;

    struct stCompileInfo * pstCompileInfoHead;
    struct stCompileInfo * pstCompileInfoTail;

    struct stCompileInfo * newCompileInfo4Tree(
           char cObjType
         , char cTreeLevelType
         , char *pObjName
         , unsigned int iObjNameLen
         , unsigned int iPathY
         , char *pOtherName
         , unsigned int iOtherNameLen
         , unsigned int iPriority
         , struct stExprInfo * pExprInfo
         , char *pValue
         , unsigned int iValueLen
         , unsigned int iLoopCount4ShortPath
    );

    struct stCompileInfo * newCompileInfo4Line(
           char cObjType
         , char *pObjName
         , unsigned int iObjNameLen
    );

    bool compileTextByTree( 
         struct stTree *pOneTree
       , struct stPath *pFatherPathNode
    );

    bool freeAllCompileInfo4OnePath(struct stCompileInfo *pCompileInfo4OnePath);

    bool compileOnePath (
         struct stPath *pPathList
       , unsigned int iPathY
       , struct stPath *pFatherPathNode
    );

    bool findFisrtNodeOfOneShortPath (
         struct stPath *pPathList
       , unsigned int iPathY
       , bool *isNLoop
       , struct stPath *pFatherPathNode
       , unsigned int iLoopCount
    );

    bool go2NodesOfOneShortPath (
         struct stPath *pPathNextNode
       , unsigned int iPathY
       , bool *isNLoop
       , unsigned int iLoopCount
       , unsigned int * iSkipNodeCount
    );

    bool addCompileInfoHead();
    bool orderTreeNodeByPriority(struct stCompileInfo *pTreeCompileInfo);
    bool orderCplInfoHeadByPriority();

    struct stString * pResultList;
    char * pResultTail;

    bool writeResultList4Tree (
          unsigned int iSeq
        , char cObjType
        , unsigned int iLineNum
        , char * pLineHead4This
        , unsigned int iLineHeadKgf
        , unsigned int iObjId
        , char * pObjName
        , unsigned int iObjNameLen
        , unsigned int iPathY
        , char * pOtherName
        , unsigned int iOtherNameLen
        , char * pValue
        , unsigned int iValueLen
    );

    bool writeLastResult4Tree (
          unsigned int iSeq
        , unsigned int iObjId
        , char * pObjName
        , unsigned int iObjNameLen
        , unsigned int iFirstLineNum4Tree 
    );

    bool writeResultList4Line (
          unsigned int iSeq
        , char cObjType
        , unsigned int iLineNum
        , char * pLineHead4This
        , unsigned int iLineHeadKgf
        , unsigned int iObjId
        , char * pObjName
        , unsigned int iObjNameLen

        , char cLeftParmType
        , char * pLeftParmTypeName
        , unsigned int iLeftParmTypeNameLen

        , char * pLeftParm
        , unsigned int iLeftParmLen

        , struct stString * pOpr
        , char cOprType

        , char cRightParmType
        , char * pRightParmTypeName
        , unsigned int iRightParmTypeNameLen

        , char * pRightParm
        , unsigned int iRightParmLen
    );

    struct stString * pstTranResult4OneLine;
    bool makeTranResult4OneLine (
          unsigned int iSeq

        , char cLeftParmType
        , char cOprType
        , char cRightParmType

        , char * pLeftParm
        , unsigned int iLeftParmLen
        , struct stString * pLeftParmTranList

        , struct stString * pOpr
        , struct stString * pOprTranList

        , char * pRightParm
        , unsigned int iRightParmLen
        , struct stString * pRightParmTranList
    );

    struct stSuccessText4ObjPoint
    {
        char * pTextAddr;
        void * pObjPoint;
    };

    struct stFailText4ObjPoint
    {
        char * pTextAddr;
        struct stString * pObjPoint;
    };

    unsigned int iCloseDebugTimes;
    struct stSuccessText4ObjPoint * pSuccessText4ObjPointHashTab;
    bool addSuccessText4ObjPoint(char * pTextSave, void * pSuccessObjPoint);
    bool isSuccessText4ObjPoint(void * pObjPoint);

    struct stFailText4ObjPoint * pFailText4ObjPointHashTab;
    bool addFailText4ObjPoint(void * pFailObjPoint);
    bool isFailText4ObjPoint(void * pObjPoint);

    bool writeCommentAtLineStart(
         struct stCompileInfo * pOneCompileInfo
       , char * pIndent1, unsigned int iIndentLen1
       , char * pIndent2, unsigned int iIndentLen2
    );
    bool writeCommentAtLineEnd(struct stCompileInfo * pOneCompileInfo);

    bool writePassCode(char *pPassCode, unsigned int iPassCodeLen);

    bool doWithCompileInfo4Line4CT(struct stCompileInfo * pOneFork, unsigned int iObjId4This);
    bool go2CompileInfoTree4Cpl(struct stCompileInfo * pOneFork);
    // bool go2CompileInfoTree4CplExpr4Tran(struct stCompileInfo * pOneFork);

    /**************************************************
    go2CompileInfoTree4Tran(struct stCompileInfo * pOneFork)
        runAttrExpr4OnePathCplInfo(struct stCompileInfo * pOneFork);
        writeTreeTranResult(pTranShortPathHeadNodeList)
            writeTranRes4ShortPaths(pTranShortPathHeadNodeList);
                go2CompileInfoTree4Tran(pOneCompileInfo->pFork);
    **************************************************/
    struct stExprRetHead * pstExprRetHead;
    bool runAttrExpr(struct stCompileInfo *pOneCompileInfo);
    struct stString mRet4runValueExpr;
    bool runValueExpr(struct stExprInfo * pValExpr, struct stCompileInfo *pCompileInfo);

    bool go2CompileInfoTree4Tran(struct stCompileInfo * pOneFork);
    bool runAttrExpr4OnePathCplInfo(struct stCompileInfo * pOneFork);
    bool writeTreeTranResult(struct stString * pTranShortPathHeadNodeList);
    bool writeTreeTranResult4n(struct stString * pTranShortPathHeadNodeList);
    bool doWithMem4WriteTranResult(unsigned int iNeedMemSize);
    bool writeTranRes4ShortPaths(struct stString * pTranShortPathHeadNodeList);
    bool writeLineTranResult(struct stString * pOneTranResult4OneLine);

    bool outputCompileInfo();


};

#endif

