编译原理课程设计C-语言编译器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理课程设计报告课题名称: C-语言编译器设计
提交文档学生姓名:李杰
提交文档学生学号:0743041240
同组成员名单:无
指导教师姓名:金军
N不指导教师评阅意见:
.
.
提交报告时间: 2010年 6 月 10日
1.课程设计目标
实验建立C-编译器。

只含有scanner和parser部分。

2.分析与设计
(1)实现方法:
编程语言为C语言。

编程方法:scanner部分根据DFA图用switch-case结构实现状态转换;parser部分用递归下降分析方法实现。

(2)扫描器:
C-惯用的词法
1、语言的关键字:else if int return void while
2、专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */
3、其他标记是ID和NUM,通过下列正则表达式定义:
ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9
4、空格由空白、换行符和制表符组成。

空格通常被忽略,除了它必须分开ID、NUM关键字。

5. 注释用通常的C语言符号/ * . . . * /围起来。

注释可以放在任何空白出现的位置(即注释不能放在标
记内)上,且可以超过一行。

注释不能嵌套
各单词的状态转换图(DFA图如下)词法结构见文件"globals.h"中。

(3)分析器:分析树结构见文件"globals.h"中。

C-的BNF语法如下:
(4)代码设计说明:
程序结构:语法分析函数parse通过调用词法分析函数getToken实现语法分析。

文件和函数的设计说明:文件main.c包含相应头文件,及main函数的实现;文件golbals.h 包含符号表和分析数的数据结构及在其它文件中使用的变量;文件util.h 和util.c实现与词法分析和语法分析输出相关的函数printToken和printTree,以及分析树节点初始化相关的函数newStmtNode,newExpNode(Expkind)和copyString;文件scan.h 和scan.c实现词法分析,主要函数为getToken;文件parse.h 和parse.c实现语法分析,函数为与文法规则对应的函数。

关键数据结构
3.程序代码实现
文件main.c代码如下:
//实验建立C-编译器。

只含有scanner和parser部分。

#include"globals.h"
#include "util.h"
#include "scan.h"
#include "parse.h"
//全局变量和标志
int lineno=0;
FILE*source;
FILE*listing;
FILE*code;
int EchoSource=TRUE;
int TraceScan=TRUE;
int TraceParse=TRUE;
int Error=FALSE;
int main(int argc,char*argv[])
{
TreeNode*syntaxTree;
char pgm[120]; //代码文件名
if(argc!=2)
{
fprintf(stderr,"usage:%s C:\source.c \n",argv[0]);
return -1;
}
strcpy(pgm,argv[1]);
if (strchr(pgm,'.')==NULL)
{ strcat(pgm,".tny"); }
source=fopen(pgm,"r");
if(source==NULL)
{
fprintf(stderr,"file %s not found \n",pgm);
return -1;
}
listing=stdout;
fprintf(listing,"\n C-COMPILA TION: %s\n",pgm); // while (getToken()!=ENDFILE);
EchoSource=FALSE;
TraceScan=FALSE;
syntaxTree=parse();
if(TraceParse)
{ fprintf(listing,"\nSyntax tree\n:");
printTree(syntaxTree);
}
fclose(source);
return 0;
}
文件globals.h代码如下:
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MAXRESERVED 6
typedef enum
{
ENDFILE,ERROR,
IF,ELSE,INT,RETURN,VOID,WHILE, //关键字
ID,NUM,
ASSIGN,EQ,L T,PLUS,MINUS,TIMES,OVER,LPAREN,RP AREN,SEMI,BT,LQ,BQ, UEQ,DOU,LZGH,RZGH,LDGH,RDGH,//特殊字符
} TokenType;
extern FILE* source ;
extern FILE* listing;
extern FILE* code;
extern int lineno;
//语法分析树
typedef enum {Stmtk,Expk} Nodekind;
typedef enum {IfK,ElseK,IntK,ReturnK,V oidK,WhileK,AssignK,HanK,HanshutiK} Stmtkind; typedef enum {Opk,Constk,Idk,V ark} Expkind;
typedef enum {V oid,Integer,Boolean} ExpType;
#define MAXCHILDREN 3
typedef struct treeNode
{
struct treeNode*child[MAXCHILDREN];
struct treeNode*sibling;
int lineno;
Nodekind nodekind;
union {Stmtkind stmt; Expkind exp;} kind;
union { TokenType op;
int val;
char*name;} attr;
ExpType type;
} TreeNode;
extern int EchoSource;
extern int TraceScan;
extern int TraceParse;
extern int Error;
#endif
文件util.h代码如下:
#ifndef _UTIL_H_
#define _UTIL_H_
void printToken( TokenType, const char*) ;
//为分析树
TreeNode*newStmtNode(Stmtkind);
TreeNode*newExpNode(Expkind);
char*copyString( char*);
void printTree( TreeNode*);
#endif
文件util.c代码如下:
#include "globals.h"
#include "util.h"
void printToken( TokenType token, const char* tokenString ) { switch (token)
{ case IF:
case INT:
case ELSE:
case RETURN:
case VOID:
case WHILE:
fprintf(listing,
"reserved word: %s\n",tokenString);
break;
case ASSIGN: fprintf(listing,"=\n"); break; case L T: fprintf(listing,"<\n"); break;
case EQ: fprintf(listing,"==\n"); break;
case LPAREN: fprintf(listing,"(\n"); break; case RPAREN: fprintf(listing,")\n"); break; case SEMI: fprintf(listing,";\n"); break;
case PLUS: fprintf(listing,"+\n"); break;
case MINUS: fprintf(listing,"-\n"); break; case TIMES: fprintf(listing,"*\n"); break; case OVER: fprintf(listing,"/\n"); break;
case BT: fprintf(listing,">\n"); break;
case LQ: fprintf(listing,"<=\n"); break;
case BQ: fprintf(listing,">=\n"); break;
case UEQ: fprintf(listing,"!=\n"); break;
case DOU: fprintf(listing,",\n"); break;
case LZGH: fprintf(listing,"[\n"); break;
case RZGH: fprintf(listing,"]\n"); break;
case LDGH: fprintf(listing,"{\n"); break;
case RDGH: fprintf(listing,"}\n"); break; case ENDFILE: fprintf(listing,"EOF\n"); break; case NUM:
fprintf(listing,
"NUM, val= %s\n",tokenString);
break;
case ID:
fprintf(listing,
"ID, name= %s\n",tokenString);
break;
case ERROR:
fprintf(listing,
"ERROR: %s\n",tokenString);
break;
default: /* should never happen */
fprintf(listing,"Unknown token: %d\n",token);
}
}
TreeNode*newStmtNode(Stmtkind kind)
{
TreeNode*p=(TreeNode*)malloc(sizeof(TreeNode));
int k;
if(p==NULL)
{ fprintf(listing,"out of memory error at line %d\n",lineno); } else
{
for(k=0;k<MAXCHILDREN;k++)
{ p->child[k]=NULL; }
p->sibling=NULL;
p->nodekind=Stmtk;
p->kind.stmt=kind;
p->lineno=lineno;
}
return p;
}
TreeNode*newExpNode(Expkind kind)
{
TreeNode*p=(TreeNode*)malloc(sizeof(TreeNode));
int k;
if(p==NULL)
{ fprintf(listing,"out of memory error at line %d\n",lineno); } else
{
for(k=0;k<MAXCHILDREN;k++)
{ p->child[k]=NULL; }
p->sibling=NULL;
p->nodekind=Expk;
p->kind.exp=kind;
p->lineno=lineno;
p->type=V oid;
}
return p;
}
char*copyString( char*s)
{
int i;
char*p;
if(s==NULL)
{ return NULL; }
i=strlen(s)+1;
p=malloc(i);
if(p==NULL)
{ fprintf(listing,"out of memory error at line %d\n",lineno); } else { strcpy(p,s); }
return p;
}
static indentno=0;
#define INDENT indentno+=2
#define UNINDENT indentno-=2
static void printSpace(void)
{
int k;
for(k=0;k<indentno;k++)
{ fprintf(listing," "); }
}
void printTree( TreeNode*t)
{ int i;
INDENT;
while(t!=NULL)
{
printSpace();
if(t->nodekind==Stmtk)
{
switch (t->kind.stmt)
{
case IfK:
fprintf(listing,"If\n");
break;
case IntK:
fprintf(listing,"Int\n");
break;
case V oidK:
fprintf(listing,"V oid\n");
break;
case ReturnK:
fprintf(listing,"Return\n");
break;
case WhileK:
fprintf(listing,"While\n");
break;
case AssignK:
fprintf(listing,"Assign to: %s\n",t->);
break;
case HanK:
fprintf(listing,"Hanshu\n");
break;
case HanshutiK:
fprintf(listing,"Hanshuti\n");
break;
default:
fprintf(listing,"Unknown stmt kind\n");
break;
}
}
else if(t->nodekind==Expk)
{ switch (t->kind.exp)
{
case Opk:
fprintf(listing,"Op:");
printToken(t->attr.op,"\0");
break;
case Constk:
fprintf(listing,"Const: %d\n",t->attr.val);
break;
case Idk:
fprintf(listing,"Id: %s\n",t->);
break;
case V ark:
fprintf(listing,"V ark: %d\n",t->attr.val);
break;
default:
fprintf(listing,"Unknown exp kind\n");
break;
}
}
else { fprintf(listing,"Unknown exp kind\n"); }
for(i=0;i<MAXCHILDREN;i++)
{ printTree(t->child[i]); }
t=t->sibling;
}
UNINDENT;
}
文件scan.h代码如下:
#ifndef _SCAN_H_
#define _SCAN_H_
#define MAXTOKENLEN 40
extern char tokenString[MAXTOKENLEN+1];
TokenType getToken(void);
#endif
文件scan.c代码如下:
#include"globals.h"
#include "util.h"
#include "scan.h"
//DFA中的状态
typedef enum
{START,INID,INNUM,DONE,INASSIGN,INCOMMENT,ZHU,ZZHU} StateType;
char tokenString[MAXTOKENLEN+1];
#define BUFLEN 256 //代码文件的行数
static char lineBuf[BUFLEN]; //保存当前行
static int linepos=0; //lineBuf中的当前位置
static int bufsize=0; //buffer 串的大小
static int EOF_Flag=FALSE;
//获取字符从lineBuf[BUFLEN]中
static int getNextChar(void)
{
if(!(linepos< bufsize))
{
lineno++; //新一行
if(fgets(lineBuf,BUFLEN-1,source)) //取新一行
{ if(EchoSource) fprintf(listing,"%4d: %s",lineno,lineBuf);
bufsize=strlen(lineBuf);
linepos=0;
return lineBuf[linepos++]; //先返回lineBuf[linepos],后linepos加1.
}
else
{ EOF_Flag=TRUE;
return EOF;
}
}
else return lineBuf[linepos++];
}
//没有取得字符。

static void ungetNextChar(void)
{
if(!EOF_Flag) linepos--;
}
//关键字的查找表
static struct
{ char* str;
TokenType tok;
} reservedWords[MAXRESERVED]
=
{ {"if",IF},{"else",ELSE},{"void",VOID},{"return",RETURN},{"int",INT},{"while",WHILE }};
//关键字的查找
static TokenType reserveLookup(char*s)
{
int i;
for(i=0;i<MAXRESERVED;i++)
{
if(!strcmp(s,reservedWords[i].str))
{
return reservedWords[i].tok;
}
}
return ID;
}
TokenType getToken(void)
{
//token串存放的索引
int tokenStringIndex=0;
//存放返回的token
TokenType currentToken;
//现在的状态
StateType state=ST ART;
//token串的标记
int save;
int f1=0; //标志取>:1、<:2、=:3和!:4 int d=getNextChar();
if(d==EOF)
{ currentToken=ENDFILE;
return currentToken;
}
else
{
ungetNextChar();
}
while(state!=DONE)
{ int c=getNextChar();
save=TRUE;
switch(state)
{
case START:
if(isdigit(c))
state=INNUM;
else if (isalpha(c))
state=INID;
else if(c=='>')
{ f1=1;
state=INASSIGN;
}
else if(c=='<')
{ f1=2;
state=INASSIGN;
}
else if(c=='=')
{ f1=3;
state=INASSIGN;
}
else if(c=='!')
{ f1=4;
state=INASSIGN;
}
else if((c==' ')||(c=='\t')||(c=='\n')) save=FALSE;
else if (c=='/')
{ save=FALSE;
state=ZHU;
}
else
{
state=DONE;
switch (c)
{
case EOF:
save=FALSE;
currentToken=ENDFILE;
break;
case '+':
currentToken=PLUS;
break;
case '-':
currentToken=MINUS;
break;
case '*':
currentToken=TIMES;
break;
case '(':
currentToken=LP AREN;
break;
case ')':
currentToken=RP AREN;
break;
case '[':
currentToken=LZGH;
break;
case ']':
currentToken=RZGH;
break;
case '{':
currentToken=LDGH;
break;
case '}':
currentToken=RDGH;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=DOU;
break;
default:
currentToken=ERROR;
break;
}
}
break;
case ZHU:
if(c=='*')
{ save=FALSE;
state=INCOMMENT;
}
else
{ ungetNextChar();
save=TRUE; //取“/”号
state=DONE;
currentToken=OVER;
}
break;
case INCOMMENT:
save=FALSE;
if(c==EOF)
{ state=DONE;
currentToken=ENDFILE;
}
else if(c=='*')
{
state=ZZHU;
}
break;
case ZZHU:
save=FALSE;
if(c==EOF)
{ state=DONE;
currentToken=ENDFILE;
}
else if(c=='*')
{ state=ZZHU; }
else if(c=='/')
{ state=ST ART; }
else
{ state=INCOMMENT; } break;
case INASSIGN:
state=DONE;
if(c=='=')
{
if(f1==1)
{ currentToken=BQ; }
else if(f1==2)
{ currentToken=LQ; }
else if(f1==3)
{ currentToken=EQ; }
else if(f1==4)
{ currentToken=UEQ; }
else
{
save=FALSE;
currentToken=ERROR;
}
}
else
{ ungetNextChar();
if(f1==1)
{ currentToken=BT; }
else if(f1==2)
{ currentToken=L T; }
else if(f1==3)
{ currentToken=ASSIGN; }
else
{ save=FALSE;
currentToken=ERROR;
}
}
break;
case INNUM:
if(!isdigit(c))
{ //NUM完。

ungetNextChar();
save=FALSE;
state=DONE;
currentToken=NUM;
}
break;
case INID:
if(!isalpha(c))
{ //标识符完。

ungetNextChar();
save=FALSE;
state=DONE;
currentToken=ID;
}
break;
case DONE:
default: //should never happen
fprintf(listing,"Scanner Bug: state=%d\n",state);
state=DONE;
currentToken=ERROR;
break;
}
if((save)&&(tokenStringIndex<=MAXTOKENLEN)) { tokenString[tokenStringIndex++]= (char)c; }
if(state==DONE)
{
tokenString[tokenStringIndex]='\0';
if(currentToken==ID)
{ currentToken=reserveLookup(tokenString); }
}
}
if (TraceScan)
{
fprintf(listing,"\t%d:",lineno);
printToken(currentToken,tokenString); }
return currentToken;
}
文件parse.h代码如下:
#ifndef _P ARSER_H
#define _P ARSER_H
TreeNode*parse(void);
#endif
文件parse.c代码如下:
#include "globals.h"
#include "util.h"
#include "parse.h"
#include "scan.h"
static TokenType token;
//递归下降函数声明
static TreeNode*program(void);
static TreeNode*declaration(void);
static TreeNode*func_declaration(void); static TreeNode*var_declaration(void); static TreeNode*params(void);
static TreeNode*param_list(void);
static TreeNode*param(void);
static TreeNode*compound_stmt(void); static TreeNode*local_var_declaration(void); static TreeNode*statement_list(void); static TreeNode*statement(void);
static TreeNode*selection_stmt(void); static TreeNode*iteration_stmt(void); static TreeNode*return_stmt(void);
static TreeNode*expression_stmt(void);
static TreeNode*expression(void);
static TreeNode*simple_expression(TreeNode*k);
static TreeNode*additive_expression(TreeNode*k);
static TreeNode*term(TreeNode*k);
static TreeNode*factor(TreeNode*k);
static TreeNode*var(void);
static TreeNode*call(TreeNode*k);
static TreeNode*args(void);
static void syntaxError(char*me)
{ fprintf(listing,"\n>>> ");
fprintf(listing,"Syntax error at line %d: %s\n",lineno,me);
Error=TRUE;
}
static void match(TokenType ex)
{
if(token==ex) { token=getToken();}
else
{ syntaxError("unexoected token->");
printToken(token, tokenString);
fprintf(listing," ");
}
}
static TreeNode*program()
{ TreeNode* t=declaration();
TreeNode* p=t;
while((token!=INT)&&(token!=VOID))
{ syntaxError("unexpected token->");
printToken(token, tokenString);
token=getToken();
}
while((token==INT)||(token==VOID)) { TreeNode* q;
q=declaration();
if(q!=NULL)
{
if(t==NULL) { t=p=q;}
else
{ p->sibling=q;
p=q;
}
}
}
return t;
}
static TreeNode*declaration(void)
{
TreeNode* t=NULL;
if(token==INT)
{ t=newStmtNode(IntK);
match(INT);
}
if(token==VOID)
{
t=newStmtNode(V oidK);
match(VOID);
}
if((t!=NULL)&&(token==ID))
{ TreeNode* p=NULL;
p=newExpNode(Idk);
p->=copyString(tokenString);
t->child[0]=p;
match(ID);
}
if((token==LPAREN)&&(t->child[0]!=NULL)) { t->child[1]=func_declaration(); }
else if((token==LZGH)||(token==SEMI))
{ t->child[1]=var_declaration(); }
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
return t;
}
static TreeNode*func_declaration(void)
{ TreeNode* t=newStmtNode(HanK);
match(LPAREN);
t->child[0]=params(); /*get the param list*/ match(RP AREN);
t->child[1]=compound_stmt();
return t;
}
static TreeNode*var_declaration(void)
{ TreeNode* t=NULL;
if(token==LZGH)
{ match(LZGH);
t=newExpNode(V ark);
if((t!=NULL)&&(token==NUM))
{ t->attr.val=atoi(tokenString); }
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
match(NUM);
match(RZGH);
match(SEMI);
}
else { match(SEMI);} //将;号辨别放在declaration中return t;
}
static TreeNode*params(void)
{ TreeNode* t=NULL;
if(token==VOID)
{ t=newStmtNode(V oidK);
match(VOID);
}
else if(token==INT)
{ t=param_list();}
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
return t;
}
static TreeNode*param_list(void)
{ TreeNode* t=param();
TreeNode* p=t;
while(token==DOU)
{ TreeNode*q=NULL;
match(DOU);
q=param();
if(q!=NULL)
{
if(t==NULL) { t=p=q;}
else
{ p->sibling=q;
p=q;
}
}
}
return t;
}
static TreeNode*param(void)
{ TreeNode* t=NULL;
if(token==INT)
{ t=newStmtNode(IntK);
match(INT);
if(token==ID)
{ TreeNode* p=NULL;
p=newExpNode(Idk);
p->=copyString(tokenString);
t->child[0]=p;
match(ID);
}
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
if((token==LZGH)&&(t->child[0]!=NULL))
{
match(LZGH);
t->child[1]=newExpNode(V ark);
match(RZGH);
}
else { return t; }
}
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
return t;
}
static TreeNode*compound_stmt(void)
{ TreeNode* t=newStmtNode(HanshutiK);
match(LDGH);
if(token==INT)
{ t->child[1]=local_var_declaration();
if(token==RDGH)
{ match(RDGH);
return t;
}
else{ t->child[2]=statement_list(); }
}
else if(token==RDGH)
{ match(RDGH);
return t;
}
else { t->child[0]=statement_list();}
while((token!=RDGH)&&(token!=ENDFILE)) { token=getToken();} match(RDGH);
return t;
}
static TreeNode*local_var_declaration(void)
{ TreeNode*t=NULL;
TreeNode* s=t;
while(token==INT)
{ TreeNode* q=newStmtNode(IntK);
match(INT);
if((q!=NULL)&&(token==ID))
{ TreeNode* p=NULL;
p=newExpNode(Idk);
p->=copyString(tokenString);
match(ID);
p->child[1]=var_declaration();
q->child[0]=p;
if(t==NULL) { t=s=q;}
else
{ s->sibling=q;
s=q; }
}
else
{ syntaxError("unexpected token->");
printToken(token, tokenString);
}
}
return t;
}
static TreeNode*statement_list(void)
{ TreeNode* t=statement();
TreeNode*p=t;
while (IF == token||token==LDGH||ID == token||WHILE == token ||RETURN ==token)
{ TreeNode* q;
q=statement();
if(q!=NULL)
{
if(t==NULL) { t=p=q;}
else
{ p->sibling=q;
p=q;
}
}
}
return t;
}
static TreeNode*statement(void)
{ TreeNode* t=NULL;
switch(token)
{
case IF:
t=selection_stmt(); break;
case ID:
t=expression_stmt(); break;
case SEMI:
t=expression_stmt(); break;
case WHILE:
t=iteration_stmt(); break;
case RETURN:
t=return_stmt(); break;
case LDGH:
t=compound_stmt(); break;
default:
syntaxError("unexpected token->");
printToken(token, tokenString);
token=getToken();
break;
}
return t;
}
static TreeNode*selection_stmt(void)
{ TreeNode* t=newStmtNode(IfK);
match(IF);
match(LPAREN);
if(t!=NULL) { t->child[0]=expression();}
match(RP AREN);
t->child[1]=statement();
if(token==ELSE)
{ match(ELSE);
if(t!=NULL) { t->child[2]=statement();} }
return t;
}
static TreeNode*expression_stmt(void)
{ TreeNode* t=NULL;
if(token==SEMI)
{ return t;}
else
{ t=expression();
match(SEMI);
}
return t;
}
static TreeNode*iteration_stmt(void)
{ TreeNode* t=newStmtNode(WhileK);
match(WHILE);
match(LPAREN);
if(t!=NULL) { t->child[0]=expression();}
match(RP AREN);
if(t!=NULL) { t->child[1]=statement(); }
return t;
}
static TreeNode*return_stmt(void)
{ TreeNode* t=newStmtNode(ReturnK);
match(RETURN);
if (token==SEMI)
{ match(SEMI);
return t;
}
else
{ if(t!=NULL) { t->child[0]=expression();}
}
match(SEMI);
return t;
}
static TreeNode*expression(void)
{ TreeNode* t=var();
if(t==NULL)
{ t=simple_expression(t); }
else
{ TreeNode* p=NULL;
if(token==ASSIGN)
{ p=newStmtNode(AssignK);
p->=t->;
t=p;
match(ASSIGN);
t->child[1]=expression();
return t;
}
else { t=simple_expression(t);}
}
return t;
}
static TreeNode*simple_expression(TreeNode*k)
{ TreeNode* t=additive_expression(k);
k=NULL;
if((token==EQ)||(token==BT)||(token==BQ)||(token==L T)|| (token==LQ)||(token==UEQ))
{ TreeNode*q=newExpNode(Opk);
q->attr.op=token;
q->child[0]=t;
t=q;
match(token);
t->child[1]=additive_expression(k);
return t;
}
return t;
}
static TreeNode*additive_expression(TreeNode*k) { TreeNode* t=term(k);
k=NULL;
while((token==PLUS)||(token==MINUS))
{ TreeNode*q=newExpNode(Opk);
q->attr.op=token;
q->child[0]=t;
match(token);
q->child[1]=term(k);
t=q;
}
return t;
}
static TreeNode*term(TreeNode*k)
{ TreeNode* t=factor(k);
k=NULL;
while((token==TIMES)||(token==OVER))
{ TreeNode*q=newExpNode(Opk);
q->attr.op=token;
q->child[0]=t;
t=q;
match(token);
q->child[1]=factor(k);
}
return t;
}
static TreeNode*factor(TreeNode*k)
{ TreeNode* t=NULL;
if(k!=NULL)
{
if(token==LP AREN)
{ t=call(k); }
else { t=k; }
}
else
{
switch(token)
{
case LP AREN:
match(LP AREN);
t=expression();
match(RP AREN);
break;
case ID:
t=var();
if((token==LP AREN)&&(t->child[0]==NULL))
{ t=call(t); }
break;
case NUM:
t=newExpNode(Constk);
if((t!=NULL)&&(token==NUM))
{ t->attr.val=atoi(tokenString); }
match(NUM);
break;
default:
syntaxError("unexpected token->");
printToken(token, tokenString);
token=getToken();
break;
}
}
return t;
}
static TreeNode*var(void)
{ TreeNode* t=NULL;
if(token==ID)
{ t=newExpNode(Idk);
t->=copyString(tokenString);
match(ID);
if(token==LZGH)
{ match(LZGH);
t->child[0]=expression();
match(RZGH);
}
}
return t;
}
static TreeNode*call(TreeNode*k)
{ TreeNode* t=k;
match(LPAREN);
if(token==RP AREN)
{ match(RP AREN);
return t;
}
else
{ t->child[0]=args();
match(RP AREN);
}
return t;
}
static TreeNode*args(void)
{ TreeNode* t=expression();
TreeNode*p=t;
while(token==DOU)
{ TreeNode* q;
match(DOU);
q=expression();
if(q!=NULL)
{
if(t==NULL) { t=p=q;}
else
{ p->sibling=q;
p=q;
}
}
}
return t;
}
TreeNode*parse(void)
{
TreeNode*t;
token=getToken();
t=program();
if(token!=ENDFILE)
{ syntaxError("code end before\n");}
return t;
}
4.测试结果
测试用例:
词法分析用例:
正确用例:(source.txt)
/* A program to perform Eucild's
Algorithm to compute gcd. */
int gcd (int u, int v)
{
if (v==0) return u;
else return gcd(v,u-u/v*v);
/* u-u/v*v== u mod v */
}
void main(void)
{
int x; int y;
x=input(); y=input();
output(gcd(x,y));
}
>=;<=;==;!=;
错误用例:(source1.txt)
/* A program to perform Eucild's
Algorithm to compute gcd. */
int gcd (int u, int v)
{ ? returk; re9;
! if (v==0) return u;
" else return gcd(v,u-u/v*v);
/* u mod v */
}
语法分析用例:
正确用例:(source2.txt)
/* A program to perform selection sort on a 10 element array. */
int x[10];
int minloc (int a[],int low,int high)
{ int i; int x; int k;
k=low;
x=a[low];
i=low+1;
while (i<high)
{ if (a[i]<x)
{ x=a[i];
k=i; }
i=i+1;
}
return k;
}
void sort (int a[],int low,int high) { int i;int k;
i=low;
while (i<high-1)
{ int t;
k=minloc (a,i,high);
t=a[k];
a[k]=a[i];
a[i]=t;
i=i+1;
}
}
void main (void)
{ int i;
i=0;
while (i<10)
{ x[i]= input;
i=i+1; }
sort (x,0,10);
i=0;
while (i<10)
{ output(x[i]);
i=i+1; }
}
错误用例:(source3.txt)
/* A program to perform Eucild's Algorithm to compute gcd. */ int gcd (int u, int v
{
if (v==0 return u;
else return gcd(v,u-u/v*v);
/* u-u/v*v== u mod v */
}
void main(void)
{
int x, int y;
x=input(); y=input();
output(gcd(x,y));
}
>=;<=;==;!=;
词法分析结果输出:
正确结果:
C:\Documents and Settings\计算机学院专业实验室\桌面\compiler\Debug>compiler sou ce.txt
C-COMPILATION: source.txt
1: /* A program to perform Eucild's
2: Algorithm to compute gcd. */
3: int gcd (int u, int v)
3:reserved word: int
3:ID, name= gcd
3:(
3:reserved word: int
3:ID, name= u
3:,
3:reserved word: int
3:ID, name= v
3:)
4: {
4:{
5: if (v==0) return u;
5:reserved word: if
5:(
5:ID, name= v
5:==
5:NUM, val= 0
5:)
5:reserved word: return
5:ID, name= u
5:;
6: else return gcd(v,u-u/v*v); 6:reserved word: else
6:reserved word: return
6:ID, name= gcd
6:(
6:ID, name= v
6:,
6:ID, name= u
6:-
6:ID, name= u
6:/
6:ID, name= v
6:*
6:ID, name= v
6:)
6:;
7: /* u-u/v*v== u mod v */
8:
9: }
9:}
10: void main(void)
10:reserved word: void
10:ID, name= main
10:(
10:reserved word: void
10:)
11: {
11:{
12: int x; int y;
12:reserved word: int 12:ID, name= x
12:;
12:reserved word: int 12:ID, name= y
12:;
13: x=input(); y=input(); 13:ID, name= x
13:=
13:ID, name= input
13:(
13:)
13:;
13:ID, name= y
13:=
13:ID, name= input
13:(
13:)
13:;
14: output(gcd(x,y));
14:ID, name= output 14:(
14:ID, name= gcd
14:(
14:ID, name= x
14:,
14:ID, name= y
14:)
14:)
14:;
15: }
15:}
16: >=;<=;==;!=;!
16:>=
16:;
16:<=
16:;
16:==
16:;
16:!=
16:;
17:EOF
错误结果:
C:\Documents and Settings\计算机学院专业实验室\桌面\compiler\Debug>compiler sour ce1.txt
C-COMPILATION: source1.txt
1: /* A program to perform Eucild's
2: Algorithm to compute gcd. */
3: int gcd (int u, int v)
3:reserved word: int
3:ID, name= gcd
3:(
3:reserved word: int
3:ID, name= u
3:,
3:reserved word: int
3:ID, name= v
3:)
4: { ? returk; re9;
4:{
4:ERROR: ?
4:ID, name= returk
4:;
4:ID, name= re
4:NUM, val= 9
4:;
5: ! if (v==0) return u;
5:ERROR: !
5:reserved word: if
5:(
5:ID, name= v
5:==
5:NUM, val= 0
5:)
5:reserved word: return
5:ID, name= u
5:;
6: " else return gcd(v,u-u/v*v); 6:ERROR: "
6:reserved word: else
6:reserved word: return
6:ID, name= gcd
6:(
6:ID, name= v
6:,
6:ID, name= u
6:-
6:ID, name= u
6:/
6:ID, name= v
6:*
6:ID, name= v
6:)
6:;
7: /* u mod v */
8: }
8:}
9:EOF
C:\Documents and Settings\计算机学院专业实验室\桌面\compiler\Debug>
语法分析的结果输出:
正确结果:
C:\Documents and Settings\计算机学院专业实验室\桌面\compiler\Debug>compiler sour ce2.txt
C-COMPILATION: source2.txt
Syntax tree
: Int
Id: x
Vark: 10
Int
Id: minloc
Hanshu
Int
Id: a
Vark: -842150451
Int
Id: low
Int
Id: high
Hanshuti
Int
Id: i
Int
Id: x
Int
Id: k
Assign to: k
Id: low
Assign to: x
Id: a
Id: low
Assign to: i
Op:+
Id: low
Const: 1
While
Op:<
Id: i
Id: high
Hanshuti
If
Op:<
Id: a
Id: i
Id: x
Hanshuti
Assign to: x Id: a
Id: i
Assign to: k Id: i
Assign to: i
Op:+
Id: i
Const: 1
Return
Id: k
Void
Id: sort
Hanshu
Int。

相关文档
最新文档