@@ -144,6 +144,7 @@ Private Const op_like As String = "$"
144144Private Const op_neg As String = "~"
145145Private Const op_AllItems As String = "*+-/^%\=<>&|$"
146146Private Const op_AllNotUnaryItems As String = "*/^%\=<>&|$"
147+ Private Const d_FullGrammar As String = "*+-~/^%\=<>&|!$()[]{}'; "
147148Private Const d_lCurly As String = "{"
148149Private Const d_rCurly As String = "}"
149150Private Const d_lParenthesis As String = "("
@@ -152,7 +153,10 @@ Private Const d_lSquareB As String = "["
152153Private Const d_rSquareB As String = "]"
153154Private Const d_Apostrophe As String = "'"
154155Private Const d_Space As String = " "
156+ Private Const d_Semicolon As String = ";"
155157Private Const e_ValueError As String = "#VALUE!"
158+ Private Const e_NAError As String = "#NA"
159+ Private Const e_InvalidAssignment As String = "#e-100" 'Expressions cannot be assigned a value.
156160Private Const Tiny As Double = 1 E-20
157161'#
158162'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -305,7 +309,7 @@ Private Sub Class_Initialize()
305309 PI = 4 * Atn(1 )
306310 PID2 = PI / 2
307311 e = Exp(1 )
308- P_SEPARATORCHAR = ";"
312+ P_SEPARATORCHAR = d_Semicolon
309313 P_DEC_SYMBOL = dsDot
310314 AscDecSymbol = 46
311315 P_GALLOPING_MODE = True
@@ -598,67 +602,99 @@ End Function
598602
599603''' <summary>
600604''' Method to obtain abstract expressions that do not contemplate the intermediate
601- ''' assignments defined by the equals sign .
605+ ''' assignments.
602606''' </summary>
603- Public Sub AbstractAssignments ()
604- Dim i As Long
605- Dim j As Long
606- Dim tUB As Long
607- Dim tkUB As Long
607+ Public Function AbstractAssignments (ByRef aExpression As Variant ) As String ()
608+ Dim strToEvaluate As String
609+ Dim EqualSymbolPos As Long
610+ Dim TokenDet As TokenInfo
608611 Dim tmpToken As token
609- Dim BaseIndex As Long
612+ Dim tmpResult() As String
613+ Dim tmpStrAssignments As String
610614 Dim n As Long
611- Dim tmpIdxRep As String
615+ Dim testChar As String
616+ Dim testChar2 As String
612617
613- tUB = UBound(EvalTree )
614- tkUB = UBound(EvalTree(tUB).Storage)
615- i = LBound(EvalTree(tUB).Storage )
616- BaseIndex = UBound(SubTreeData) + 1
618+ strToEvaluate = FormatEntry(CStr(aExpression) )
619+ strToEvaluate = ReconstructLiteralStrings(P_EXPRESSION, _
620+ SBracketsNotationToNominal(ReplaceImpliedMult(strToEvaluate)) )
621+ ReDim tmpResult( 0 To 1 ) 'Indexes: [0] variables; [1] expression to evaluate
617622 Do
618- If EvalTree(tUB).Storage(i).OperationToken = otEqual Then
619- If (i + j + 1 ) <= tkUB Then 'Do not move anything beyond array limits
620- tmpToken = EvalTree(tUB).Storage(i)
621- EvalTree(tUB).Storage(i) = EvalTree(tUB).Storage(i + j + 1 )
622- EvalTree(tUB).Storage(i + j + 1 ) = tmpToken
623+ Do 'Discard false positives
624+ EqualSymbolPos = GetOPeratorSymbolPos(strToEvaluate, op_equal, EqualSymbolPos + 1 )
625+ If EqualSymbolPos > 2 Then
626+ testChar = MidB$(strToEvaluate, EqualSymbolPos - 2 , 2 )
627+ testChar2 = MidB$(strToEvaluate, EqualSymbolPos + 2 , 2 ) 'Check ahead for "=="
628+ Else
629+ testChar = vbNullString
630+ testChar2 = vbNullString
623631 End If
624- j = j + 1 'equality counter
625- Else
626- If EvalTree(tUB).Storage(i).Arg1.LinkedIndex <> -1 Then
627- If EvalTree(tUB).Storage(i).Arg1.LinkedIndex >= BaseIndex Then
628- LIndexConstruc(1 ) = EvalTree(tUB).Storage(i).Arg1.LinkedIndex
629- tmpIdxRep = Join$(LIndexConstruc, vbNullString)
630- EvalTree(tUB).Storage(i).Arg1.LinkedIndex = EvalTree(tUB).Storage(i).Arg1.LinkedIndex - j
631- LIndexConstruc(1 ) = EvalTree(tUB).Storage(i).Arg1.LinkedIndex
632- EvalTree(tUB).Storage(i).DefString = Replace( _
633- EvalTree(tUB).Storage(i).DefString, _
634- tmpIdxRep, _
635- Join$(LIndexConstruc, vbNullString))
632+ Loop While EqualSymbolPos > 0 And (testChar Like "[<>=]" Or testChar2 = op_equal)
633+ If EqualSymbolPos Then
634+ TokenDet.LogicalToken = True
635+ TokenDet.Position = EqualSymbolPos
636+ TokenDet.OperationToken = otEqual
637+ TokenDet.OperatorLen = LenB(op_equal)
638+ ExtractEvalToken strToEvaluate, tmpToken, TokenDet
639+ 'Collect variables
640+ If tmpStrAssignments = vbNullString Then
641+ If AbstractValidate(tmpToken.Arg1.DefString) Then
642+ tmpStrAssignments = tmpToken.Arg1.DefString
643+ Else
644+ n = n + 1
636645 End If
637- End If
638- If EvalTree(tUB).Storage(i).Arg2.LinkedIndex <> -1 Then
639- If EvalTree(tUB).Storage(i).Arg2.LinkedIndex >= BaseIndex Then
640- LIndexConstruc(1 ) = EvalTree(tUB).Storage(i).Arg2.LinkedIndex
641- tmpIdxRep = Join$(LIndexConstruc, vbNullString)
642- EvalTree(tUB).Storage(i).Arg2.LinkedIndex = EvalTree(tUB).Storage(i).Arg2.LinkedIndex - j
643- LIndexConstruc(1 ) = EvalTree(tUB).Storage(i).Arg2.LinkedIndex
644- EvalTree(tUB).Storage(i).DefString = Replace( _
645- EvalTree(tUB).Storage(i).DefString, _
646- tmpIdxRep, _
647- Join$(LIndexConstruc, vbNullString))
646+ If AbstractValidate(tmpToken.Arg2.DefString) Then
647+ If tmpStrAssignments = vbNullString Then
648+ tmpStrAssignments = tmpToken.Arg2.DefString
649+ Else
650+ tmpStrAssignments = tmpStrAssignments & "#" & tmpToken.Arg2.DefString
651+ End If
652+ Else
653+ n = n + 1
654+ End If
655+ Else
656+ If Not AbstractValidate(tmpToken.Arg1.DefString) Then
657+ n = n + 1
658+ End If
659+ If AbstractValidate(tmpToken.Arg2.DefString) Then
660+ tmpStrAssignments = tmpStrAssignments & "#" & tmpToken.Arg2.DefString
661+ Else
662+ n = n + 1
648663 End If
649664 End If
650- i = i + 1
665+ Else
666+ Exit Do
667+ End If
668+ Loop
669+ If n Then 'Isolate assigments
670+ If n < 2 Then
671+ tmpResult(0 ) = tmpStrAssignments
672+ tmpResult(1 ) = Replace(strToEvaluate, Join$(Split(tmpStrAssignments, _
673+ "#" ), op_equal) & op_equal, _
674+ vbNullString)
675+ Else 'Expressions cannot be assigned a value.
676+ tmpResult(0 ) = e_InvalidAssignment
677+ tmpResult(1 ) = e_InvalidAssignment
651678 End If
652- n = n + 1
653- Loop While n - 1 < tkUB
654- If j = n Then 'Full assigment
655- ReDim Preserve EvalTree(0 To tUB - 1 )
656- Else 'j < n
657- ReDim Preserve EvalTree(tUB).Storage(0 To tkUB - j)
658- EvalTree(tUB).index = EvalTree(tUB).index - j
659- EvalTree(tUB).Capacity = EvalTree(tUB).Capacity - j
679+ Else
680+ tmpResult(0 ) = e_NAError
681+ tmpResult(1 ) = strToEvaluate
660682 End If
661- End Sub
683+ AbstractAssignments = tmpResult
684+ End Function
685+ Private Function AbstractValidate (strAssignments As String ) As Boolean
686+ Dim i As Long
687+ Dim L As Long
688+ Dim tmpResult As Boolean
689+
690+ L = Len(d_FullGrammar)
691+ i = 1
692+ Do
693+ tmpResult = (InStr(1 , strAssignments, Mid(d_FullGrammar, i, 1 )) = 0 )
694+ i = i + 1
695+ Loop While i <= L And tmpResult
696+ AbstractValidate = tmpResult
697+ End Function
662698
663699Private Function aCeiling (ByRef expression As String , ByRef fName As String ) As String
664700 On Error GoTo err_Handler
@@ -4044,42 +4080,49 @@ Private Function GetCBItemIdx(ByRef cbBuffer As ClusterBuffer, ByRef ItemName As
40444080 End If
40454081End Function
40464082
4047- Private Function GetEvalToken (ByRef expression As String ) As token
4083+ Private Sub ExtractEvalToken (ByRef expression As String , _
4084+ ByRef aToken As token , ByRef TokenDet As TokenInfo )
40484085 Dim TokenStart As Long
40494086 Dim TokenEnd As Long
4050- Dim TokenDet As TokenInfo
40514087 Dim tmpArgs() As String
40524088
4053- TokenDet = GetTokenInfo(expression)
40544089 If TokenDet.Position > 2 Then
40554090 '@--------------------------------------------------------------------
40564091 ' Delimit token
40574092 GetTokenStart expression, TokenDet.Position, TokenStart
40584093 GetTokenEnd expression, TokenDet.Position, TokenDet.OperatorLen, TokenEnd
4059- GetEvalToken .DefString = MidB$(expression, TokenStart, TokenEnd - TokenStart + 2 )
4060- GetEvalToken .OperationToken = TokenDet.OperationToken
4061- SplitToken GetEvalToken .DefString, tmpArgs, GetEvalToken .OperationToken
4062- GetEvalToken .Logical = TokenDet.LogicalToken
4094+ aToken .DefString = MidB$(expression, TokenStart, TokenEnd - TokenStart + 2 )
4095+ aToken .OperationToken = TokenDet.OperationToken
4096+ SplitToken aToken .DefString, tmpArgs, aToken .OperationToken
4097+ aToken .Logical = TokenDet.LogicalToken
40634098 '@--------------------------------------------------------------------
40644099 ' Define arguments
4065- GetEvalToken .Arg1.DefString = tmpArgs(LBound(tmpArgs))
4066- GetEvalToken .Arg2.DefString = tmpArgs(UBound(tmpArgs))
4100+ aToken .Arg1.DefString = tmpArgs(LBound(tmpArgs))
4101+ aToken .Arg2.DefString = tmpArgs(UBound(tmpArgs))
40674102 '@--------------------------------------------------------------------
40684103 ' Fill arguments data
4069- FillTokenArgProps GetEvalToken .Arg1
4070- FillTokenArgProps GetEvalToken .Arg2
4104+ FillTokenArgProps aToken .Arg1
4105+ FillTokenArgProps aToken .Arg2
40714106 Else 'Retun values
4072- GetEvalToken .DefString = expression
4073- GetEvalToken .OperationToken = OperatorToken.otNull
4074- GetEvalToken .Logical = TokenDet.LogicalToken
4107+ aToken .DefString = expression
4108+ aToken .OperationToken = OperatorToken.otNull
4109+ aToken .Logical = TokenDet.LogicalToken
40754110 '@--------------------------------------------------------------------
40764111 ' Define argument
4077- GetEvalToken .Arg1.DefString = expression
4112+ aToken .Arg1.DefString = expression
40784113 '@--------------------------------------------------------------------
40794114 ' Fill argument data
4080- FillTokenArgProps GetEvalToken .Arg1
4081- FillTokenArgProps GetEvalToken .Arg2, True
4115+ FillTokenArgProps aToken .Arg1
4116+ FillTokenArgProps aToken .Arg2, True
40824117 End If
4118+ End Sub
4119+ Private Function GetEvalToken (ByRef expression As String ) As token
4120+ Dim TokenDet As TokenInfo
4121+ Dim tmpResult As token
4122+
4123+ TokenDet = GetTokenInfo(expression)
4124+ ExtractEvalToken expression, tmpResult, TokenDet
4125+ GetEvalToken = tmpResult
40834126End Function
40844127
40854128Private Function GetFunctionName (ByRef expression As String ) As String
0 commit comments