📄 exp.cpp
字号:
xb_error(XB_PARSE_ERROR); while( s && *s ) { if( *s == ')' ) { Wctr--; if( !Wctr ) { TokenType = 'F'; /* function */ PreviousType = 'F'; TokenLen++; return XB_NO_ERROR; } } if( *s == '(' ) Wctr++; s++; TokenLen++; MaxCtr++; if( MaxCtr >= MaxLen ) xb_error(XB_PARSE_ERROR); } xb_error(XB_PARSE_ERROR); } else { np = s + 1; pp = s - 1; if( !s || !*s || (IsSeparator( *s ) && !(*s == '-' && *np == '>' ) && !(*s == '>' && *pp == '-' ))) { if(TokenLen > 0) { TokenType = 'D'; /* database field */ PreviousType = 'D'; return XB_NO_ERROR; } } } } return XB_NO_ERROR;}/*************************************************************************///! IsSeparator/*!*/char xbExpn::IsSeparator( char c ){ if( c == '-' || c == '+' || c == '*' || c == '/' || c == '$' || c == ' ' || c == '#' || c == '<' || c == '>' || c == '^' || c == '=' || c == '.' /* || c == ')' */ ) return c; else return 0;}/*************************************************************************///! GetExpNode/*!*/xbExpNode * xbExpn::GetExpNode(xbShort Len) { xbExpNode * Temp; Temp = new xbExpNode; if( Temp && Len > 0 ) Temp->ResultLen = Len; return Temp;}/*************************************************************************///! LoadExpNode/*!*/xbExpNode * xbExpn::LoadExpNode( const char *ENodeText, /* pointer to text data */ const char EType, /* Operand type */ const xbShort ELen, /* length of node text data */ const xbShort BufLen ) /* length needed in the buffer*/{ xbExpNode * CurNode; if(( CurNode = GetExpNode(BufLen)) == NULL ) return NULL; CurNode->NodeText = strdup( ENodeText ); CurNode->Type = EType; CurNode->Len = ELen; CurNode->InTree = 1; CurNode->ResultLen = BufLen; return CurNode;}/*************************************************************************///! BuildExpressionTree/*!*/xbShort xbExpn::BuildExpressionTree( const char * Expression, xbShort MaxTokenLen, xbDbf * d ){ /* previous node is the node to insert under */ xbExpNode * CurNode = 0; xbExpNode * PreviousNode; xbShort rc, FieldNo=0, BufLen; xbShort TokenLenCtr; char c; const char *p; char TempField[11]; char TableName[31]; xbDbf * TempDbf=0; int LocTokenLen; if( Tree ) { delete Tree; Tree = NULL; } p = Expression; PreviousNode = NULL; PreviousType = TokenLenCtr = 0; while( IsWhiteSpace( *p )) { p++; TokenLenCtr++; if(TokenLenCtr >= MaxTokenLen) return XB_NO_ERROR; } rc = GetNextToken( p, MaxTokenLen-TokenLenCtr ); LocTokenLen = TokenLen; if( rc != XB_NO_DATA && rc != XB_NO_ERROR ) return rc; while( rc == 0 ){ if( TokenType == 'D' && d ){ if( TokenLen > 30 ) strncpy( TableName, p, 30 ); else strncpy( TableName, p, TokenLen ); memset( TempField, 0x00, 11 ); if( strstr( p, "->" ) != NULL ) { if(( TempDbf = d->xbase->GetDbfPtr( TableName )) == NULL ) xb_error(XB_INVALID_FIELD); xbShort tlen = 0; while( TableName[tlen] != '-' && TableName[tlen+1] != '>' ) tlen++; tlen = TokenLen - tlen - 2; // length of field name const char * fp = strstr( p, "->" ); fp += 2; // ptr to beginning of field name strncpy( TempField, fp, tlen ); } else { TempDbf = d; if( TokenLen > 10 ) xb_error(XB_INVALID_FIELD); strncpy( TempField, p, TokenLen ); } if(( FieldNo = TempDbf->GetFieldNo( TempField )) == -1 ) xb_error(XB_INVALID_FIELD); BufLen = TempDbf->GetFieldLen( FieldNo ) + 1; } else if( TokenType == 'C' || TokenType == 'N' ) BufLen = TokenLen + 1; else BufLen = 0; if( TokenType == 'C' ) p++; /* go past first ' */ if( TokenType != 'O' ) { if( !Tree ) { /* create root node with this token */ CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen ); Tree = CurNode; } else { /* put as child 2 of previous node */ CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen ); PreviousNode->Sibling2 = CurNode; CurNode->Node = PreviousNode; } if( TokenType == 'E' ) { if((rc=ReduceComplexExpression(p,TokenLen,CurNode,d))!=0) return rc; if(PreviousNode) CurNode = PreviousNode->Sibling2; else CurNode = Tree; } else if( TokenType == 'F' ) { if(( rc = ReduceFunction( p, CurNode, d)) != 0 ) return rc; CurNode->ExpressionType = GetFuncInfo( p, 2 ); CurNode->dbf = d; } else if( TokenType == 'D' && d ) { CurNode->DataLen = BufLen - 1; CurNode->FieldNo = FieldNo; CurNode->dbf = TempDbf; c = TempDbf->GetFieldType( FieldNo ); if( c == 'C' || c == 'M' ) CurNode->ExpressionType = 'C'; else if( c == 'L' ) CurNode->ExpressionType = 'L'; else if( c == 'N' || c == 'F' ) CurNode->ExpressionType = 'N'; else if( c == 'D' ) CurNode->ExpressionType = 'D'; } else if( TokenType == 'C' || TokenType == 'N' ) { CurNode->DataLen = CurNode->Len; CurNode->StringResult = CurNode->NodeText; CurNode->StringResult.resize( CurNode->DataLen+1 ); if( TokenType == 'N' ) { CurNode->DoubResult = strtod( CurNode->StringResult, 0 ); CurNode->ExpressionType = 'N'; } else CurNode->ExpressionType = 'C'; } } else /* it is an operator */ { if(!Tree) { if(*p == '-') { CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); CurNode->ExpressionType = 'C'; } else xb_error(XB_EXP_SYNTAX_ERROR); } else { if( Tree->Type != 'O' ) { CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); Tree->Node = CurNode; /* link the new parent to old tree */ CurNode->Sibling1 = Tree; /* connect the sibling */ Tree = CurNode; /* root in tree */ } else { PreviousNode = CurNode->Node; CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); while( PreviousNode && (( OperatorWeight( PreviousNode->NodeText, TokenLen ) == 0 ) || ( OperatorWeight( CurNode->NodeText, TokenLen ) >= /*<=*/ OperatorWeight( PreviousNode->NodeText, TokenLen )))) PreviousNode = PreviousNode->Node; if( PreviousNode ) { CurNode->Node = PreviousNode; CurNode->Sibling1 = PreviousNode->Sibling2; PreviousNode->Sibling2 = CurNode; CurNode->Sibling1->Node = CurNode; } else { /* insert at root */ CurNode->Sibling1 = Tree; Tree = CurNode; CurNode->Sibling1->Node = CurNode; } } if( LogicalType ) CurNode->ExpressionType = 'L'; } } PreviousNode = CurNode;// p += CurNode->Len; p += LocTokenLen; if( TokenType == 'C' ) { p++; /* go past last ' */ TokenLenCtr+=2; /* add the quotes */ }// TokenLenCtr += CurNode->Len; TokenLenCtr += LocTokenLen; if( TokenLenCtr >= MaxTokenLen ) return XB_NO_ERROR; if( p && *p && TokenType == 'E' ) { p++; TokenLenCtr++; } while( IsWhiteSpace( *p )) { p++; TokenLenCtr++; if( TokenLenCtr >= MaxTokenLen ) return XB_NO_ERROR; } rc = GetNextToken( p, MaxTokenLen-TokenLenCtr ); LocTokenLen = TokenLen; if( rc != XB_NO_DATA && rc != XB_NO_ERROR ) return rc; } return XB_NO_ERROR;}/*************************************************************************///! GetExpressionResultType/*!*/char xbExpn::GetExpressionResultType( XB_EXPRESSION * e ) { xbExpNode * Temp = 0; if( e ) Temp = e; else if( !Temp ) Temp = Tree; else return 0; if( e->Type == 'O' && ( *e->NodeText == '<' || *e->NodeText == '>' || *e->NodeText == '=' || *e->NodeText == '#' || *e->NodeText == '$' )) return 'L'; while( Temp && !Temp->ExpressionType && Temp->Sibling1 ) Temp = Temp->Sibling1; return Temp->ExpressionType;}/*************************************************************************///! GetExpressionHandle/*!*/XB_EXPRESSION * xbExpn::GetExpressionHandle( void ) { XB_EXPRESSION * e; e = Tree; Tree = NULL; return e;}/*************************************************************************///! OperatorWeight/*!*/xbShort xbExpn::OperatorWeight( const char * Oper, xbShort len ){ if( len < 1 || len > 5 ) return 0; if( len == 1 && ( Oper[0] == '*' && Oper[1] == '*' )) return 3; if( Oper[0] == '+' || Oper[0] == '-' ) return 1; if( Oper[0] == '*' || Oper[0] == '/' ) return 2; if(Oper[0] == '.') return 1; return 0;}/*************************************************************************///! ReduceComplexExpression/*!*/xbShort xbExpn::ReduceComplexExpression(const char *NextToken, xbShort Len, xbExpNode *cn, xbDbf *d) { const char *p; xbShort rc; xbExpNode * SaveTree; SaveTree = Tree; Tree = NULL; p = NextToken; p++; if(( rc = BuildExpressionTree( p, Len-2, d )) != XB_NO_ERROR ) return rc; if(cn->Node) { /* then this is the base tree */ cn->Node->Sibling2 = Tree; Tree->Node = cn->Node; delete cn; Tree = SaveTree; } else delete cn; return XB_NO_ERROR;}/*************************************************************************///! GetFunctionTokenLen/*!*/xbShort xbExpn::GetFunctionTokenLen( const char * s ){ xbShort cnt, LeftParenCtr; const char *p; cnt = LeftParenCtr = 0; p = s; while( p && ( *p != ',' || ( *p == ',' && LeftParenCtr > 0 )) && !( LeftParenCtr == 0 && *p == ')')) { if( *p == '(' ) LeftParenCtr++; else if( *p == ')' ) LeftParenCtr--; p++; cnt++; } return cnt;}/*************************************************************************///! ReduceFunction/*!*/xbShort xbExpn::ReduceFunction(const char *NextToken, xbExpNode *cn, xbDbf *d){ const char *p; xbShort rc; xbShort FuncTokenLen; xbExpNode * SaveTree; p = strchr( NextToken, '(' ); if (!p) xb_error(XB_PARSE_ERROR); p++; while( IsWhiteSpace( *p )) p++; if (*p == ')') return XB_NO_ERROR; /* do function paramater 1 */ FuncTokenLen = GetFunctionTokenLen( p ); SaveTree = Tree; Tree = NULL; if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) return rc; cn->Sibling1 = Tree; Tree->Node = cn; Tree = SaveTree; /* do function paramater 2 */ p += FuncTokenLen; while( IsWhiteSpace( *p )) p++; if(*p == ')') return XB_NO_ERROR; if( *p != ',' ) xb_error(XB_PARSE_ERROR); p++; while( IsWhiteSpace( *p )) p++; FuncTokenLen = GetFunctionTokenLen( p ); SaveTree = Tree; Tree = NULL; if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) return rc; cn->Sibling2 = Tree; Tree->Node = cn; Tree = SaveTree; /* do function paramater 3 */ p += FuncTokenLen; while( IsWhiteSpace( *p )) p++; if (*p == ')') return XB_NO_ERROR; if( *p != ',' ) xb_error(XB_PARSE_ERROR); p++; while( IsWhiteSpace( *p )) p++; FuncTokenLen = GetFunctionTokenLen( p ); SaveTree = Tree; Tree = NULL; if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) xb_error(rc); cn->Sibling3 = Tree; Tree->Node = cn; Tree = SaveTree; return XB_NO_ERROR;}/*************************************************************************///! ParseExpression/*!*/xbShort xbExpn::ParseExpression(const char *exp, xbDbf *d) { return BuildExpressionTree(exp, strlen(exp), d);}/*************************************************************************///! ProcessExpression/*!*/xbShort xbExpn::ProcessExpression(const char *e, xbDbf *d) { xbShort rc; if(( rc = BuildExpressionTree( e, strlen( e ), d )) != XB_NO_ERROR ) return rc; if(( rc = ProcessExpression( Tree )) != XB_NO_ERROR ) return rc; return XB_NO_ERROR;}/*************************************************************************/#ifdef XBASE_DEBUG//! DumpExpressionTree/*!*/void xbExpn::DumpExpressionTree( xbExpNode * E ){ if( !E ) E = Tree; if( !E ) return; DumpExpNode( E ); if( E->Sibling1 ) DumpExpressionTree( E->Sibling1 ); if( E->Sibling2 ) DumpExpressionTree( E->Sibling2 ); if( E->Sibling3 ) DumpExpressionTree( E->Sibling3 ); return;}/*************************************************************************///! DumpExpNode/*!*/void xbExpn::DumpExpNode(xbExpNode *e) { cout << "\n\n****** Exp Node ******"; cout << "\nExp Node Address " << e; cout << " Node Text = " << e->NodeText; cout << "\nType = " << e->Type; cout << " Len = " << e->Len; cout << " InTree = " << e->InTree; cout << "\nParent = " << e->Node; cout << "\nField No = " << e->FieldNo; cout << "\nExpressionType = " << e->ExpressionType; cout << "\nStringResult = " << e->StringResult; cout << " DoubResult = " << e->DoubResult; cout << " IntResult = " << e->IntResult; cout << " ResultLen = " << e->ResultLen; cout << " DataLen = " << e->DataLen; cout << " Sibling 1 = " << e->Sibling1; cout << " Sibling 2 = " << e->Sibling2; if( e->Sibling3 ) cout << " Sibling3 = " << e->Sibling3; return;}#endif#endif // XB_EXPRESSIONS/*************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -