四川大学Cminus语法分析器纯代码.docx

上传人:b****5 文档编号:7225855 上传时间:2023-01-22 格式:DOCX 页数:37 大小:21.76KB
下载 相关 举报
四川大学Cminus语法分析器纯代码.docx_第1页
第1页 / 共37页
四川大学Cminus语法分析器纯代码.docx_第2页
第2页 / 共37页
四川大学Cminus语法分析器纯代码.docx_第3页
第3页 / 共37页
四川大学Cminus语法分析器纯代码.docx_第4页
第4页 / 共37页
四川大学Cminus语法分析器纯代码.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

四川大学Cminus语法分析器纯代码.docx

《四川大学Cminus语法分析器纯代码.docx》由会员分享,可在线阅读,更多相关《四川大学Cminus语法分析器纯代码.docx(37页珍藏版)》请在冰豆网上搜索。

四川大学Cminus语法分析器纯代码.docx

四川大学Cminus语法分析器纯代码

#include

#include

#include

#include

using namespace std;

#define BUFLEN 256

#define MAXLEN 256

#define MAXTOKENLEN 40

#define MAXCHILDREN 4

static int lineno;

static int linepos = 0;//读取的字符在lineBuf的位置

static int EOF_FLAG = false;

static int bufsize = 0;//lineBuf的长度

static char lineBuf[BUFLEN];

FILE * source;

char tokenString[MAXTOKENLEN+1];

string output;//输出文件

enum TokenType

{

ENDFILE,ERROR,

IF,ELSE,INT,RETURN,VOID,WHILE,

ID,NUM,

ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI,LBRACKET,RBRACKET,LBRACE,RBRACE,COMMA,

GT,GEQ,NEQ,LEQ

};

enum StateType

{

START,INASSIGN,INCOMMENT,INNUM,INID,DONE,PRECOMMENT,AFTERCOMMENT

};

struct

{

char* str;

TokenType tok;

}ReserverWords[6]

= { {"if",IF},{"else",ELSE},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE} };

void UnGetNextChar()

{

if (!

EOF_FLAG)

linepos--;

}

int GetNextChar()

{

if(!

(linepos

{

lineno++;

if(fgets(lineBuf,BUFLEN-1,source))

{

bufsize=strlen(lineBuf);

linepos=0;

return lineBuf[linepos++];

}

else

{

EOF_FLAG=true;

return EOF;

}

}

else

{

return lineBuf[linepos++];

}

}

TokenType ReservedLookUp(char * s)

{

int i;

for (i = 0; i < 6; i++)

{

if(!

strcmp(s,ReserverWords[i].str))

{

return ReserverWords[i].tok;

}

}

return ID;

}

TokenType GetToken()

{

StateType state = START;//初始状态为start

bool save;

TokenType CurrentToken;

int tokenStringIndex=0;

string assign="";

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 == '<')||(c=='>')||(c=='=')||(c=='!

'))

{

state = INASSIGN;

assign+=char(c);

}

else if ((c == ' ') || (c == '\t') || (c == '\n'))

save = false;

else if (c == '/')

{

save = false;

state = PRECOMMENT;

}

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 = LPAREN;

break;

case ')':

CurrentToken = RPAREN;

break;

case ';':

CurrentToken = SEMI;

break;

case '[':

CurrentToken = LBRACKET;

break;

case ']':

CurrentToken = RBRACKET;

break;

case '{':

CurrentToken = LBRACE;

break;

case '}':

CurrentToken = RBRACE;

break;

case ',':

CurrentToken = COMMA;

break;

default:

CurrentToken = ERROR;

break;

}

}

    break;

case INCOMMENT:

save = false;

if (c == EOF)

{

state = DONE;

CurrentToken = ENDFILE;

}

else if (c == '*')

state = AFTERCOMMENT;

else

{

state=INCOMMENT;

}

break;

case INASSIGN:

if (c == '=')

{

CurrentToken = EQ;

state=DONE;

}

else if(assign=="!

")

{

UnGetNextChar();

save = false;

CurrentToken = ERROR;

state=DONE;

}

else if(assign=="=")

{

UnGetNextChar();

save = false;

CurrentToken =ASSIGN ;

state=DONE;

}

else if(assign=="<")

{

UnGetNextChar();

save = false;

CurrentToken =LT ;

state=DONE;

}

else

{

UnGetNextChar();

save = false;

CurrentToken =GT ;

state=DONE;

}

break;

case INNUM:

if (!

isdigit(c))

{

UnGetNextChar();

save = false;

state = DONE;

CurrentToken = NUM;

}

break;

case INID:

if (!

isalpha(c))

{

UnGetNextChar();

save = false;

state = DONE;

CurrentToken = ID;

}

break;

case PRECOMMENT:

if(c=='*')

{

state=INCOMMENT;

save=false;

}

else

{

UnGetNextChar();

CurrentToken=OVER;

state=DONE;

}

break;

case AFTERCOMMENT:

save=false;

if(c=='/')

{

state=START;

}

else if(c=='*')

{

state=AFTERCOMMENT;

}

else

{

state=INCOMMENT;

}

break;

case DONE:

default:

state = DONE;

CurrentToken = ERROR;

break;

}

if((save)&&(tokenStringIndex<=MAXTOKENLEN))

{

tokenString[tokenStringIndex++]=(char)c;

}

if(state==DONE)

{

tokenString[tokenStringIndex]='\0';

if(CurrentToken==ID)

{

CurrentToken=ReservedLookUp(tokenString);

}

}

}

return CurrentToken;

}

enum NodeKind//节点类型

{

FuncK,IntK,IdK,ParamsK,ParamK,CompK,ConstK,CallK,ArgsK,VoidK,Var_DeclK,Arry_DeclK,Arry_ElemK,AssignK/*,WhileK*/,OpK,

Selection_StmtK,Iteration_StmtK,Return_StmtK

}; 

struct//节点类型和字符串关系

{

string str;

NodeKind nk;

}nodekind[18]

= { {"Funck",FuncK},{"IntK",IntK},{"IdK",IdK},{"ParamsK",ParamsK},{"ParamK",ParamK},{"CompK",CompK},{"ConstK",ConstK},{"CallK",CallK},

{"ArgsK",ArgsK},{"VoidK",VoidK},{"Var_DeclK",Var_DeclK},{"Arry_DeclK",Arry_DeclK},{"Arry_ElemK",Arry_ElemK},{"AssignK",AssignK},

/*{"WhileK",WhileK},*/{"OpK",OpK},{"Selection_StmtK",Selection_StmtK},{"Iteration_StmtK",Iteration_StmtK},{"Return_StmtK",Return_StmtK}};

struct//符号与字符串关系

{

string str;

TokenType tk;

}Ope[11]

= { {"=",ASSIGN},{"==",EQ},{"<",LT},{"+",PLUS},{"-",MINUS},{"*",TIMES},{"/",OVER},

{">",GT},{">=",GEQ},{"!

=",NEQ},{"<=",LEQ}};

string OpeLookUp(TokenType tk)//操作符转换为字符串

{

int i;

for(i=0;i<11;i++)

{

if(tk==Ope[i].tk)

{

return Ope[i].str;

}

}

}

string Change(NodeKind nk)//节点类型转换为字符串

{

int i;

for(i=0;i<19;i++)

{

if(nk==nodekind[i].nk)

{

return nodekind[i].str;

break;

}

}

}

TokenType token;

struct TreeNode

{

struct TreeNode *  child[4];

struct TreeNode *  sibling;

int lineno;

    NodeKind nodekind;

union { TokenType op; int val; const char * name;} attr;

};

TreeNode * declaration_list(void);

TreeNode * declaration(void);

TreeNode * params(void);

TreeNode * param_list(TreeNode * p);

TreeNode * param(TreeNode * p);

TreeNode * compound_stmt(void);

TreeNode * local_declaration(void);

TreeNode * statement_list(void);

TreeNode * statement(void);

TreeNode * expression_stmt(void);

TreeNode * selection_stmt(void);

TreeNode * iteration_stmt(void);

TreeNode * return_stmt(void);

TreeNode * expression(void);

TreeNode * var(void);

TreeNode * simple_expression(TreeNode * p);

TreeNode * additive_expression(TreeNode * p);

TreeNode * term(TreeNode * p);

TreeNode * factor(TreeNode * p);

TreeNode * call(TreeNode * p);

TreeNode * args(void);

char * copyString(char *s)

{

int n;

char * t;

if (s==NULL)

{

return NULL;

}

n=strlen(s)+1;

t=(char*)malloc(n);

if (t==NULL){

}

else

{

strcpy(t,s);

}

return t;

}

void match(TokenType expected)

{

if(token==expected)

token=GetToken();

else

{

cout<<"unexpected token"<

}

}

TreeNode * newNode(NodeKind kind)

TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));

int i;

if (t==NULL)

{

;

}

else {

for (i=0;i<4;i++) 

{

t->child[i] = NULL;

}

    t->sibling = NULL;

    t->nodekind = kind;

    

    t->lineno = lineno;

if (kind==OpK||kind==IntK||kind==IdK)

{

if(kind==IdK)

t->attr.name = "";

}

if(kind==ConstK)

t->attr.val = 0;

}

return t;

}

TreeNode * declaration_list(void)//declaration_list->declaration_list declaration | declaration

{

TreeNode * t = declaration();

TreeNode * p =t;

 while((token!

=INT)&&(token!

=VOID)&&(token!

=ENDFILE))

 {   

 token = GetToken();

 if(token==ENDFILE)

 break;

 }

while(token==INT||token==VOID)

{

TreeNode * q;

q = declaration();

if (q!

=NULL)

{

if (t==NULL)

{

t=p=q;

}

else

{

p->sibling=q;

p=q;

}

}

}

match(ENDFILE);

return t;

}

TreeNode * declaration(void)

{

TreeNode * t = NULL;

TreeNode * p = NULL;

TreeNode * q = NULL;

TreeNode * s = NULL;

TreeNode * a = NULL;

if (token==INT)

{

p=newNode(IntK);

match(INT);

}

else//(token==VOID)

{

p=newNode(VoidK);

match(VOID);

}

if(p!

=NULL&&token==ID)

{

q = newNode(IdK);

q->attr.name = copyString(tokenString); 

match(ID);

if (token==LPAREN)

{

t = newNode(FuncK);

t->child[0] = p;   //p是t子节点

t->child[1] = q;

match(LPAREN);

t->child[2] = params();

match(RPAREN);

t->child[3] = compound_stmt();

}

else if (token==LBRACKET)

{

t = newNode(Var_DeclK);

a = newNode(Arry_DeclK);

t->child[0] = p;   //p是t子节点

t->child[1] = a;

match(LBRACKET);

s = newNode(ConstK);

s->attr.val = atoi(tokenString);

match(NUM);

a->child[0]=q;

a->child[1]=s;

match(RBRACKET);

match(SEMI);

}

else if (token==SEMI)

{

t = newNode(Var_DeclK);

t->child[0] = p;

t->child[1] = q;

match(SEMI);

}

else

{

;

}

}

else

{

;

}

return t;

}

TreeNode * params(void)//params_list | void

{

TreeNode * t = newNode(ParamsK);

TreeNode * p  = NULL;

if (token==VOID)

{

p = newNode(VoidK);

match(VOID);

if (token==RPAREN)

{

if(t!

=NULL)

t->child[0] = p;

}

else//参数列表为(void id,[……]) 

{

t->child[0] = param_list(p);

}

}

else//(token==INT)

{

t->child[0] = param_list(p);

}

return t;

}

TreeNode * param_list(TreeNode * k)//params_list->params_list,param | param

{

TreeNode * t = param(k);

TreeNode * p = t; 

k = NULL;//没有要传给param的VoidK,所以将k设为NULL

while (token==COMMA)

{

TreeNode * q = NULL;

match(COMMA);

q = param(k);

if (q!

=NULL)

{

if (t==NULL)

{

t=p=q;

}

else

{

p->sibling = q;

p = q;

}

}

}

return t;

}

TreeNode * param(TreeNode * k)

{

Tr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 研究生入学考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1