mini_c

目标:制作一个简单的mini_c编译器

以下仅部分代码,仅供参考使用

这里写目录标题

  • mini_c
      • 目标:制作一个简单的mini_c编译器
        • 以下仅部分代码,仅供参考使用
    • 1. 词法分析部分
    • 2. 语法分析部分
    • 3. 语义分析
    • 4. 目标代码生成(未完成)

1. 词法分析部分

词法分析这里使用的是有限状态自动机,不多说直接上代码了。

//token define
enum state{start,identifier_accepted,number_accepted,plus_accepted,minus_accepted,multiply_accepted,left_bracket_1_accepted,right_bracket_1_accepted,left_bracket_2_accepted,right_bracket_2_accepted,left_bracket_3_accepted,right_bracket_3_accepted,divide,comment_body,comment_right,comment_accepted,bigger,big,smaller,small,assignment,equal,un,unequal,and_accepted,end_accepted,whitespace_accepted,keyword_accepted,error,end_of_file,dot_accepted,to_accepted
};/*    accepted token state:id:identifier_acceptednum:number_accepted+:plus_accepted-:minus_accepted*:multiply_accepted/:divide(,):left_bracket_1_accepted,right_bracket_1_accepted[,]:left_bracket_2_accepted,right_bracket_2_accepted{,}:left_bracket_3_accepted,right_bracket_3_accepted>:bigger<:smaller>=:big<=:small=:assignment==:equal!=:unequal,:and_accepted;:end_acceptedkeyword:keyword_accepted.:dot_accepted::to_accepted
*///token define
typedef struct Token{char token_string[1000];enum state token_state;
} tokenInfo;//keyword define
const char* keywords[13] = {"else","if","switch","case","default","int","void","struct","return","break","goto","while","for"};//use to justify whether the character is a letter
int isLetter(char current_char){if((current_char<='z' && current_char>='a' )||(current_char>='A' && current_char<='Z') ){return true;}else{return false;}
}//use to justify whether the character is a number
int isNumber(char current_char){if(current_char<='9' && current_char>='0'){return true;}else{return false;}
}//use to justify whether the token is a keyword
int isKeyword(char id[],int length){id[length] = '\0';for(int i=0;i<13;i++){if(strcmp(id,keywords[i]) == 0){return true;}}return false;
}//use to print token string
void printToken(char token[],int length){for(int i=0;i<length;i++){//printf("%c",token[i]);}token[length] = '\0';//printf("\n");
}//use to make token string and token state into token information struct
tokenInfo getTokenInfo(char token[],int length,enum state token_state){tokenInfo token_info;token[length] = '\0';// for(int i=0;i<length;i++){//   //printf("%c",token[i]);// }strcpy(token_info.token_string,token);token_info.token_state = token_state;return token_info;
}//use to read a token from the file
tokenInfo lexical_analyzer(FILE* file){int cnt1 = 0;int cnt2 = 0;enum state current_state = start;char token[1000][1050];char current_char = getc(file);while(current_char!=EOF || current_state!=start){switch(current_state){case start:{if(isLetter(current_char)){current_state = identifier_accepted;token[cnt1][cnt2++] = current_char; }else if(isNumber(current_char)){current_state = number_accepted;token[cnt1][cnt2++] = current_char;}else{switch(current_char){case '+':{current_state = plus_accepted;token[cnt1][cnt2++] = current_char;break;}case '-':{current_state = minus_accepted;token[cnt1][cnt2++] = current_char;break;}case '*':{current_state = multiply_accepted;token[cnt1][cnt2++] = current_char;break;}case '(':{current_state = left_bracket_1_accepted;token[cnt1][cnt2++] = current_char;break;}case ')':{current_state = right_bracket_1_accepted;token[cnt1][cnt2++] = current_char;break;}case '[':{current_state = left_bracket_2_accepted;token[cnt1][cnt2++] = current_char;break;}case ']':{current_state = right_bracket_2_accepted;token[cnt1][cnt2++] = current_char;break;}case '{':{current_state = left_bracket_3_accepted;token[cnt1][cnt2++] = current_char;break;}case '}':{current_state = right_bracket_3_accepted;token[cnt1][cnt2++] = current_char;break;}case '/':{current_state = divide;token[cnt1][cnt2++] = current_char;break;}case '>':{current_state = bigger;token[cnt1][cnt2++] = current_char;break;}case '<':{current_state = smaller;token[cnt1][cnt2++] = current_char;break;}case '=':{current_state = assignment;token[cnt1][cnt2++] = current_char;break;}case '!':{current_state = un;token[cnt1][cnt2++] = current_char;break;}case ',':{current_state = and_accepted;token[cnt1][cnt2++] = current_char;break;}case ';':{current_state = end_accepted;token[cnt1][cnt2++] = current_char;break;}case ' ':case '\n':case '\t':{current_state = whitespace_accepted;break;}case '.':{current_state = dot_accepted;token[cnt1][cnt2++] = current_char;break;}case ':':{current_state = to_accepted;token[cnt1][cnt2++] = current_char;break;}default:{//printf("unknown character!!\n");tokenInfo info = {"\0",error};//if(!feof(file))//fseek(file,-1,SEEK_CUR);return info;break;}}}current_char = getc(file);break;}case identifier_accepted:{if(!isLetter(current_char)){if(isKeyword(token[cnt1],cnt2)){current_state = keyword_accepted;}else{//printf("an identifier is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;}}else{current_state = identifier_accepted;token[cnt1][cnt2++] = current_char; current_char = getc(file);}break;}case number_accepted:{if(!isNumber(current_char)){//printf("a constant is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;}else{current_state = number_accepted;token[cnt1][cnt2++] = current_char; current_char = getc(file);}break;}case plus_accepted:{//printf("a plus is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;              break;}case minus_accepted:{//printf("a minus is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;               break;}case multiply_accepted:{//printf("a multiply is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case left_bracket_1_accepted:{//printf("a left bracket_1 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case left_bracket_2_accepted:{//printf("a left bracket_2 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case left_bracket_3_accepted:{//printf("a left bracket_3 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case right_bracket_1_accepted:{//printf("a right bracket_1 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case right_bracket_2_accepted:{//printf("a right bracket_2 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case right_bracket_3_accepted:{//printf("a right bracket_3 is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case divide:{if(current_char!='*'){//printf("a divide is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}else{current_state = comment_body;token[cnt1][cnt2++] = current_char;current_char = getc(file);break;}}case comment_body:{if(current_char!='*'){current_state = comment_body;token[cnt1][cnt2++] = current_char;current_char = getc(file);break;}else{current_state = comment_right;token[cnt1][cnt2++] = current_char;current_char = getc(file);break;}}case comment_right:{if(current_char=='/'){current_state = comment_accepted;token[cnt1][cnt2++] = current_char;current_char = getc(file);break;}else{current_state = comment_body;token[cnt1][cnt2++] = current_char;current_char = getc(file);break;}}case comment_accepted:{//注释识别但是不返回这个token//printf("a comment is accepted!\n");printToken(token[cnt1],cnt2);cnt2 = 0;current_state = whitespace_accepted;break;}case bigger:{if(current_char!='='){//printf("a bigger is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}else{current_state = big;token[cnt1][cnt2++] = current_char;current_char = getc(file);}}case big:{//printf("a maybig is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case smaller:{if(current_char!='='){//printf("a smaller is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}else{current_state = small;token[cnt1][cnt2++] = current_char;current_char = getc(file);}}case small:{//printf("a maysmall is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case assignment:{if(current_char!='='){//printf("an assignment is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}else{current_state = equal;token[cnt1][cnt2++] = current_char;current_char = getc(file);}}case equal:{//printf("an equal is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case un:{if(current_char!='='){//printf("an un is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}else{current_state = unequal;token[cnt1][cnt2++] = current_char;current_char = getc(file);}}case unequal:{//printf("an unequal is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case and_accepted:{//printf("an and is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case end_accepted:{//printf("an end is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case whitespace_accepted:{//空白符识别但是不返回tokenif(current_char == ' ' || current_char == '\n' || current_char == '\t'){current_state = whitespace_accepted;current_char = getc(file);}else{printf("a whitespace is accepted!\n");printf("\n");current_state = start;}break;}case keyword_accepted:{//printf("a keyword is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;    break;}case dot_accepted:{//printf("a dot is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}case to_accepted:{//printf("a to is accepted!\n");printToken(token[cnt1],cnt2);tokenInfo info = getTokenInfo(token[cnt1++],cnt2,current_state);if(!feof(file))fseek(file,-1,SEEK_CUR);return info;cnt2 = 0;current_state = start;break;}default:{break;}}}if(current_char == EOF){tokenInfo info = {"",end_of_file};return info;} }

简单总结:
简单来说我的思路就是首先判断token的第一个字符应当属于哪个token,然后再进行一步步转化直到进入token的接收态。
该部分代码最大的缺点是很多代码段其实是重复的,但是我没有进行函数封装。

2. 语法分析部分

语法分析部分采用的是简单消除了左递归的递推文法。(吐槽!老师给的伪代码有很大问题,想要使用得自己更改)
大致的逻辑如下图:
(图太大了等我有时间再传= =)
递推关系式的实现代码如下:
(有些功能函数未在该代码中写出)
((递推关系式和简单解释看注释(注释中英文混杂的原因是一开始编辑器没调好中文全乱码只能写英文T T)))

enum nodeType{functionNode,paramsNode,compoundNode,ifStmtNode,switchStmtNode,whileStmtNode,forStmtNode,//6returnStmtNode,breakStmtNode,caseStmtNode,defaultStmtNode,addNode,multNode,structNode,//13IDNode,NUMNode,assignNode,relopNode,arrayNode,funcallNode};//19enum variable_type{INT,VOID,STRUCT,NEITHER};
typedef struct treeNode{enum state token_type;  enum nodeType node_type;char id_string[1000];struct treeNode *sibling;/*function[name,params,body]*/struct treeNode *params;struct treeNode *body;/*params[type,id]*/enum variable_type type;/*compound[decl,body]*/struct treeNode *decl;/*if_stmt[test,then,else]*/struct treeNode *test;struct treeNode *then;struct treeNode *else_stmt;/*switch_stmt[test,case]*/struct treeNode *case_stmt;/*while_stmt[test,body]*//*for_stmt[part1,part2,part3,body]*/struct treeNode *part1;struct treeNode *part2;struct treeNode *part3;/*return_stmt[returnexp]*/struct treeNode *returnexp;/*break_stmt[]*//*case_stmt[test,body]*//*default_stmt[body]*//*add/mult[left,right]*/struct treeNode *left;struct treeNode *right;/*assign/relop[lvalue,rvalue]*/struct treeNode *lvalue;struct treeNode *rvalue;/*struct[struct_name,memName]*/struct treeNode *struct_name;/*array[array_name,index_exp]*/struct treeNode *array_name;struct treeNode *index_exp;/*funcall[funname,args_list]*/struct treeNode *fun_name;struct treeNode *args_list;/*ID[id]*//*NUM[value]*/int value;
}treeNode;
/*--begin--declaration-list()--*/
/*program               ->   declaration-listdeclaration-list    ->   declaration { declaration }*/treeNode* declaration_list(){treeNode *root = declaration();treeNode *p = root;while(!feof(file)){treeNode *q = declaration();p->sibling = q;p=q;}return root;
}/*--end--declaration-list()--*//*--begin--declaration()--*/
/*declaration           ->   variable-declaration | function-declarationvariable-declaration     ->   type-specifier ID ["[" NUM "]"]type-specifier           ->   int | void |struct-specifierstruct-specifier        ->   struct [ID] ["{" struct-declaration-list "}"]struct-declaration-list ->  int ID ";" { int ID ";"}function-declaration    ->   type-specifier ID "(" parameters ")" compound-statementparameters               ->   parameter-list | voidparameter-list         ->   parameter {"," parameter}parameter                ->   type-specifier ID ["[" "]"]
*/treeNode* declaration(){enum variable_type t = type_specifier();if(t==NEITHER) return NULL;treeNode *d = decl_body(t);return d;
}enum variable_type type_specifier(){if(currentToken.token_state == keyword_accepted){if(keyword_cmp(currentToken.token_string,"int")){match(keyword_accepted);return INT;}else if(keyword_cmp(currentToken.token_string,"void")){match(keyword_accepted);return VOID;}else if(keyword_cmp(currentToken.token_string,"struct")){match(keyword_accepted);tokenInfo currentT = currentToken;addStructType(currentToken.token_string);//addtype(ID,currentToken.token_string);//unimplementedif(currentToken.token_state==left_bracket_3_accepted){//struct可以在声明的时候加入变量,所以要测试//有没有左括号match(left_bracket_3_accepted);while(currentToken.token_state!=right_bracket_3_accepted){match(keyword_accepted);//这个取得是int,因为只有这个类型所以只取这个tokenInfo tt = match(identifier_accepted);if(currentToken.token_state==left_bracket_2_accepted){//有可能声明的是一个数组match(left_bracket_2_accepted);addStructMemArrayType(tt.token_string,currentT.token_string,getCurrentTokenValue());tokenInfo tt2 = match(number_accepted);match(right_bracket_2_accepted);//addtype(ID,ARRAY,STRUCT_MEMBER,STRUCT_NAME);printf("struct member %s [%s] created\n",tt.token_string,tt2.token_string);match(end_accepted);}else{//addtype(ID,STRUCT_MEMBER,STRUCT_NAME);addStructMemType(tt.token_string,currentT.token_string);printf("struct member %s created\n",tt.token_string);match(end_accepted);}}match(right_bracket_3_accepted);return STRUCT;}}else{return NEITHER;}}return NEITHER;
}treeNode* decl_body(enum variable_type t){treeNode *p = NULL;tokenInfo tt = match(identifier_accepted);//考虑到不管是变量还是函数都有ID,直接取ID//addtype(ID);//由于不知道这里ID是什么类型,所以先创一个ID//printf("currentToken:%s\n",currentToken.token_string);switch(currentToken.token_state){case left_bracket_1_accepted:{p = fun_decl(t,tt.token_string);//这里考虑再传个ID名字进去break;}case end_accepted:{//addtype(ID,ID_NAME);addIdType(tt.token_string);printf("int %s created\n",tt.token_string);match(end_accepted);break;}case left_bracket_2_accepted:{match(left_bracket_2_accepted);addArrayType(tt.token_string,getCurrentTokenValue());tokenInfo tt2 = match(number_accepted);match(right_bracket_2_accepted);match(end_accepted);//addtype(ID,ARRAY_NAME,NUM);printf("array %s[%s] created\n",tt.token_string,tt2.token_string);break;}default:{//printf("decl_body error");break;}}return p;}treeNode* fun_decl(enum variable_type t,char name[]){treeNode *p=NULL;//addtype(ID,FUNCTION_NAME);//addFunType(name);printf("function %s() created\n",name);p=new_node();p->node_type=functionNode;printf("treeNode function has created\n");strcpy(p->id_string,name);match(left_bracket_1_accepted);p->params = param_list();match(right_bracket_1_accepted);p->body = compound_stmt();return p;}treeNode* param_list(){treeNode *t=NULL,*p=NULL,*root=NULL;while(currentToken.token_state!=right_bracket_1_accepted){t=new_node();t->node_type=paramsNode;t->type = type_specifier();tokenInfo tt = match(identifier_accepted);strcpy(t->id_string,tt.token_string);if(currentToken.token_state==left_bracket_2_accepted){match(left_bracket_2_accepted);match(right_bracket_2_accepted);//addtype(ID,REFERENCE);addReferencedType(tt.token_string);printf("parameter %s[] created\n",tt.token_string);}else{addIdType(tt.token_string);printf("parameter %s created\n",tt.token_string);}if(root==NULL){root=t;}if(p!=NULL){p->sibling = t;}p=t;if(currentToken.token_state!=right_bracket_1_accepted){match(and_accepted);}}return root;
}
/*--end--declaration()--*//*--begin--compound_stmt()--*/
/*compound-statement        ->   "{" [local-declarations] [statment-list] "}"local-declarations      ->   {variable-declaration}statement-list            ->   {statement}*/
treeNode* compound_stmt(){treeNode *f=NULL;//if(currentToken.token_state==left_bracket_3_accepted){match(left_bracket_3_accepted);//建个新的域typeList *newTypeList = new_list_node();list->sibling = newTypeList;list = newTypeList;f = new_node();f->node_type=compoundNode;printf("treeNode compound is created\n");while(currentToken.token_state==keyword_accepted && (keyword_cmp(currentToken.token_string,"int")||keyword_cmp(currentToken.token_string,"struct"))){f->decl = declaration();}//printf("stmt_list entered\n");f->body = stmt_list();//printf("fun_body:current:%s\n",currentToken.token_string);match(right_bracket_3_accepted);/*}else{f = new_node();printf("treeNode compound is created\n");f->decl = declaration();//printf("stmt_list entered\n");f->body = stmt_list();}*/return f;
}treeNode* stmt_list(){//int cnt = 1;treeNode *t = statement();treeNode *r = t;//printf("stmt_list:current:%s\n",currentToken.token_string);while(currentToken.token_state!=right_bracket_3_accepted){treeNode *q = statement();//printf("%d\n",cnt++);t->sibling = q;t=q;}return r;
}/*--end--compound_stmt()--*//*--begin--statement()--*/
/*statement                 ->   compound-statement | expression-statement |selection-statement | labeled-statement | iteration-statement | jump-statementexpression-statement   ->   [expression]*/treeNode* statement(){treeNode *t=NULL;//printf("statement entered\n\n\n\n");//printf("current:%s\n", currentToken.token_string);switch(currentToken.token_state){case keyword_accepted:{if(keyword_cmp(currentToken.token_string,"if")||keyword_cmp(currentToken.token_string,"switch")){t=selection_stmt();}else if(keyword_cmp(currentToken.token_string,"while")||keyword_cmp(currentToken.token_string,"for")){t=iteration_stmt();}else if(keyword_cmp(currentToken.token_string,"return")||keyword_cmp(currentToken.token_string,"break")){t=jump_stmt();}else if(keyword_cmp(currentToken.token_string,"case")||keyword_cmp(currentToken.token_string,"default")){t=labeled_stmt();}else{printf("keyword error\n");//t = compound_stmt();}break;}case left_bracket_3_accepted:{t=compound_stmt();break;}default:{//printf("exp_stmt entered\n");t=exp_stmt();break;}}return t;
}treeNode* exp_stmt(){treeNode *t=NULL;if(currentToken.token_state!=end_accepted){t=expression();}match(end_accepted);return t;
}/*--end--statement()--*//*--begin--selection_stmt()--*/
/*selection-statement       ->   if "(" expression ")" statement [else statement] | switch "(" expression ")" statement*/
treeNode* selection_stmt(){treeNode *t = new_node();switch(currentToken.token_state){case keyword_accepted:{if(keyword_cmp(currentToken.token_string,"if")){printf("treeNode if has created\n");t->node_type=ifStmtNode;match(keyword_accepted);match(left_bracket_1_accepted);t->test = expression();match(right_bracket_1_accepted);t->then = statement();if(keyword_cmp(currentToken.token_string,"else")){match(keyword_accepted);t->else_stmt = statement();}}else if(keyword_cmp(currentToken.token_string,"switch")){printf("treeNode switch has created\n");t->node_type=switchStmtNode;match(keyword_accepted);match(left_bracket_1_accepted);t->test = expression();match(right_bracket_1_accepted);t->case_stmt = statement();}else{printf("keyword error");}break;}default:{printf("selection error");break;}}return t;
}/*--end--selection_stmt()--*//*--begin--iteration_stmt()--*/
/*iteration-statement       ->   while "(" expression ")" statement |for "(" [expression] ";" [expression] ";" [expression] ")" statement
*/
treeNode* iteration_stmt(){treeNode *t = new_node();switch(currentToken.token_state){case keyword_accepted:{if(keyword_cmp(currentToken.token_string,"while")){printf("treeNode while has created\n");t->node_type=whileStmtNode;//printf("------------");match(keyword_accepted);match(left_bracket_1_accepted);t->test = expression();match(right_bracket_1_accepted);t->body = statement();}else if(keyword_cmp(currentToken.token_string,"for")){printf("treeNode for has created\n");t->node_type=forStmtNode;match(keyword_accepted);match(left_bracket_1_accepted);t->part1 = expression();match(end_accepted);t->part2 = expression();match(end_accepted);t->part3 = expression();match(right_bracket_1_accepted);t->body = statement();}else{printf("keyword error");}break;}default:{printf("iteration error");break;}}return t;
}/*--end--iteration_stmt()--*//*--begin--jump_stmt()--*/
/*jump-statement        ->   return [expression] ";" |break ";"*/
treeNode* jump_stmt(){treeNode *t = new_node();switch(currentToken.token_state){case keyword_accepted:{if(keyword_cmp(currentToken.token_string,"return")){printf("treeNode return has created\n");t->node_type=returnStmtNode;match(keyword_accepted);t->returnexp = expression();match(end_accepted);}else if(keyword_cmp(currentToken.token_string,"break")){t->node_type=breakStmtNode;match(keyword_accepted);printf("treeNode break has created\n");match(end_accepted);}else{printf("keyword error");}break;}default:{printf("jump error");break;}}//printf("------------------\n");//printf("current:%s",currentToken.token_string);return t;
}/*--end--jump_stmt()--*//*--begin--labeled_stmt()--*/
/*labeled-statement     ->   case conditional-expression ':'  statement |default ":" statement
*/treeNode* labeled_stmt(){treeNode *t=new_node();switch(currentToken.token_state){case keyword_accepted:{if(keyword_cmp(currentToken.token_string,"case")){printf("treeNode case has created\n");t->node_type=caseStmtNode;match(keyword_accepted);t->test = add_exp();match(to_accepted);t->body = statement();}else if(keyword_cmp(currentToken.token_string,"default")){printf("treeNode default has created\n");t->node_type=defaultStmtNode;match(keyword_accepted);match(to_accepted);t->body = statement();}else{printf("keyword error");}break;}default:{printf("labeled error");break;}}return t;
}
/*--end--labeled_stmt()--*//*--begin--expression()==*/
/*expression                    ->   assighment-expression | conditional-expressionassignment-expression     ->   variavle "=" expressionvariable                  ->   ID [ "[" NUM "]" | "."ID]conditional-expression       ->   additive-expression [relation-operator additive-expression]relation-operator            ->   "<=" | ">=" | "<" | ">" | "==" | "!="additive-expression           ->   multiplicative-expression {add-operator multiplicative-expression}add-operator              ->   "+" | "-"multiplicative-expression ->   primary-expression {mul-operator primary-expression}mul-operator                ->   "*" | "/"primary-expression         ->   variable | NUM | "(" expression ")" | call-functioncall-function                ->   ID "(" [argument-list] ")"argument-list             ->   expression { "," expression}
*/
treeNode* expression(){treeNode *p = add_exp();treeNode *t = NULL;//printf("expression:current:%s\n",currentToken.token_string);switch(currentToken.token_state){case assignment :{match(assignment);t = new_node();printf("treeNode assign has created\n");t->node_type=assignNode;t->lvalue = p;t->rvalue = expression();break;}case bigger:case smaller:case big:case small:case equal:case unequal:{t = new_node();t->token_type = currentToken.token_state;match(currentToken.token_state);printf("treeNode relop has created\n");t->node_type=relopNode;t->lvalue = p;t->rvalue = add_exp();break;}default:{t = p;}}return t;
}treeNode* add_exp(){treeNode *t = mul_exp();while(currentToken.token_state==plus_accepted || currentToken.token_state == minus_accepted){treeNode *newtemp= new_node();newtemp->token_type = currentToken.token_state;match(currentToken.token_state);printf("treeNode add has created\n");newtemp->node_type=addNode;newtemp->left = t;newtemp->right = mul_exp();t = newtemp;}return t;
}treeNode* mul_exp(){treeNode *t = postfix_exp();while(currentToken.token_state==multiply_accepted || currentToken.token_state == divide){treeNode *newtemp= new_node();newtemp->token_type = currentToken.token_state;match(currentToken.token_state);printf("treeNode mult has created\n");newtemp->node_type=multNode;newtemp->left = t;newtemp->right = postfix_exp();t = newtemp;}return t;
}treeNode* postfix_exp(){treeNode *t = primary_exp();switch(currentToken.token_state){case dot_accepted:{match(dot_accepted);treeNode *p = new_node();printf("treeNode struct has created\n");p->node_type=structNode;p->struct_name = t;strcpy(p->id_string,currentToken.token_string);match(identifier_accepted);t = p;break;}case left_bracket_2_accepted:{match(left_bracket_2_accepted);treeNode *p = new_node();printf("treeNode array has created\n");p->node_type=arrayNode;p->array_name = t;p->index_exp = expression();match(right_bracket_2_accepted);t=p;break;}case left_bracket_1_accepted:{match(left_bracket_1_accepted);treeNode *p = new_node();printf("treeNode funcall has created\n");p->node_type=funcallNode;p->fun_name = t;p->args_list = optional_args();match(right_bracket_1_accepted);t = p;break;}default:{//printf("error");break;}}return t;
}treeNode* primary_exp(){treeNode *t = NULL;switch(currentToken.token_state){case left_bracket_1_accepted:{match(left_bracket_1_accepted);t = expression();match(right_bracket_1_accepted);break;}case identifier_accepted:{t = new_node();  printf("treeNode ID %s has created\n",currentToken.token_string); t->node_type=IDNode;strcpy(t->id_string,currentToken.token_string);match(identifier_accepted);   break;}case number_accepted:{t = new_node();printf("treeNode NUM has created\n");t->node_type=NUMNode;t->token_type = number_accepted;t->value = getCurrentTokenValue();match(number_accepted);break;}default:{printf("primary_exp error");break;}}return t;
}treeNode* optional_args(){treeNode *r = expression();treeNode *t = r;while(currentToken.token_state!= right_bracket_1_accepted){treeNode *p = expression();t->sibling = p;t = p ;match(and_accepted);}return r;
}/*--end--expression()--*/

简单总结:
递推关系式本身其实没太大问题,但是按照这个递推关系式得出来的文法相较于C语言文法会有一些限制:必须将变量全部申明完成之后才可以进行语句,且变量无法初始化。
(懒得删测试注释了= =)

3. 语义分析

在此只建立了一个变量表。
变量表是由一个域链表和域中变量名表组成的,变量名表使用的是哈希表的方式存储的。

enum typeType{idType,arrayType,funType,structType,structMemType,referencedType,structMemArrayType};typedef struct TypeNode{enum typeType thisType;char type_id[1000];struct TypeNode *sibling;/*arrayType*/int type_size;/*structType*/char parent_struct_name[1000];int value;} typeNode;typedef struct TypeList{struct TypeList *sibling;typeNode *localTypeList[101];//这里用质数101来算
} typeList;//这个是用来加到变量表里面的
void addIdType(char id[]){//idint thisHashValue = getHashValue(id);//printf("%d\n\n",thisHashValue);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = idType;strcpy(newNode->type_id,id);//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}}void addStructType(char id[]){//structint thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = structType;strcpy(newNode->type_id,id);//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}
}void addFunType(char id[]){int thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = funType;strcpy(newNode->type_id,id);//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}
}void addReferencedType(char id[]){int thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = referencedType;strcpy(newNode->type_id,id);//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}
}void addArrayType(char id[],int num){int thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = arrayType;strcpy(newNode->type_id,id);newNode->type_size = num;//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}
}void addStructMemType(char id[],char parentId[]){int thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = structMemType;strcpy(newNode->type_id,id);strcpy(newNode->parent_struct_name,parentId);//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}
}void addStructMemArrayType(char id[],char parentId[],int num){int thisHashValue = getHashValue(id);typeNode *node = list->localTypeList[thisHashValue];typeNode *newNode = new_type_node();newNode->thisType = structMemType;strcpy(newNode->type_id,id);strcpy(newNode->parent_struct_name,parentId);newNode->type_size = num;//插到链表里面if(node==NULL) node = newNode;else{newNode->sibling = node->sibling;node->sibling = newNode;}}

自我反思:
语义分析其实没仔细看。。。所以只是做了一个简单的变量表,而且自认为是有错误的,比如:域是链表形式的,只能顺序读= =
而且这个代码的重复度。。。非常高!完全可以一个函数解决的,只是偷懒不想整合了。。ヽ(≧□≦)ノ

4. 目标代码生成(未完成)

mini_c编译器的简单代码逻辑相关推荐

  1. java简单代码逻辑实现数学黑洞6174

    import java.util.Arrays;public class Prac02 {public static void main(String[] args) {int num=(int)(( ...

  2. 代码逻辑是分方法写好 还是在一个方法写好_这一团糟的代码,真的是我写的吗?...

    阿里妹导读:你有没有遇到过这种情况:过几周或者几个月之后,再看到自己写的代码,感觉一团糟,不禁怀疑人生?我们每天都与代码打交道,但当被问道什么是好的代码时,很多人可能会先愣一下,然后给出的回答要么比较 ...

  3. 技术工坊|解密区块链DApp的代码逻辑,从请求到数据存储都要经历什么?(上海)...

    请求-调用-执行-存储,不论是网站还是APP,这是从代码到应用的运行逻辑,那么区块链世界的Dapp应用是否也会执行这套逻辑?Dapp的代码逻辑与传统app有什么不同? 6月20日,由HiBlock区块 ...

  4. 【风控流程】大数据风控代码逻辑

    写在前面: 此文为一个简单的风控决策模型的开发逻辑及细节,仅供科技金融领域做风控建模的新手参考,具备能够看懂并且尝试风控模型开发及部署的能力. 跃跃欲试吧. [博客地址]:https://blog.c ...

  5. 内联函数和编译器对Go代码的优化

    什么是内联函数 图片版权:Renee French. 在很多讲 Go 语言底层的技术资料和博客里都会提到内联函数这个名词,也有人把内联函数说成代码内联.函数展开.展开函数等等,其实想表达的都是 Go ...

  6. 简述如何书写工程化的简单代码

    在坛子里混了这么久,看了很多同学的代码,感觉到大家的代码,学校里面的书生气有点重,对于细节考虑不够,有时候,感觉和吃了颗苍蝇一样,确实很不舒服. 这里根据我个人的经验,给大家简述一下,工程化代码,以及 ...

  7. 前端 JavaScript 之『节流』的简单代码实现

    前戏 首先,总结一下上一篇文章--<前端 JavaScript 之『防抖』的简单代码实现>的内容:「防抖」就是在高频率触发事件停止触发后,延时执行某个处理逻辑. 防抖虽然在一定程度上对性能 ...

  8. 【Python笔记】列表基础操作 :创建,增加、删除、查询。附加:练习题。用简单代码解释。

    Python:列表基础操作 创建,增加.删除.查询.附加练习题.用简单代码解释. 目录 Python:列表基础操作 演示环境 第一部分:列表(list) 1. 创建空列表 2. 创建只有默认值的列表 ...

  9. python使用spark_如何在Python中编写简单代码,并且速度超越Spark?

    全文共3482字,预计学习时长7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选择. ...

  10. python 字节流分段_如何在Python中编写简单代码,并且速度超越Spark?

    全文共 3482字,预计学习时长 7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选 ...

最新文章

  1. 在同一台电脑上同时安装Python2和Python3
  2. window下启动nexus出错Unsupported major.minor version 51
  3. WordPress中的cookie 机制
  4. android系统属性获取及设置
  5. ython二十五: 解压序列
  6. matlab设置非平坦结构元,详解MATLAB/Simulink通信系统建模与仿真图书信息
  7. xbox one s驱动_续航800公里 体验6座SUV理想ONE
  8. 通过css样式,控制文字显示...
  9. Linux添加/删除用户和用户组(linux中,添加cvs用户,实质就是添加linux用户。)
  10. Git:git同步git push时候提示filename too long解决办法
  11. 数学建模编程用c语言,C程序设计一百例--用c语言解决数学建模问题.doc
  12. 基于python的数据管理系统的设计_基于Python的自然语言数据处理系统的设计与实现...
  13. 科技护肤品,买还是不买
  14. php 计费系统设计,仓储系统之计费模块设计
  15. MacBook Pro 2018款充电口不能用解决办法
  16. dvm 与jvm 区别
  17. 支持查看朋友圈的微信Mac版客户端
  18. 数据结构-青蛙杯棒球比赛
  19. CSS网页设计教程:表单Button的Outl…
  20. java查询数据库方法show create

热门文章

  1. Systrace抓取
  2. 社交网络分析之关系图(原理+Python代码)
  3. keil软件仿真打印输出配置
  4. 做了多年开发的你发现自己的水平一直上不去,一篇文章教你如何提高开发水平的方法
  5. 阿里数据师最爱用的图表特效,10分钟让可视化报告内涵又炫酷
  6. ubuntu上搭建wiki系统
  7. 《《《总结》》》PCL的42个实例整理:1~24
  8. 拉格朗日乘子法、惩罚函数法
  9. C# winform程序调用屏幕键盘
  10. Qt调用工业相机之相机的触发模式及代码实现