fkparse的运行原理 ================= 本章大致介绍了fkparse的工作流程和源码分析。 工作流程 -------- 词法和语法分析 ~~~~~~~~~~~~~~ | 词法分析器和语法分析器由Flex与Bison生成。在成功打开输入文件后,程序就会调用yyparse()进行语法分析(具体怎么分析的我自己也不太清楚,应该是按照LR分析的那种算法,总之这个函数具体怎么运行的对掌握大概内容不重要),分析完成并没有出现语法错误后,就会往全局变量extension(声明在main.h)中存入一个分析完成的ExtensionObj对象。 | 关于Flex和Bison的语法这里不会十分详细的说明,但会在下面稍微提一下。 分析并生成代码 ~~~~~~~~~~~~~~ | 在进行完没有语法错误,或者成功从语法错误中恢复了的语法分析后,yyparse()将返回0,然后main.c中调用函数继续分析extension并据此生成Lua代码。 | 以上就是fkparse工作的大概流程,十分简单,下面详细看看。 基础设施 -------- list.c ~~~~~~ 基础设施之链表。里面定义了链表的创建、尾插、头插、取下标、删除某个元素、获取元素下标、获取链表长度、链表销毁等操作。 在声明其的structs.h中,还含有一些常用宏,如链表遍历、链表判断为空、判断是否包含某个元素等。以及从链表的函数中宏定义出来的一些栈的操作也在里面。 hash.c ~~~~~~ 作为整个符号表的基础而存在的哈希表数据结构。 定义了哈希表的创建、销毁、取得数据、存放数据等等,以及许多跟哈希表内部算法有关的内容。 symtab.c ~~~~~~~~ 基于哈希表而制作的跟符号表操作有关的函数。 | 为了实现全局变量和局部变量,fkparse在一次分析过程中使用了许多符号表,大体上每个代码块一个符号表。由于在分析代码时,分析函数成为一个栈,所以fkparse的符号表也是以栈的形式组织的。在一次对符号表的搜索中,程序会从栈顶向栈底逐一检索;当一个代码块分析完了,它的符号表就从栈中弹出,然后销毁掉。 | 本文件具体包括了符号表的检索、设定键值以及销毁。符号表的创建直接用创建哈希表的函数即可。 分析与中间结构 -------------- fkparse不产生语法树,而是在分析过程中直接创建中间结构。 ast.c ~~~~~ 曾经里面含有各种语法树的构造函数,现在里面只剩个checktype了,不久后将与error.c合并掉。 object.c ~~~~~~~~ 含有各种中间对象的构造和析构函数,以及一个很方便调用的对所有Object均适用的析构函数。 lex.c ~~~~~ Flex根据lex.l生成的词法分析器,被语法分析器调用。它会读取文件中的字符串,并返回合乎词法规则的token。 Flex按照贪心原则进行匹配,也就是多种情况下按照最长字符串来,所以它能成功区分“摸牌阶段摸牌时”和“摸”这两个词语。 grammar.c ~~~~~~~~~ Bison根据grammar.y生成的语法分析器代码。它是自底向上进行分析的,在分析过程中会根据文法规则和语义动作创建相应的对象。 代码生成 -------- builtin.c ~~~~~~~~~ 含有各种各样的内置函数和内置变量,以及一个初始化内置符号表的函数。 error.c ~~~~~~~ 含有报错相关的各种函数。可以根据行列号将源文本输出到屏幕上,考虑了汉字和其他UTF-8字符的特殊情况。 generate.c ~~~~~~~~~~ 根据各种对象对症下药,生成对应的Lua代码。 main.c ~~~~~~ 主函数,说实话不是那么重要,fkparse到后期估计会以dll/so这样库的形式登场吧。 其他 ---- fkparser.lua ~~~~~~~~~~~~ 生成的Lua运行起来所必备的种种函数,毕竟直接生成神杀的Lua难度很高。 test/\*.txt ~~~~~~~~~~~ fkparse开发时的测试用例。