设为首页 加入收藏

TOP

C-编译器的实现(一)
2018-10-21 14:14:38 】 浏览:186
Tags:编译器 实现

  写这个编译器的目的,是为了完成编译原理课上老师布置的大作业,实际上该大作业并不是真的实现一个编译器,而我选择硬刚,是为了完成我的小愿望--手写内核,编译器和CPU。我花了整个上半学期,写完了WeiOS,为了让它支持更多的用户态程序,甚至是基本的程序开发,必须给它量身打造一个编译器。于是这个编译器被提上日程。

  因为我要复习考研和专业课过多,我打消了手写词法分析和语法分析的念头,转而使用FLEXYACC,等到有时间再完成手工的版本--我认为也不是很难,如果用递归下降的话。

  全部代码都在该处 https://github.com/mynamevhinf/CMinusCompiler

 

词法分析

  因为是精简的C语言,所以只支持基本的符号(Token),像”++”, “--”和位操作都不予考虑。另外,只支持intvoid类型。于是便构成了以下符号集:

  number   [1-9][0-9]*

  letter     [a-zA-Z]

  Identifier  {letter}({letter}|{number})*

  Newline   \n

  whitespace [ \t\r]+

保留字:

  If else while int void return

 

运算和界限符号:

  <= >= != == + - * / < > ; , ( ) { } [ ]

 

主体函数是getToken(),这个函数封装了FLEX原生的yylex函数。而yyparser也将直接调用该函数。它的主要工作是在开始第一次词的检索前,初始化相关变量。然后在每次被调用的时候,返回符号的类型给yyparser,并且把构成符号的字符串临时保存在tokenString字符数组中。所以这函数相当于什么事情都没有干。

另外注意的是注释的两个符号,我直接在词法分析处理注释了。行注释是”//”,利用FLEX自带的input()函数(如果有的话,没有就写一个)一直读到’\n’出现。然后就是段注释符”/*”和”*/”,相似的做法。

 

语法分析

  以下是BNF格式的语法规则:

  Program -> declaration_list

  declaration_list -> declaration_list  declaration | declaration

  declaration ->  var_declaration | func_declaration

  type_specifier ->  INT | VOID

  var_declaration ->  type_specifier VARIABLE ;  |  type_specifier VARIABLE [ NUM ] ;

  func_declaration ->  type_specifier VARIABLE ( params ) compound_stmt

  Params -> params_list | VOID

  params_list -> params_list , param | param

  Param -> type_specifier VARIABLE  | type_specifier VARIABLE [ ]

  compound_stmt -> { local_declarations stmt_list }

  local_declarations -> local_declarations var_declaration | /* empty */

  stmt_list ->stmt_list stmt  |   stmt

  Stmt -> expr_stmt | if_stmt | return_stmt | compound_stmt | iteration_stmt

  expr_stmt -> expr ; | ;

  if_stmt ->IF ( expr ) stmt | IF ( expr )  stmt ELSE stmt

  iteration_stmt -> WHILE ( expr ) stmt

  return_stmt ->RET ; | RET expr ;

  Expr -> var = expr | simple_expr

  Var -> VARIABLE | VARIABLE [ NUM ]

  Call -> VARIABLE ( args )

  Args -> arg_list |  /* empty */

  arg_list -> arg_list , expr | expr

  simple_expr -> NUM  | var | call  | ( expr )  | - simple_expr

            | simple_expr + simple_expr

            | simple_expr - simple_expr

            | simple_expr * simple_expr

            | simple_expr / simple_expr

            | simple_expr < simple_expr

            | simple_expr > simple_expr

            | simple_expr >=simple_expr

            | simple_expr <= simple_expr

            | simple_expr != simple_expr

            | simple_expr == simple_expr

 

  我用globl.h中的TreeNode结构来保存语法树中的每一个节点。而一些为空的转换,我打算还是用一个该结构来表示,但是类型标记为None(也许有点浪费内存).

  我实现的C-还算是个比较完整的程序语言,所以很有必要生成AST(抽象语法树),那么语法树中共有几种类型的节点呢?按理说应每种语法规则对应一种类型,例如参数列表,声明语句,普通语句和表达式等都对应一个节点类型,详细可以参见NodeType枚举类型。Parser.c文件是处理与语法树相关的函数,目前来说当中几个函数还没写清楚,

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇如何在notepad++实现代码自动化排.. 下一篇第 11 章 字符串和字符串函数(命..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目