//===-- Lexer.cpp ---------------------------------------------------------===// // // The KLEE Symbolic Virtual Machine // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "expr/Lexer.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include #include #include using namespace llvm; using namespace klee; using namespace klee::expr; /// const char *Token::getKindName() const { switch (kind) { default: case Unknown: return "Unknown"; case Arrow: return "Arrow"; case At: return "At"; case Colon: return "Colon"; case Comma: return "Comma"; case Comment: return "Comment"; case EndOfFile: return "EndOfFile"; case Equals: return "Equals"; case Identifier: return "Identifier"; case KWArray: return "KWArray"; case KWFalse: return "KWFalse"; case KWQuery: return "KWQuery"; case KWReserved: return "KWReserved"; case KWSymbolic: return "KWSymbolic"; case KWTrue: return "KWTrue"; case KWWidth: return "KWWidth"; case LBrace: return "LBrace"; case LParen: return "LParen"; case LSquare: return "LSquare"; case Number: return "Number"; case RBrace: return "RBrace"; case RParen: return "RParen"; case RSquare: return "RSquare"; case Semicolon: return "Semicolon"; } } void Token::dump() { llvm::errs() << "(Token \"" << getKindName() << "\" " << (void*) start << " " << length << " " << line << " " << column << ")"; } /// static inline bool isInternalIdentifierChar(int Char) { return isalnum(Char) || Char == '_' || Char == '.' || Char == '-'; } Lexer::Lexer(const llvm::MemoryBuffer *MB) : BufferPos(MB->getBufferStart()), BufferEnd(MB->getBufferEnd()), LineNumber(1), ColumnNumber(0) { } Lexer::~Lexer() { } int Lexer::PeekNextChar() { if (BufferPos == BufferEnd) return -1; return *BufferPos; } int Lexer::GetNextChar() { if (BufferPos == BufferEnd) return -1; // Handle DOS/Mac newlines here, by stripping duplicates and by // returning '\n' for both. char Result = *BufferPos++; if (Result == '\n' || Result == '\r') { if (BufferPos != BufferEnd && *BufferPos == ('\n' + '\r' - Result)) ++BufferPos; Result = '\n'; } if (Result == '\n') { ++LineNumber; ColumnNumber = 0; } else { ++ColumnNumber; } return Result; } Token &Lexer::SetTokenKind(Token &Result, Token::Kind k) { Result.kind = k; Result.length = BufferPos - Result.start; return Result; } static bool isReservedKW(const char *Str, unsigned N) { unsigned i; // Check for i[0-9]+ if (N>1 && Str[0] == 'i') { for (i=1; i3 && Str[0]=='f' && Str[1]=='p' && isdigit(Str[2])) { for (i=3; i') return GetNextChar(), SetTokenKind(Result, Token::Arrow); else if (isdigit(Next)) return LexNumber(Result); else return SetTokenKind(Result, Token::Unknown); break; } default: if (isdigit(Char)) return LexNumber(Result); else if (isalpha(Char) || Char == '_') return LexIdentifier(Result); return SetTokenKind(Result, Token::Unknown); } }