深入研究Clang(七) Clang Lexer代码阅读笔记之Lexer

简介: 作者:史宁宁(snsn1984)源码位置:clang/lib/Lexer.cpp源码网络地址:http://clang.llvm.org/doxygen/Lexer_8cpp_source.htmlLexer.cpp这个文件,是Clang这个前端的词法分析器的主要文件,它的内容是对Lexer这个类的具体实现,原文件的注释中:“This file implements the Lexer and Token interfaces.” 这么解释这个文件的,但是Token只有两个简单函数的实现,剩下的都是Lexer的实现。

作者:史宁宁(snsn1984)

源码位置:clang/lib/Lexer.cpp

源码网络地址:http://clang.llvm.org/doxygen/Lexer_8cpp_source.html


Lexer.cpp这个文件,是Clang这个前端的词法分析器的主要文件,它的内容是对Lexer这个类的具体实现,原文件的注释中:“This file implements the Lexer and Token interfaces.” 这么解释这个文件的,但是Token只有两个简单函数的实现,剩下的都是Lexer的实现。所以要想搞清楚Clang的词法分析器是怎么实现的,那么必须对这个文件有着深入的理解。


从Lexer的初始化函数开始入手:

void Lexer::InitLexer(const char *BufStart, const char *BufPtr,
   56                       const char *BufEnd) {
   57   BufferStart = BufStart;
   58   BufferPtr = BufPtr;
   59   BufferEnd = BufEnd;
   60 
   61   assert(BufEnd[0] == 0 &&
   62          "We assume that the input buffer has a null character at the end"
   63          " to simplify lexing!");
   64 
   65   // Check whether we have a BOM in the beginning of the buffer. If yes - act
   66   // accordingly. Right now we support only UTF-8 with and without BOM, so, just
   67   // skip the UTF-8 BOM if it's present.
   68   if (BufferStart == BufferPtr) {
   69     // Determine the size of the BOM.
   70     StringRef Buf(BufferStart, BufferEnd - BufferStart);
   71     size_t BOMLength = llvm::StringSwitch<size_t>(Buf)
   72       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
   73       .Default(0);
   74 
   75     // Skip the BOM.
   76     BufferPtr += BOMLength;
   77   }
   78 
   79   Is_PragmaLexer = false;
   80   CurrentConflictMarkerState = CMK_None;
   81 
   82   // Start of the file is a start of line.
   83   IsAtStartOfLine = true;
   84   IsAtPhysicalStartOfLine = true;
   85 
   86   HasLeadingSpace = false;
   87   HasLeadingEmptyMacro = false;
   88 
   89   // We are not after parsing a #.
   90   ParsingPreprocessorDirective = false;
   91 
   92   // We are not after parsing #include.
   93   ParsingFilename = false;
   94 
   95   // We are not in raw mode.  Raw mode disables diagnostics and interpretation
   96   // of tokens (e.g. identifiers, thus disabling macro expansion).  It is used
   97   // to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
   98   // or otherwise skipping over tokens.
   99   LexingRawMode = false;
  100 
  101   // Default to not keeping comments.
  102   ExtendedTokenMode = 0;
  103 }

这个初始化函数,是在Lexer类的两个构造函数里被调用的,具体代码如下:


  104 
  105 /// Lexer constructor - Create a new lexer object for the specified buffer
  106 /// with the specified preprocessor managing the lexing process.  This lexer
  107 /// assumes that the associated file buffer and Preprocessor objects will
  108 /// outlive it, so it doesn't take ownership of either of them.
  109 Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *InputFile, Preprocessor &PP)
  110   : PreprocessorLexer(&PP, FID),
  111     FileLoc(PP.getSourceManager().getLocForStartOfFile(FID)),
  112     LangOpts(PP.getLangOpts()) {
  113 
  114   InitLexer(InputFile->getBufferStart(), InputFile->getBufferStart(),
  115             InputFile->getBufferEnd());
  116 
  117   resetExtendedTokenMode();
  118 }
  119 
  120 void Lexer::resetExtendedTokenMode() {
  121   assert(PP && "Cannot reset token mode without a preprocessor");
  122   if (LangOpts.TraditionalCPP)
  123     SetKeepWhitespaceMode(true);
  124   else
  125     SetCommentRetentionState(PP->getCommentRetentionState());
  126 }
  127 
  128 /// Lexer constructor - Create a new raw lexer object.  This object is only
  129 /// suitable for calls to 'LexFromRawLexer'.  This lexer assumes that the text
  130 /// range will outlive it, so it doesn't take ownership of it.
  131 Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
  132              const char *BufStart, const char *BufPtr, const char *BufEnd)
  133   : FileLoc(fileloc), LangOpts(langOpts) {
  134 
  135   InitLexer(BufStart, BufPtr, BufEnd);
  136 
  137   // We *are* in raw mode.
  138   LexingRawMode = true;
  139 }

这两个构造函数各有不同,从输入参数上就可以看出。也有相同的地方,就是对一些参数只是引用的关系,并没有获取这些参数的所有权。


Lexer的构造函数,在自己的类内部,分别被以下的函数所调用:

Create_PragmaLexer: Lexer constructor - Create a new lexer object for _Pragma expansion.
http://clang.llvm.org/doxygen/classclang_1_1Lexer.html#ac7f3b1ce4f2eeaec8d787d22bf197cd0


getSpelling - This method is used to get the spelling of a token into a preallocated buffer, instead of as an std::string.

http://clang.llvm.org/doxygen/classclang_1_1Lexer.html#a94f2c5710332ae19d7955c609ac37adb


getRawToken

http://clang.llvm.org/doxygen/classclang_1_1Lexer.html#adac8b8cf001621ec3b109d82a7074f05


 getBeginningOfFileToken

http://clang.llvm.org/doxygen/Lexer_8cpp.html#a4845396d18432c436e605303b057dbb4


findLocationAfterToken

http://clang.llvm.org/doxygen/classclang_1_1Lexer.html#a099b99b2d19ef5cdd8fcb80d8cf4064e



目录
相关文章
|
前端开发 C语言 iOS开发
基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了
跟学院派的厚书给大家的印象不同,其实用LLVM写个简单的编译器是件容易的事情,因为大部分事情LLVM都替我们做了。
8189 0
|
前端开发 IDE 编译器
LLVM编译器前端 Clang 简介
昨天晚上安装rails的开发环境,被ruby的编译搞的有点崩溃。下载的ruby的源码不能用系统自带的gcc -4.21编译,也不能用系统自带的clang进行编译,必须下载并使用gcc -4.2进行编译才能通过。今天稍微看看编译器的一些背景。
489 0
LLVM编译器前端 Clang 简介
|
编译器 iOS开发 Windows
带你读《LLVM编译器实战教程》之一:构建和安装LLVM
本书的前半部分将向您介绍怎么样去配置、构建、和安装LLVM的不同软件库、工具和外部项目。接下来,本书的后半部分将向您介绍LLVM的各种设计细节,并逐步地讲解LLVM的各个编译步骤:前段、中间表示(IR)、后端、即时编译(JIT)引擎、跨平台编译和插件接口。本书包含有大量翔实的示例和代码片段,以帮助读者平稳顺利的掌握LLVM的编译器开发环境。
19400 0
|
C++ iOS开发 小程序
深入研究Clang(十) Clang Static Analyzer简介
Clang Static Analyzer 官网地址:http://clang-analyzer.llvm.org/ Clang Static Analyer是一个源码分析工具,它可以发现C、C++和Objective-C程序中的bug。
2228 0
|
Unix
深入研究Clang(九) Clang代码阅读之打log读流程2
继续上一篇,同样的hello.c,同样的执行过程,只不过继续添加了一些log信息,而且对代码进行了更近一步的挖掘。先看输入和输出的log信息(前半部分): shining@shining-VirtualBox:~/llvm-3.
1417 0
深入研究Clang(八) Clang代码阅读之打log读流程1
这个过程简单的分为几步。 第一步:写一个简单的小程序,hello.c。内容如下: #includeint main() {  printf("Hello world!\n");} 第二步:找出如何在LLVM里面输出信息,最后选择采用llvm::errs(),等于采用了LLVM的错误机制。
1187 0
|
前端开发 C语言 C++
LLVM和Clang背后的故事
LLVM是Apple官方支持的编译器,而该编译器的前端是Clang,这两个工具都被集成到了Xcode里面。
1712 0
|
Android开发 C语言 C++
《深入理解LLVM》第一章 LLVM简介
第一章 LLVM简介 作者:史宁宁 1.1 LLVM是什么 LLVM是什么?这是一个虽然基础,但是也曾经让很多新入门的人迷惑的一个问题。从字面上来讲,LLVM(Low Level Virtual Machine)是一个底层虚拟机,LLVM曾经有一部分功能对虚拟机有所帮助。
2421 0

热门文章

最新文章