存档
How to write a lexer?
手头已经有的code里面,除了ucc,还真没有那个编译器是手写lexer的,或许是太简单了。(对了, 好像还有lcc).
不过简单有简单的好处,lexer这种东西毕竟是通用的,不限于compiler,而且手写一个也很能锻炼一下coding能力。
ucc是这样实现的:
- 创建一个包含256个函数指针的数组,针对letter,digital和其他的token进行区分,比如所有的letter都是一个处理函数,ditigal是一个,其他的特殊token分别有一个,比如*, – 等;
- 每次读进一个byte,这个byte的范围是0~255;
- 根据value选择相应的处理函数, 得到具体的返回值;
- 最常见的情况之一是各种letter, 分几种情况处理:
- ‘L’打头, 那么后面很可能是这样: L’a’ 或者 L”hello world\n”, 要判断一下后一个字符是不是’或者”, 是的话按照char或者string处理(char和string的处理还挺麻烦, 后面再讲);
- 继续向后吃掉所有的letter或者digit;
- 然后就得到一个identifier了, 先去keyword表里查一下, 看是不是keyword. 这里用了hash表, 按照keyword的首字母排序;
- 去symbol里面查一下, 看是否已经有同名的id存在, 如果有的话, 就将已经保存下来的id地址返回; 否则就新allocate一段内存, 然后返回新的内存的指针;
- 最常见的情况之二是digit, 也分几种情况处理:
- 首先说明一下, ‘-’的处理是不包含在这里面的, 因为有二义性, 而且需要前溯好几步, 放在语法解析比较好, 比如a – 1 和a = -1 你就不好在词法解析这个级别做, 所以lexer只是把minus这个结果返回就可以了;
- 然后要考虑浮点数, 包括.和e这些, 还有0x和0X这样的十六进制数, 077这样的八进制数;
- 不过有一个疑问, 如果一开始就处理’.', 像10.444这样的数怎么处理?
- 后面是一些token的处理:
- ‘\’, 后面跟的一般是转义符, 作为char处理;
- ‘”‘, 后面跟的是字符串, 作为string处理;
- ‘+’, 分三种情况:++, +=, + ;
- ‘-’, 分四种情况:–, -=, ->, – ;
- ‘*’, 分两种情况:*=, * ;
- ‘/’, 分两种情况:/=, / ;
- ‘%’, 分两种情况:%=, % ;
- ‘<’, 分四种情况:<<, <<=, <=, <;
- ‘>’, 分四种情况:>>, >>=, >=, >;
- ‘!’, 分两种情况:!=, !;
- ‘=’, 分两种情况:==, =;
- ‘|’, 分三种情况:||, |=, |;
- ‘&’, 分三种情况:&&, &=, &;
- ‘^’, 分两种情况:^=, ^;
- ‘.’, 分三种情况:
- ‘.’后面跟着数字, 则作为float处理;
- “…”连在一起, 作为ellipse处理;
- 单独的’.';
- 其余所有的token都直接返回对应的值.
所以主要的难度在于数字的处理和identifer table的管理上.
GCC学习笔记—demystifying gcc
在网上搜gcc frontend时偶然发现了这份ppt,绝对是gcc入门的最佳资料,强烈推荐。
主要讲了关于build/debug,front-end,middle-end,back-end,包括c,c++和java.
原文出处在这里:
http://www.cs.wustl.edu/~mdeters/oopsla2006/
本地下载地址(pdf):
http://veryzhang.cn/wp-content/uploads/2009/04/demystifying-gcc.pdf
上面这个是2006年的presentation,有点老了,而且附带的源代码也找不到了,后来给作者发了封邮件,这位大哥给了新的地址:
Hi Xuecheng,
I’ve looked and I can’t find these code examples either at the moment.
If I find them, I’ll let you know. There are also some more recent
tutorial slides here:http://www.cs.wustl.edu/~mdeters/pldi2008/
And additional resources (slightly older) here:
http://www.cs.wustl.edu/~mdeters/seminar/fall2005/
that give some information about GCC. Note that the Java front-end
has changed significantly since the 2005 and 2006 courses (in case
you’re looking at the source for a recent GCC compiler). Other parts
have changed a lot too.One of the code resources listed for the 2006 course was of jRate, a
real-time Java implementation, based on GCC’s (ahead-of-time-compiled)
Java implementation, that makes modifications to the GCJ compiler and
the libraries, and also a little to the GCC C++ compiler. The source
modifications of jRate to GCC are open-source, available through
SourceForge:Take care, and happy hacking!
Morgan
lex和yacc学习笔记
1.标准的c语法和词法范式只有输出token功能;
2.lex传递给yyac的是token的索引,需要在lex中自己实现一个符号表管理机制,把token的名称记录下来;
3.treelang是在lex中通过get_string函数来获取token的名称,并且由gcc统一管理;
4.每次遇到一个token,treelang都会创建一个新的tok结构体,将这个token赋值到tok结构体中;每一个token都有对应的tok结构体;
5.treelang_parse_file会调用yyparse,然后yyparse会调用yylex;
6.lex文件第二个%%段开始默认就是yylex吗?
7.先执行token识别过程,再执行yylex;实际运行过程是,在token识别之前,先调用YY_RULE_SETUP,这个宏最终的实际定义是YY_DECL,就是yylex;太乱了!
8.yylex被my_yylex调用,my_yylex有被定义成宏YYLEX,YYLEX被yyparse调用;

最新评论