使用yacc/lexer实现的简易的pascal-s编译器,能够将指定语法的pascal-s语言代码编译为特定的目标代码,工作流程为:源程序--词法分析器--> token流(一连串token)--语法分析器--> parser tree(or ast) --分析判断源程序是否合法,并给出语义错误,最后进行翻译-->目标语言
源程序--词法分析器--> token流(一连串token)--语法分析器--> parser tree(or ast) --分析判断源程序是否合法,并给出语义错误,最后进行翻译-->目标语言
设计词法分析:
设计pascal-s语言的flex词法规则表达,使用flex识别pascal-s源程序中的单词。使用Flex分析单词时,需要记录单词的位置信息(行/列),用于在语义分析时提供错误定位信息。
设计语法分析器:
设计pascal-s语言的bison语法规则表达,使用bison识别pascal-s源程序中的语法符号,根据语法符号之间的关系构建出语法树。
设计语法树:
语法树是源代码程序的抽象表达,每一条语法规则中的推导关系都代表语法树中的父节点和子节点关系。使用在进行语法分析时,组装出抽象语法树,获得源代码程序的抽象表达。
设计符号
将源代码程序中的变量和值抽象成符号,将其内容(类型、名称等等)存储在符号结构体内,供语义分析过程中进行静态类型检查以及在代码生成中生成目标代码。
设计符号表
使用符号表将符号组织起来,以供查找。一个作用域对应着一个符号表。
设计作用域
将pascal-s语言中的作用域的概念具体为作用域结构体,作用域结构体拥有一个符号表,其中是在该作用域中声明的符号。
设计作用域栈
使用作用域进出作用域栈来模拟运行源代码进出作用域的过程。当在某个作用域内查找符号时,就是现在在本作用域中寻找符号,然后在比本作用域在作用域栈中更靠近栈底的作用域中寻找符号。
设计访问方法
使用访问器模式来访问语法树的每一个节点,在某个语法树节点的访问方法中可以显式地指定访问其子节点的顺序,如此就可以方便地进行语义分析和代码生成。
设计语义分析
在访问方法中收集符号的信息,组装成符号结构体,并保存在正确的符号表内。当遇到函数声明等会引入作用域的语法树节点时,创建新的作用域对象并操作作用域栈。
设计代码生成方案