一:共有16个文件。MAIN.C:主函数GLOBALS.H:全局定义的文件SCAN.C/SCAN.H:词法分析PARSE.C/PARSE.H:语法分析UTIL.C/UTIL.H:构造树SYMTAB.C/SYMTAB.H:符号表CGEN.C/CGEN.H:生成汇编代码CODE.C/CODE.H:这个只是用来把分析过程输出到屏幕的.二:各个文件的分析。1,MAIN.C:主要有三个FILE*句柄:source--源代码文件。listing--显示分析过程的文件,这里重定向到stdout,也就是屏幕。code--目标汇编代码文件。从该文件中可知程序运行的流程:检查参数正确否(tiny.exefilename)-构造语法树(调用parse函数)-根据语法树生成代码(调用codeGen函数,该函数又调用cGen函数)。2,GLOBALS.H:定义了关键字个数8个。定义了关键字,运算符等内容的枚举值。定义了语句类型的枚举值,这个决定树的结点。定义了变量类型(也就三种,void,integer,boolean)。定义了树的节点--这个最重要了!!其结构如下所示:typedefstructtreeNode{structtreeNode*child[MAXCHILDREN];structtreeNode*sibling;intlineno;NodeKindnodekind;union{StmtKindstmt;ExpKindexp;}kind;union{TokenTypeop;intval;char*name;}attr;ExpTypetype;/*fortypecheckingofexps*/}TreeNode;从字面就知道意思了。因为关键字少,语法简单,所以孩子结点不多,他这里定义最多3个,所以直接用数组就可以了,不动态分配。剩下的定义了一些条件编译的变量,对整个编译的核心内容无关紧要。不说了。3,SCAN.c/SCAN.H主要有这么几个函数:staticintgetNextChar(void);staticvoidungetNextChar(void);staticTokenTypereservedLookup(char*s);TokenTypegetToken(void);从字面也知道意思了。那个reservedLookup函数是查找关键字的,在符号表中找。这里还定义了一个保存关键字的结构:staticstruct{char*str;TokenTypetok;}reservedWords[MAXRESERVED]={{if,IF},{then,THEN},{else,ELSE},{end,END},{repeat,REPEAT},{until,UNTIL},{read,READ},{write,WRITE}};最重要的是getToken(void)函数。这个相当于lex的功能,进行词法分析。也就是一个DFA,switch后面跟了一堆的case。其中,我比较欣赏他getNextChar(void)函数的思路,完整给出,让大家鉴赏一下:staticintgetNextChar(void){if(!(lineposbufsize)){lineno++;if(fgets(lineBuf,BUFLEN-1,source)){if(EchoSource)fprintf(listing,%4d:%s,lineno,lineBuf);bufsize=strlen(lineBuf);linepos=0;returnlineBuf[linepos++];}else{EOF_flag=TRUE;returnEOF;}}elsereturnlineBuf[linepos++];}4,PARSE.C/PARSE.H有这么几个函数:TreeNode*parse(void)staticTreeNode*stmt_sequence(void);staticTreeNode*statement(void);staticTreeNode*if_stmt(void);staticTreeNode*repeat_stmt(void);staticTreeNode*assign_stmt(void);staticTreeNode*read_stmt(void);staticTreeNode*write_stmt(void);staticTreeNode*exp(void);staticTreeNode*simple_exp(void);staticTreeNode*term(void);staticTreeNode*factor(void);最重要的是parse这个函数,就是用来构造整个程序的语法树的。下面的一堆私有函数看名字就知道了,,它们构造相应语法的语法树,然后parse最后把它们这些子树整合成一个大树。5,SYMTAB.C/SYMTAB.H这个是符号表操作的,也就是词法分析的时候查找表,看该token是不是关键字。如果不是,就当作表识符添加进去。在语法分析的时候也要用到,看变量有没有声明的时候用的。