第一个作业是写一个词法分析的rule,词法分析对我帮助不大,主要是理解使用就可以,就大部分参照github上的实现了。
实验需要注意的内容:
1)cool/include/PA2/cool-parse.h 里面定义了需要处理的关键字
/* Tokens. */
#define CLASS 258
#define ELSE 259
#define FI 260
#define IF 261
#define IN 262
#define INHERITS 263
....
- 实验的主要内容是在cool.flex中增加对关键字,注释,嵌入注释,字符串的处理。在cool.flex内部定义好规则时候,make flexer 时,会调用flex. flex 输入cool.flex, 输出cool-lex.cc,这个就是flex自动产生的处理词法的代码。
3)产生flex后,可以调用perl pa1-grading.pl,打分会报告哪些没有处理好
4)没有处理好的
对于这种,可以直接grep “line number test 2”,查看时那个文件没有处理好。./grading 目录下有一堆输入文件
可以直接调用 ./lexer ./gool.cool 或者出错的文件 ./lexer ./lineno2.cool
它会根据我们输入的规则,print信息。
我的问题是注释里面遇到换行,没有增加lineno,在comment里面加上对了。
上面是环境的问题,下面是除了课程的资料以外需要的了解的内容,遇到的问题我就直接问chatgpt了。
1)Flex支持的函数:
yymore(): As mentioned earlier, this function is used to accumulate text from multiple rule matches before taking action. It’s particularly useful when you want to combine consecutive matches into a single token.
yytext: As discussed before, this global variable holds the current matched text or lexeme. It’s automatically populated by Flex based on the pattern that matches.
yylineno: This global variable keeps track of the current line number being processed by the lexer. You can use it to maintain accurate line number information for error reporting or other purposes.
These are some of the key functions and features that you’ll encounter while using Flex to build lexical analyzers. Remember that Flex provides a set of tools and features to make it easier to write lexical rules and integrate the lexer into your larger compiler or parsing system.
我列出了主要用的,主要用的还是yymore(),用来继续处理token的内容; 另一个就是yytext 则是表示当前匹配的内容。这里主要是讲数字,字符串以及自定义的object与符号表中的内容连接起来。
2) 如何编写cool.flex
对于关键字的支持比较简单,主要还是支持字符串和注释,以及嵌套注释。
这里就是状态机,初始时和正常状态下都处于INITIAL状态,cool语言时的注释以"( *" 开头,考虑到会存在嵌套注释,因此在INITIAL,COMMENTS,INLINE_COMMENTS三种状态下,都可能会遇到 "( * " 此时我们进入COMMENTS状态,因此BEGIN COMMENTS。
<INITIAL,COMMENTS,INLINE_COMMENTS>"(*" {
comment_layer++;
BEGIN COMMENTS;
}
在注释中,遇到非特殊字符,不需要特殊处理,可以直接忽视,因此{}内部都为空。
<COMMENT>[^\n(*]* { }
<COMMENT>[()*] { }
在遇到换行符时,增加行数计数。
<COMMENT>\n {
curr_lineno++;
}
这里的comment_layer–与上面的comment_layer++对应,进入comment时递增,出comment递减,主要是为了应对嵌套注释。在走到最外层时,回到INITIAL状态。
<COMMENT>"*)" {
comment_layer--;
if (comment_layer == 0) {
BEGIN INITIAL;
}
}
github路径:https://github.com/hitqshao/stanford-compilers-coursework.git
这个仓库我fork了https://github.com/gboduljak/stanford-compilers-coursework.git, 对应修改的代码在./assignments/PA/cool.flex.