Clang的Lexer(词法分析器)的源代码的主要位置例如以下:

clang/lib/Lex    这里是基本的Lexer的代码;

clang/include/clang/Lex   这里是Lexer的头文件代码的位置;

同一时候,Lexer还使用了clangBasic库,所以要分析Lexer的代码,clangBasic(clang/lib/Basic)的一些代码也会用到。

首先从Lexer入手。

clang/include/clang/Lex/Lexer.h

clang::Lexer:

00057   //===--------------------------------------------------------------------===//
00058 // Context-specific lexing flags set by the preprocessor.
00059 //
00060
00061 /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace
00062 /// and return them as tokens. This is used for -C and -CC modes, and
00063 /// whitespace preservation can be useful for some clients that want to lex
00064 /// the file in raw mode and get every character from the file.
00065 ///
00066 /// When this is set to 2 it returns comments and whitespace. When set to 1
00067 /// it returns comments, when it is set to 0 it returns normal tokens only.
00068 unsigned char ExtendedTokenMode;
00069
00070 //===--------------------------------------------------------------------===//

这个成员变量保存词法分析的一个状态,依据它的值的不同:0、1、2,分别相应仅仅返回正常的token。返回comments
和正常的token。返回空格、comments和正常的token。

以下是几个操作这个成员变量的函数。基本上都是获取值、设置值和重设值。

代码不复杂,

00162   /// isKeepWhitespaceMode - Return true if the lexer should return tokens for
00163 /// every character in the file, including whitespace and comments. This
00164 /// should only be used in raw mode, as the preprocessor is not prepared to
00165 /// deal with the excess tokens.
00166 bool isKeepWhitespaceMode() const {
00167 return ExtendedTokenMode > 1;
00168 }
00169
00170 /// SetKeepWhitespaceMode - This method lets clients enable or disable
00171 /// whitespace retention mode.
00172 void SetKeepWhitespaceMode(bool Val) {
00173 assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
00174 "Can only retain whitespace in raw mode or -traditional-cpp");
00175 ExtendedTokenMode = Val ? 2 : 0;
00176 }
00177
00178 /// inKeepCommentMode - Return true if the lexer should return comments as
00179 /// tokens.
00180 bool inKeepCommentMode() const {
00181 return ExtendedTokenMode > 0;
00182 }
00183
00184 /// SetCommentRetentionMode - Change the comment retention mode of the lexer
00185 /// to the specified mode. This is really only useful when lexing in raw
00186 /// mode, because otherwise the lexer needs to manage this.
00187 void SetCommentRetentionState(bool Mode) {
00188 assert(!isKeepWhitespaceMode() &&
00189 "Can't play with comment retention state when retaining whitespace");
00190 ExtendedTokenMode = Mode ? 1 : 0;
00191 }
00192
00193 /// Sets the extended token mode back to its initial value, according to the
00194 /// language options and preprocessor. This controls whether the lexer
00195 /// produces comment and whitespace tokens.
00196 ///
00197 /// This requires the lexer to have an associated preprocessor. A standalone
00198 /// lexer has nothing to reset to.
00199 void resetExtendedTokenMode();

关于raw mode:
raw mode的时候。ExtendedTokenMode = 2,Lexer会输出包括空格、comments和正常tokens在内的全部
字符。在Lexer的父类:clang::PreprocessorLexer类中(),有一个成员变量:

00049   /// \brief True if in raw mode.
00050 ///
00051 /// Raw mode disables interpretation of tokens and is a far faster mode to
00052 /// lex in than non-raw-mode. This flag:
00053 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
00054 /// 2. Identifier information is not looked up for identifier tokens. As an
00055 /// effect of this, implicit macro expansion is naturally disabled.
00056 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
00057 /// implicitly transformed by the lexer.
00058 /// 4. All diagnostic messages are disabled.
00059 /// 5. No callbacks are made into the preprocessor.
00060 ///
00061 /// Note that in raw mode that the PP pointer may be null.
00062 bool LexingRawMode;

它能够表明Lexer是否在raw mode下。同一时候,这里的凝视也说明了raw model的作用。

从clang::Lexer的定义能够看出,它是clang::PreprocessorLexer的子类,上面raw model的部分也引用了clang::PreprocessorLexer类的代码,以下看下clang::PreprocessorLexer的代码。

clang/include/clang/Lex/PreprocessorLexer.h

00022 namespace clang {
00023
00024 class FileEntry;
00025 class Preprocessor;

从这里能够看出clang::PreprocessorLexer使用了上面两个类,而在头文件里的详细位置就是:

00027 class PreprocessorLexer {
00028 virtual void anchor();
00029 protected:
00030 Preprocessor *PP; // Preprocessor object controlling lexing.

以及

00164   /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
00165 /// getFileID(), this only works for lexers with attached preprocessors.
00166 const FileEntry *getFileEntry() const;

从代码中能够看出。这两个类,一个是作为成员变量。一个是作为了一个成员函数的返回类型来使用的。我们跟踪代码去看下这两个类的详细实现。这两个类的详细实现。FileEntry较为简单。非常easy看出究竟内容。而Preprocessor类较为复杂,牵涉内容较多,在这里暂且不作分析。兴许继续分析。

深入研究Clang(五) Clang Lexer代码阅读笔记之Lexer的更多相关文章

  1. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  2. Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  3. [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  4. Linux-3.0.8 input subsystem代码阅读笔记

    先乱序记录一下阅读Linux input subsystem代码的笔记. 在input device driver的入口代码部分,需要分配并初始化input device结构,内核提供的API是inp ...

  5. Typecho 代码阅读笔记(二) - 数据库访问

    转载请注明出处:http://blog.csdn.net/jh_zzz 这一块比较复杂,我还没有完全理解为什么要把 SQL 语句的组装搞这么复杂. 从一个普通皮肤页面开始 themes/default ...

  6. <<梦断代码>>阅读笔记三

    看完了这最后三分之一的<梦断代码>,意味着这本软件行业的著作已经被我粗略地过了一遍. 在这最后三分之一的内容中,我深入了解了在大型软件项目的运作过程中存在的困难和艰辛.一个大型软件项目的成 ...

  7. Typecho 代码阅读笔记(三) - 插件机制

    转载请注明出处:http://blog.csdn.net/jh_zzz 以 index.php 为例: /** 初始化组件 */ Typecho_Widget:: widget('Widget_Ini ...

  8. Typecho 代码阅读笔记(一) - 页面渲染及路由机制

    转载请注明出处:http://blog.csdn.net/jh_zzz 从 index.php 开始看, /** 初始化组件 */ Typecho_Widget:: widget('Widget_In ...

  9. cocos2d-x代码阅读笔记 - 入口

    每一个C\C++程序都有一个非常有名的入口函数 main(),在Windows系统下,这个函数就变成了WinMain函数. 在cocos2d-x 2.0.4的Windows版本中,main函数非常简单 ...

随机推荐

  1. linux下C++的多线程编程

    1. 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(proces ...

  2. cocos2d中的anchorPoint属性详解

    原文地址:http://www.tuicool.com/articles/ANVjMj 1> anchorPoint对position的影响 anchorPoint的作用就是相当于确定在子节点的 ...

  3. Luogu 2216 [HAOI2007]理想的正方形 (单调队列优化)

    题意: 给出一个 N×M 的矩阵,以及一个数值 K ,求在给定的矩阵中取出一个 K×K 的矩阵其中最大值减去最小值的最小值. 细节: 没有细节来发暴力走天下,20分也是分啊~~~ QAQ. 分析: 感 ...

  4. pycharm的一些操作指令和技巧

    Alt+Enter 自动添加包Ctrl+t SVN更新Ctrl+k SVN提交Ctrl + / 注释(取消注释)选择的行Ctrl+Shift+F 高级查找Ctrl+Enter 补全Shift + En ...

  5. 在xcode上把你的app多语言国际化(NSLocalizedString)

    1.到project->info->localizations   下面的加号,添加你需要的语言 千万不要删除  base 否虽然我不知道有什么用,我是删了整个storyboard没了,很 ...

  6. php删除

    <?php$id = $_GET['id'];$db= new Mysqli("localhost","root","root",&q ...

  7. mysql的row_number()实现

    在mysql中没有row_number()方法,这里模拟row_number()实现: 如有表 studentid   name age   class1 张1 15     12 张2 15     ...

  8. 【bzoj2901】矩阵求和 前缀和

    题目描述 给出两个n*n的矩阵,m次询问它们的积中给定子矩阵的数值和. 输入 第一行两个正整数n,m. 接下来n行,每行n个非负整数,表示第一个矩阵. 接下来n行,每行n个非负整数,表示第二个矩阵. ...

  9. KS求有向图强连通分量模板

    #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; ; *maxn; struct no ...

  10. python简易爬虫,帮助理解re模块

    20161203更新: 1.使用了BS4解析html 2.使用了mysql-connector插入了数据库表 pip install mysql-connector import urllib.req ...