c_minus compiler project
Post on 18-Jan-2016
302 Views
Preview:
DESCRIPTION
TRANSCRIPT
C_Minus Compiler Project
What do we support?
数据类型: Integer, char, float,void
数据类型:数组,函数
算术运算符: + 、 - 、 * 、 / ;
关系运算符: > 、 < 、 >= 、 <= 、 == 、 !=;
逻辑运算符:与、或、非;
语句结构:条件句、循环语句、说明语句、赋值语句、转移语句等。
What do we generate?
P-Code
数学运算 :adi, adf, subi, subf, multi, multf, divi, divf
关系运算 :grt, les, leq, geq, equ, neq
流程控制 :fjp, ujp, lab
函数 :mst, cup, ret, ent
load & store :lodi, lodf, lodc, lodci, lodcf, lodcc, lda, sto, stn
How do we do it?
开始 词法分析 语法分析
建立符号表类型检查代码生成
结束
语法树
符号表
C_Minus 的语法树 ( 数据结构1)
enum NodeKind {StmtK,ExpK,DeclK};
enum StmtKind {IfK,WhileK,ForK,ReturnK,CompoundK};
enum ExpKind
{TypeK,OpK,NotK,ArrayK,ConstK,IdK,CallK};
enum DeclKind {VarDeclK,FuncDeclK,FuncDefK,ParamK};
C_Minus 的语法树 ( 数据结构2)
struct TreeNode{
struct TreeNode * child[MAXCHILDREN];
struct TreeNode * sibling;
int lineno;
NodeKind nodekind;
union {StmtKind stmt; ExpKind exp; DeclKind decl; } kind;
union { TokenType op; int vali; float valf; char valch;
char *name; ExpType vartype; } attr;
ExpType type; /* for type checking of exps */
VarKind varK;
};
C_Minus 的语法树 ( 语句 1)
If: StmtK
Test: ExpK Body: stmtK Else: stmtK
If statement
While: StmtK
Test: ExpK Body: StmtK
While statement
C_Minus 的语法树 ( 语句 2)
For statement
Return statement
For: stmtK
Initial: ExpK Test:ExpK Body:StmtKOperation:ExpK
Return:StmtK
Body : StmtK
C_Minus 的语法树 ( 语句 3)
Compound statement
Compound:StmtK
StmtK/DeclK StmtK/DeclK
C_Minus 的语法树 ( 表达式 1)
数组 ArrayK
ExpK
函数 CallK
Name:IdK Arg:ExpK Arg:ExpK
C_Minus 的语法树 ( 声明 1)
变量声明 VarDeclK
TypeK Var-list
函数声明FuncDeclK
Return Type: TypeK Name:IdK Param_list
C_Minus 的语法树 ( 声明 2)
函数定义FuncDeclK
Return Type: TypeK Name:IdK Param_list CompoundK
Symbol Table
fn( ){ int m;
if ( ){int n;
…}
else {int I;
…}
}
int u;
main( ){ char c;
…
}
示例程序:
Symbol Table
Fn , u
m
n i
c
第一层 : 函数和全局变量
第 2,3,4… 层 : 局部变量
struct SymTab{ BucketList * hashTable[SIZE]; SymTab * child; // 指向下一层的符号表 SymTab * parent; // 指向上层的符号表 SymTab * sibling; // 指向同层的符号表};
Symbol Table 的数据结构
Bucklist 的数据结构
struct BucketList{
char * name; char * fname;
LineList * lines;
entryType entrytype;
int memloc; int size;
paramType * param;
struct BucketList * next;
};
Symbol Table 的接口函数( 1)int st_insert( char * name, int lineno, ExpType type, ExpKind
kind, int size = -1);
int st_insert( char * name, int lineno, ExpType type,
TreeNode * params);
int st_lookup ( char * , Result &);
int st_funclookup(char *, ExpType, TreeNode * params);
int st_funclookup(char *, Result &);
Symbol Table 的接口函数( 2)int st_setLoc(char * name ,int memloc );
void st_newBuck();
void st_delBuck();
void st_reset();
void st_inFunc(char * name);
void st_outFunc();
void printSymTab(FILE * listing);
Type Checking 的实现
struct TreeNode{
……………….
……………….
ExpType type; /* for type checking of exps */
VarKind varK; /* Array/Func/Norm */
};
通过对树的后序遍历实现。首先计算一个结点的儿子的类型,存放在结点的 type 成员变量中,然后根据结点类型进行类型检查。
示例
(1) int x[10];
Fn(x); x.varK = Array x.type = Integer
X[1] = 9; x.varK = Norm x.type = Integer
(2) int Fn( );
x = Fn( ); Fn.varK = Func Fn.type = Integer
类型计算的规则有以下几条:
IdK , ArrayK , ConstK 的 type 由建立符号表的过程中赋值
算术运算符的 type 等于两端的类型 ( 允许 int 到 float 型的转换) ;
逻辑运算符的 type 为 Boolean ;
类型不匹配的情况有以下几种:
操作符的两端类型不一致 (int 和 float 可以转换除外 ) ;
if , for , while 语句的条件不是 Boolean 类型;
Return type 和函数定义不一致;
运算规则
Control Macros
• /* set NO_PARSE to TRUE to get a scanner-only compiler */
• #define NO_PARSE FALSE
• /* set NO_ANALYZE to TRUE to get a parser-only compiler */
• #define NO_ANALYZE FALSE
• /* set NO_CODE to TRUE to get a compiler that does not
• * generate code
• */
• #define NO_CODE FALSE
Some Global Variables?
• int TraceScan;
• int TraceParse;
• int TraceAnalyze;
• int TraceCode;
Important Functions
int getToken(); /* 取得一个 Token*/
void yyerror(const char * message); /* 打印错误信息 */
void emitComment(char *c); /* 在 P-Code 中打印注释 */
void emitCode(char *s); /* 输出一条 P-Code*/
void codeGen(TreeNode * syntaxTree, char * codefile); /* 代码生成部分
的接口 */
Code Generate
• 执行代码生成任务的函数是: static void cGen( TreeNode * tree)
• 它由根结点遍历语法树每个节点,并对每个结点递归地生成 P-code 。
• 先 对 语 法 树 的 结 点 分 成 三 大 类 : 语 句 结 点( StmtK ), 表 达 式 结 点 ( ExpK ), 声 明 结 点( DeclK ),然后逐个用对应函数进行处理。三个函数分别是:
genStmt(tree); genExp(tree, TRUE);
genDecl(tree);
switch (tree->nodekind) {
case StmtK:
genStmt(tree);
break;
case ExpK:
genExp(tree, TRUE); //set to TRUE for destructive store
break;
case DeclK:
genDecl(tree);
break;
}
cGen(tree->sibling);
Code Generate
top related