Ticket #36: nextToken-cleanup2.patch

File nextToken-cleanup2.patch, 5.2 kB (added by hopscc, 5 months ago)
  • Source/Tokenizer.cobra

     
    436436                Returns all remaining tokens as a list. 
    437437                """ 
    438438                tokens = List<of IToken>() 
     439                #st = DateTime.now 
    439440                while true 
    440441                        t = .nextToken 
    441442                        if t 
    442443                                tokens.add(t) 
    443444                        else 
    444445                                break 
     446                # Determine timings for various Tokeniser lexing changes 
     447                #duration = DateTime.now.subtract(st) 
     448                #if  tokens.count > 100 and duration > TimeSpan(0) 
     449                #       avTicksPerToken = (duration.ticks / (tokens.count to int64)) to int 
     450                #       msecs = avTicksPerToken/10000 
     451                #       fileNm = _fileName 
     452                #       fileNm = if( fileNm.startsWith("("), '(None)', Path.getFileName(fileNm) ) 
     453                #       print "[fileNm.padRight(20)]\t[duration]\t[tokens.count]\t" stop 
     454                #       print " [msecs:N3] ms/Token av ([msecs/1000:N3]sec)" 
    445455                return tokens 
    446456 
    447457        def restart 
     
    591601                                        return nil 
    592602                        try 
    593603                                assert _tokenDefs 
    594                                 if _narrowTokenDefs and _tokenDefs.count >= _minNumTokenDefsToNarrow 
    595                                         assert _tokenDefsByFirstChar 
    596                                         assert _sourceLine.length 
    597                                         if _tokenDefsByFirstChar.containsKey(_sourceLine[0]) 
    598                                                 # print 'Using short list for char: [_sourceLine[0]], [_sourceLine[0] to int]' 
    599                                                 tokenDefs = _tokenDefsByFirstChar[_sourceLine[0]] 
    600                                         else 
    601                                                 tokenDefs = _tokenDefs to ! 
    602                                 else 
    603                                         tokenDefs = _tokenDefs to ! 
     604                                tokenDefs = _getCandidateTokenDefs(_sourceLine) 
    604605                                for tokenDef in tokenDefs 
    605606                                        count += 1 
    606                                         if tokenDef.ignoreCount 
    607                                                 tokenDef.ignoreCount -= 1 
     607                                        if _skipMatchAttempt(tokenDef, _sourceLineIndex) 
    608608                                                continue 
    609                                         if not tokenDef.isActive 
    610                                                 continue 
    611                                         if _sourceLineIndex>0 and tokenDef.requiresBOL 
    612                                                 continue 
    613                                         if not .isActiveCall(tokenDef) 
    614                                                 continue 
    615609                                        #print '<> Trying to match [tokenDef]' 
    616610                                        sourceLine = _sourceLine to ! 
    617611                                        #print '_sourceLineIndex=[_sourceLineIndex]' 
     
    634628 
    635629                                        # enable methods to customize handling of tokens 
    636630                                        reinvoke = false 
    637  
    638                                         which = tok.which 
    639                                         if _onTokenTypeCache.containsKey(which) 
    640                                                 meth = _onTokenTypeCache[which] 
    641                                         else 
    642                                                 methName = 'On' + which 
    643                                                 meth = .getType.getMethod(methName) 
    644                                                 _onTokenTypeCache[which] = meth 
    645                                                  
     631                                        meth = _getTokenMethod(tok.which) 
    646632                                        if meth 
    647                                                 try 
    648                                                         tok = meth.invoke(this, @[tok]) to IToken? 
    649                                                 catch tie as TargetInvocationException 
    650                                                         throw tie.innerException 
    651                                                 if tok is nil 
    652                                                         # skip token, so go to the next one 
    653                                                         reinvoke = true 
    654                                                 else 
    655                                                         # TODO: could probably make this more efficient by axing the queue and just checking for nextToken in this method 
    656                                                         while tok 
    657                                                                 _tokenQueue.enqueue(tok) 
    658                                                                 tok = tok.nextToken 
    659                                                         reinvoke = true  # to pick up the queue 
     633                                                tok = _tokenPostProcess(meth, tok ) 
     634                                                # nil indicates skipped token - will re call this method 
     635                                                if not tok  
     636                                                        reinvoke = true  # to pick up next token after skipped 
    660637 
    661638                                        # finished with current line? 
    662639                                        if _sourceLine.length==0 
     
    689666                        _avgCount += count 
    690667                        _avgCountNum += 1 
    691668 
     669        def _getCandidateTokenDefs(sourceLine as String?) as List<of TokenDef> 
     670                if _narrowTokenDefs and _tokenDefs.count >= _minNumTokenDefsToNarrow 
     671                        assert _tokenDefsByFirstChar 
     672                        assert _sourceLine.length 
     673                        if _tokenDefsByFirstChar.containsKey(_sourceLine[0]) 
     674                                # print 'Using short list for char: [_sourceLine[0]], [_sourceLine[0] to int]' 
     675                                return _tokenDefsByFirstChar[_sourceLine[0]] 
     676                return _tokenDefs to ! 
     677 
     678        def _skipMatchAttempt(tokenDef as TokenDef, sourceLineIndex as int) as bool 
     679                if tokenDef.ignoreCount 
     680                        tokenDef.ignoreCount -= 1 
     681                        return true 
     682                if not tokenDef.isActive 
     683                        return true 
     684                if sourceLineIndex>0 and tokenDef.requiresBOL 
     685                        return true 
     686                if not .isActiveCall(tokenDef) 
     687                        return true 
     688                return false     
     689 
     690        def _getTokenMethod(which as String) as  MethodInfo?  
     691                """ 
     692                Get the method for token (On<which>) from cache if there else  
     693                reflect and cache it. 
     694                """      
     695                if not _onTokenTypeCache.containsKey(which) # not already in methods cache 
     696                        methName = 'On' + which                                  
     697                        meth = .getType.getMethod(methName)      
     698                        _onTokenTypeCache[which] = meth                  
     699                else 
     700                        meth = _onTokenTypeCache[which] 
     701                return meth 
     702                 
     703        def _tokenPostProcess(meth as MethodInfo,  tok as IToken?) as IToken? 
     704                """ 
     705                Invoke any tokenMethod and return adjusted token or first token in any provided 
     706                token chain (rest of chain queued). 
     707                nil token returned indicates token is skipped. 
     708                """ 
     709 
     710                try 
     711                        tok = meth.invoke(this, @[tok]) to IToken? 
     712                catch tie as TargetInvocationException 
     713                        throw tie.innerException 
     714                if not tok 
     715                        return nil      # token is to be skipped 
     716                retTok = tok 
     717                tok = tok.nextToken 
     718                while tok 
     719                # TODO: could probably make this more efficient by axing the queue and just checking for nextToken in this method 
     720                        _tokenQueue.enqueue(tok)  # store any token chain returned by method call 
     721                        tok = tok.nextToken 
     722                return retTok    
     723 
    692724        def pushTokenDefs(defs as List<of TokenDef>) 
    693725                ensure 
    694726                        _tokenDefs is defs