zcov: / lib/Expr/Lexer.cpp


Files: 1 Branches Taken: 87.1% 122 / 140
Generated: 2009-05-17 22:47 Branches Executed: 100.0% 140 / 140
Line Coverage: 93.2% 138 / 148


Programs: 3 Runs 1022


       1                 : //===- Lexer.cpp - --*- C++ -*-===//
       2                 : 
       3                 : #include "expr/Lexer.h"
       4                 : 
       5                 : #include "llvm/Support/MemoryBuffer.h"
       6                 : #include "llvm/Support/Streams.h"
       7                 : 
       8                 : #include <iomanip>
       9                 : #include <iostream>
      10                 : #include <string.h>
      11                 : 
      12                 : using namespace llvm;
      13                 : using namespace klee;
      14                 : using namespace klee::expr;
      15                 : 
      16                 : ///
      17                 : 
      18               65: const char *Token::getKindName() const {
                        0: branch 0 not taken
                        1: branch 1 taken
                        1: branch 2 taken
                        1: branch 3 taken
                        1: branch 4 taken
                       36: branch 5 taken
                        1: branch 6 taken
                        1: branch 7 taken
                        1: branch 8 taken
                        1: branch 9 taken
                        1: branch 10 taken
                        7: branch 11 taken
                        1: branch 12 taken
                        0: branch 13 not taken
                        1: branch 14 taken
                        1: branch 15 taken
                        1: branch 16 taken
                        5: branch 17 taken
                        1: branch 18 taken
                        1: branch 19 taken
                        1: branch 20 taken
                        1: branch 21 taken
      19               65:   switch (kind) {
      20                 :   default:
      21                0:   case Unknown:    return "Unknown";
      22                1:   case Arrow:      return "Arrow";
      23                1:   case At:         return "At";
      24                1:   case Colon:      return "Colon";
      25                1:   case Comma:      return "Comma";
      26               36:   case Comment:    return "Comment";
      27                1:   case EndOfFile:  return "EndOfFile";
      28                1:   case Equals:     return "Equals";
      29                1:   case Identifier: return "Identifier";
      30                1:   case KWFalse:    return "KWFalse";
      31                1:   case KWQuery:    return "KWQuery";
      32                7:   case KWReserved: return "KWReserved";
      33                1:   case KWTrue:     return "KWTrue";
      34                0:   case KWWidth:    return "KWWidth";
      35                1:   case LBrace:     return "LBrace";
      36                1:   case LParen:     return "LParen";
      37                1:   case LSquare:    return "LSquare";
      38                5:   case Number:     return "Number";
      39                1:   case RBrace:     return "RBrace";
      40                1:   case RParen:     return "RParen";
      41                1:   case RSquare:    return "RSquare";
      42                1:   case Semicolon:  return "Semicolon";
      43                 :   }
      44                 : }
      45                 : 
      46                0: void Token::dump() {
      47                 :   llvm::cerr << "(Token \"" << getKindName() << "\" "
      48                 :              << (void*) start << " " << length << " "
      49                0:              << line << " " << column << ")";
      50                0: }
      51                 : 
      52                 : ///
      53                 : 
      54                 : static inline bool isInternalIdentifierChar(int Char) {
                     1487: branch 1 taken
                     3881: branch 2 taken
                        1: branch 3 taken
                     1486: branch 4 taken
      55             5368:   return isalnum(Char) || Char == '_' || Char == '.';
      56                 : }
      57                 : 
      58                3: Lexer::Lexer(const llvm::MemoryBuffer *MB) 
      59                 :   : BufferPos(MB->getBufferStart()), BufferEnd(MB->getBufferEnd()), 
      60                6:     LineNumber(1), ColumnNumber(0) {
      61                3: }
      62                 : 
      63                3: Lexer::~Lexer() {
      64                3: }
      65                 : 
      66            22756: int Lexer::PeekNextChar() {
                        3: branch 0 taken
                    22753: branch 1 taken
      67            22756:   if (BufferPos == BufferEnd)
      68                3:     return -1;
      69            22753:   return *BufferPos;
      70                 : }
      71                 : 
      72            22915: int Lexer::GetNextChar() {
                        3: branch 0 taken
                    22912: branch 1 taken
      73            22915:   if (BufferPos == BufferEnd)
      74                3:     return -1;
      75                 : 
      76                 :   // Handle DOS/Mac newlines here, by stripping duplicates and by
      77                 :   // returning '\n' for both.
      78            22912:   char Result = *BufferPos++;
                      509: branch 0 taken
                    22403: branch 1 taken
      79            22912:   if (Result == '\n' || Result == '\r') {
                      506: branch 0 taken
                        3: branch 1 taken
                        0: branch 2 not taken
                      506: branch 3 taken
      80              509:     if (BufferPos != BufferEnd && *BufferPos == ('\n' + '\r' - Result))
      81                0:       ++BufferPos;
      82              509:     Result = '\n';
      83                 :   }
      84                 : 
                      509: branch 0 taken
                    22403: branch 1 taken
      85            22912:   if (Result == '\n') {
      86              509:     ++LineNumber;
      87              509:     ColumnNumber = 0;
      88                 :   } else {
      89            22403:     ++ColumnNumber;
      90                 :   }
      91                 : 
      92            22912:   return Result;
      93                 : }
      94                 : 
      95             4537: Token &Lexer::SetTokenKind(Token &Result, Token::Kind k) {
      96             4537:   Result.kind = k;
      97             4537:   Result.length = BufferPos - Result.start;
      98             4537:   return Result;
      99                 : }
     100                 : 
     101                 : static bool isReservedKW(const char *Str, unsigned N) {
     102                 :     unsigned i;
     103                 : 
     104                 :   // Check for i[0-9]+
                     1458: branch 0 taken
                        0: branch 1 not taken
                        1: branch 2 taken
                     1457: branch 3 taken
     105             1458:   if (N>1 && Str[0] == 'i') {
                        2: branch 0 taken
                        1: branch 1 taken
     106                3:     for (i=1; i<N; ++i)
                        2: branch 0 taken
                        0: branch 1 not taken
     107                2:       if (!isdigit(Str[i]))
     108                 :         break;
                        1: branch 0 taken
                        0: branch 1 not taken
     109                1:     if (i==N)
     110                1:       return true;
     111                 :   }
     112                 : 
     113                 :   // Check for fp[0-9]+([.].*)?$
                      567: branch 0 taken
                      890: branch 1 taken
                        1: branch 2 taken
                      566: branch 3 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
     114             1457:   if (N>3 && Str[0]=='f' && Str[1]=='p' && isdigit(Str[2])) {
                        2: branch 0 taken
                        0: branch 1 not taken
     115                2:     for (i=3; i<N; ++i)
                        1: branch 0 taken
                        1: branch 1 taken
     116                2:       if (!isdigit(Str[i]))
     117                 :         break;
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 3 not taken
     118                1:     if (i==N || Str[i]=='.')
     119                1:       return true;
     120                 :   }
     121                 :   
     122             1456:   return false;
     123                 : }
     124                 : static bool isWidthKW(const char *Str, unsigned N) {
                     1456: branch 0 taken
                        0: branch 1 not taken
                     1011: branch 2 taken
                      445: branch 3 taken
     125             1456:   if (N<2 || Str[0] != 'w')
     126             1011:     return false;
                      702: branch 0 taken
                      445: branch 1 taken
     127             1147:   for (unsigned i=1; i<N; ++i)
                        0: branch 0 not taken
                      702: branch 1 taken
     128              702:     if (!isdigit(Str[i]))
     129                0:       return false;
     130              445:   return true;
     131                 : }
     132             1486: Token &Lexer::SetIdentifierTokenKind(Token &Result) {
     133             1486:   unsigned Length = BufferPos - Result.start;
                      443: branch 0 taken
                      160: branch 1 taken
                      199: branch 2 taken
                      139: branch 3 taken
                       94: branch 4 taken
                      451: branch 5 taken
     134             1486:   switch (Length) {
     135                 :   case 3:
                        1: branch 1 taken
                      442: branch 2 taken
     136              443:     if (memcmp("def", Result.start, 3) == 0)
     137                1:       return SetTokenKind(Result, Token::KWReserved);
                        1: branch 1 taken
                      441: branch 2 taken
     138              442:     if (memcmp("var", Result.start, 3) == 0)
     139                1:       return SetTokenKind(Result, Token::KWReserved);
     140                 :     break;
     141                 : 
     142                 :   case 4:
                        1: branch 1 taken
                      159: branch 2 taken
     143              160:     if (memcmp("true", Result.start, 4) == 0)
     144                1:       return SetTokenKind(Result, Token::KWTrue);
     145                 :     break;
     146                 : 
     147                 :   case 5:
                        1: branch 1 taken
                      198: branch 2 taken
     148              199:     if (memcmp("array", Result.start, 5) == 0)
     149                1:       return SetTokenKind(Result, Token::KWReserved);
                        3: branch 1 taken
                      195: branch 2 taken
     150              198:     if (memcmp("false", Result.start, 5) == 0)
     151                3:       return SetTokenKind(Result, Token::KWFalse);
                       19: branch 1 taken
                      176: branch 2 taken
     152              195:     if (memcmp("query", Result.start, 5) == 0)
     153               19:       return SetTokenKind(Result, Token::KWQuery);
     154                 :     break;      
     155                 :     
     156                 :   case 6:
                        1: branch 1 taken
                      138: branch 2 taken
     157              139:     if (memcmp("define", Result.start, 6) == 0)
     158                1:       return SetTokenKind(Result, Token::KWReserved);
     159                 :     break;
     160                 : 
     161                 :   case 7:
                        1: branch 1 taken
                       93: branch 2 taken
     162               94:     if (memcmp("declare", Result.start, 7) == 0)
     163                1:       return SetTokenKind(Result, Token::KWReserved);
     164                 :     break;
     165                 :   }
     166                 : 
                        2: branch 0 taken
                     1456: branch 1 taken
     167             2916:   if (isReservedKW(Result.start, Length))
     168                2:     return SetTokenKind(Result, Token::KWReserved);
                      445: branch 0 taken
                     1011: branch 1 taken
     169             2912:   if (isWidthKW(Result.start, Length))
     170              445:     return SetTokenKind(Result, Token::KWWidth);
     171                 : 
     172             1011:   return SetTokenKind(Result, Token::Identifier);
     173                 : }
     174                 : 
     175             3497: void Lexer::SkipToEndOfLine() {
     176                 :   for (;;) {
     177             3497:     int Char = GetNextChar();
                     3402: branch 0 taken
                       95: branch 1 taken
     178             3497:     if (Char == -1 || Char =='\n')
     179               95:       break;
     180                 :   }
     181               95: }
     182                 : 
     183              924: Token &Lexer::LexNumber(Token &Result) {
                      926: branch 2 taken
                      424: branch 3 taken
                        2: branch 5 taken
                      924: branch 6 taken
                      426: branch 7 taken
                      924: branch 8 taken
     184             2274:   while (isalnum(PeekNextChar()) || PeekNextChar()=='_')
     185              426:     GetNextChar();
     186              924:   return SetTokenKind(Result, Token::Number);
     187                 : }
     188                 : 
     189             1486: Token &Lexer::LexIdentifier(Token &Result) {
                     3882: branch 1 taken
                     1486: branch 2 taken
     190            12222:   while (isInternalIdentifierChar(PeekNextChar()))
     191             3882:     GetNextChar();
     192                 : 
     193                 :   // Recognize keywords specially.
     194             1486:   return SetIdentifierTokenKind(Result);
     195                 : }
     196                 : 
     197             4537: Token &Lexer::Lex(Token &Result) {
     198             4537:   Result.kind = Token::Unknown;
     199             4537:   Result.length = 0;
     200             4537:   Result.start = BufferPos;
     201                 :   
     202                 :   // Skip whitespace.
                    10572: branch 2 taken
                     4537: branch 3 taken
     203            19646:   while (isspace(PeekNextChar()))
     204            10572:     GetNextChar();
     205                 : 
     206             4537:   Result.start = BufferPos;
     207             4537:   Result.line = LineNumber;
     208             4537:   Result.column = ColumnNumber;
     209             4537:   int Char = GetNextChar();
                        3: branch 0 taken
                      648: branch 1 taken
                      648: branch 2 taken
                      288: branch 3 taken
                       66: branch 4 taken
                        1: branch 5 taken
                      301: branch 6 taken
                       10: branch 7 taken
                       32: branch 8 taken
                       32: branch 9 taken
                        1: branch 10 taken
                        1: branch 11 taken
                       95: branch 12 taken
                        1: branch 13 taken
                        2: branch 14 taken
                     2408: branch 15 taken
     210             4537:   switch (Char) {
     211                3:   case -1:  return SetTokenKind(Result, Token::EndOfFile);
     212                 :     
     213              648:   case '(': return SetTokenKind(Result, Token::LParen);
     214              648:   case ')': return SetTokenKind(Result, Token::RParen);
     215              288:   case ',': return SetTokenKind(Result, Token::Comma);
     216               66:   case ':': return SetTokenKind(Result, Token::Colon);
     217                1:   case ';': return SetTokenKind(Result, Token::Semicolon);
     218              301:   case '=': return SetTokenKind(Result, Token::Equals);
     219               10:   case '@': return SetTokenKind(Result, Token::At);
     220               32:   case '[': return SetTokenKind(Result, Token::LSquare);
     221               32:   case ']': return SetTokenKind(Result, Token::RSquare);
     222                1:   case '{': return SetTokenKind(Result, Token::LBrace);
     223                1:   case '}': return SetTokenKind(Result, Token::RBrace);
     224                 : 
     225                 :   case '#':
     226               95:     SkipToEndOfLine();
     227               95:     return SetTokenKind(Result, Token::Comment);
     228                 : 
     229                 :   case '+': {
                        1: branch 1 taken
                        0: branch 2 not taken
     230                1:     if (isdigit(PeekNextChar()))
     231                1:       return LexNumber(Result);
     232                 :     else
     233                0:       return SetTokenKind(Result, Token::Unknown);
     234                 :   }
     235                 : 
     236                 :   case '-': {
     237                2:     int Next = PeekNextChar();
                        1: branch 0 taken
                        1: branch 1 taken
     238                2:     if (Next == '>')
     239                1:       return GetNextChar(), SetTokenKind(Result, Token::Arrow);
                        1: branch 0 taken
                        0: branch 1 not taken
     240                1:     else if (isdigit(Next))
     241                1:       return LexNumber(Result);
     242                 :     else
     243                0:       return SetTokenKind(Result, Token::Unknown);
     244                 :     break;
     245                 :   }
     246                 : 
     247                 :   default:
                      922: branch 0 taken
                     1486: branch 1 taken
     248             2408:     if (isdigit(Char))
     249              922:       return LexNumber(Result);
                     1486: branch 1 taken
                        0: branch 2 not taken
     250             1486:     else if (isalpha(Char) || Char == '_')
     251             1486:       return LexIdentifier(Result);
     252                0:     return SetTokenKind(Result, Token::Unknown);
     253                 :   }
                        5: branch 0 taken
                        0: branch 1 not taken
                        5: branch 2 taken
                        0: branch 3 not taken
     254               10: }

Generated: 2009-05-17 22:47 by zcov