LOCAL loTokenizer AS Tokenizer LOCAL lcToken AS String LOCAL lcTest AS String m.loTokenizer = CREATEOBJECT("Tokenizer") m.loTokenizer.AddTokenPattern("(\+|-)?(\.\d+|\d+(\.\d+)?)((e|E)(\+|-)?\d+)*") m.loTokenizer.AddTokenPattern('("[^"]*"|' + "'[^']*'|\[[^\[]*\])") m.loTokenizer.AddTokenPattern("{\^\d{1,4}-\d{1,2}-\d{1,2}}") m.loTokenizer.AddTokenPattern("\.(t|T|f|F|((n|N)(u|U)[lL]{2}))\.") m.loTokenizer.AddTokenPattern("(\+|-|\*|\/|%|,|\))") m.loTokenizer.AddTokenPattern("[a-zA-Z][a-zA-Z0-9]*\(") CLEAR ACCEPT "Test Expression: " TO m.loTest IF !m.loTokenizer.GetTokens(m.loTest) ? "Error @" + m.loTokenizer.ErrorPointer ELSE ? "Tokens found:" FOR EACH m.lcToken IN m.loTokenizer.Tokens ? m.lcToken ENDFOR ENDIF DEFINE CLASS Tokenizer AS Custom RegExpr = .NULL. TokenPatterns = .NULL. Tokens = .NULL. ErrorPointer = "" FUNCTION Init IF !"\_REGEXP.VCX" $ SET("Classlib") SET CLASSLIB TO (ADDBS(HOME(1)) + "ffc\_regexp.vcx") ADDITIVE ENDIF This.RegExpr = CREATEOBJECT("_regexp") This.TokenPatterns = CREATEOBJECT("collection") This.Tokens = CREATEOBJECT("collection") ENDFUNC FUNCTION AddTokenPattern (tcPattern AS String) This.TokenPatterns.Add(IIF(LEFT(m.tcPattern,1) != "^", "^", "") + m.tcPattern) ENDFUNC FUNCTION GetTokens (tcExpression AS String) LOCAL lcExpression AS String LOCAL lcTokenPattern AS String LOCAL lnTokenPattern AS Integer LOCAL lcToken AS String m.lcExpression = ALLTRIM(m.tcExpression) This.Tokens.Remove(-1) This.ErrorPointer = "" DO WHILE !EMPTY(m.lcExpression) m.lcToken = .NULL. FOR m.lnTokenPattern = 1 TO This.TokenPatterns.Count m.lcTokenPattern = This.TokenPatterns.Item(m.lnTokenPattern) This.RegExpr.Clear() This.RegExpr.Pattern = m.lcTokenPattern IF This.RegExpr.Execute(m.lcExpression,.F.) = 1 m.lcToken = This.RegExpr.Matches[1,2] m.lcExpression = LTRIM(SUBSTR(m.lcExpression,LEN(m.lcToken) + 1)) This.Tokens.Add(m.lcToken) EXIT ENDIF ENDFOR IF ISNULL(m.lcToken) This.ErrorPointer = m.lcExpression RETURN .F. ENDIF ENDDO RETURN .T. ENDFUNC ENDDEFINE