Ticket #36: nextToken-cleanup.patch

File nextToken-cleanup.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                #       avt = (duration.ticks to int) / (tokens.count to int) 
     450                #       ms = avt/10000 
     451                #       fnm = _fileName 
     452                #       if _fileName.startsWith("(") 
     453                #               fnm = '(None)' 
     454                #       lastsl =_fileName.lastIndexOf("\\") 
     455                #       if lastsl > 0 
     456                #               fnm = _fileName[lastsl+1:] to ! 
     457                #       print "[fnm.padRight(20)]\t[duration]\t[tokens.count]\t" stop 
     458                #       print " [ms:N3] ms/Token av ([ms/1000:N3]sec)" 
    445459                return tokens 
    446460 
    447461        def restart 
     
    591605                                        return nil 
    592606                        try 
    593607                                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 ! 
     608                                tokenDefs = _getCandidateTokenDefs(_sourceLine) 
    604609                                for tokenDef in tokenDefs 
    605610                                        count += 1 
    606                                         if tokenDef.ignoreCount 
    607                                                 tokenDef.ignoreCount -= 1 
     611                                        if _skipMatchAttempt(tokenDef, _sourceLineIndex) 
    608612                                                continue 
    609                                         if not tokenDef.isActive 
    610                                                 continue 
    611                                         if _sourceLineIndex>0 and tokenDef.requiresBOL 
    612                                                 continue 
    613                                         if not .isActiveCall(tokenDef) 
    614                                                 continue 
    615613                                        #print '<> Trying to match [tokenDef]' 
    616614                                        sourceLine = _sourceLine to ! 
    617615                                        #print '_sourceLineIndex=[_sourceLineIndex]' 
     
    634632 
    635633                                        # enable methods to customize handling of tokens 
    636634                                        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                                                  
     635                                        meth = _getTokenMethod(tok.which) 
    646636                                        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 
     637                                                tok = _tokenPostProcess(meth, tok ) 
     638                                                # nil indicates skipped token - will re call this method 
     639                                                if not tok  
     640                                                        reinvoke = true  # to pick up next token after skipped 
    660641 
    661642                                        # finished with current line? 
    662643                                        if _sourceLine.length==0 
     
    689670                        _avgCount += count 
    690671                        _avgCountNum += 1 
    691672 
     673        def _getCandidateTokenDefs(sourceLine as String?) as List<of TokenDef> 
     674                if _narrowTokenDefs and _tokenDefs.count >= _minNumTokenDefsToNarrow 
     675                        assert _tokenDefsByFirstChar 
     676                        assert _sourceLine.length 
     677                        if _tokenDefsByFirstChar.containsKey(_sourceLine[0]) 
     678                                # print 'Using short list for char: [_sourceLine[0]], [_sourceLine[0] to int]' 
     679                                return _tokenDefsByFirstChar[_sourceLine[0]] 
     680                return _tokenDefs to ! 
     681 
     682        def _skipMatchAttempt(tokenDef as TokenDef, sourceLineIndex as int) as bool 
     683                if tokenDef.ignoreCount 
     684                        tokenDef.ignoreCount -= 1 
     685                        return true 
     686                if not tokenDef.isActive 
     687                        return true 
     688                if sourceLineIndex>0 and tokenDef.requiresBOL 
     689                        return true 
     690                if not .isActiveCall(tokenDef) 
     691                        return true 
     692                return false     
     693 
     694        # get method for token (On<which>)  from cache if there else from reflection and cache it 
     695        def _getTokenMethod(which as String) as  MethodInfo?  
     696                if not _onTokenTypeCache.containsKey(which) # not already in methods cache 
     697                        methName = 'On' + which                                  
     698                        meth = .getType.getMethod(methName)      
     699                        _onTokenTypeCache[which] = meth                  
     700                else 
     701                        meth = _onTokenTypeCache[which] 
     702                return meth 
     703                 
     704        # invoke any tokenMethod and return adjusted token or first token in any returned 
     705        # token chain (rest of chain queued) 
     706        # nil token returned indicates token is skipped. 
     707        def _tokenPostProcess(meth as MethodInfo,  tok as IToken?) as IToken? 
     708                try 
     709                        tok = meth.invoke(this, @[tok]) to IToken? 
     710                catch tie as TargetInvocationException 
     711                        throw tie.innerException 
     712                if not tok 
     713                        return nil      # token is to be skipped 
     714                retTok = tok 
     715                tok = tok.nextToken 
     716                while tok 
     717                # TODO: could probably make this more efficient by axing the queue and just checking for nextToken in this method 
     718                        _tokenQueue.enqueue(tok)  # store any token chain returned by method call 
     719                        tok = tok.nextToken 
     720                return retTok    
     721 
    692722        def pushTokenDefs(defs as List<of TokenDef>) 
    693723                ensure 
    694724                        _tokenDefs is defs