前言
闲来无事,整理一下上个学期做过的编译原理实验,主要是代码,细节等以后有时间再回顾,希望能帮助到大家。
TEST 语言介绍
TEST 是 C语言的子集,比 C语言简单的多
- 变量:整形 int
- 控制语句:if、while、for 等
- 注释:/* 注释内容 */
- 表达式:算数表达式、布尔表达式
拓展功能
- 函数形参实现
- 数组实现
- 值传递
- 函数返回值
- 定义变量并赋初值
- 局部变量
- …
词法分析
词法规则
< ID > ::= < letter >|< ID >< letter >|< ID >< digit >
< NUM > ::= < digit >|< NUM >< digit >
< letter > ::= a | b |…| z | A | B |…| Z
< digit > ::= 1|2|…|9|0
< singleword > ::= + | - | * | ( | ) | { | } | ; | : | [ | ] | !
< doubleword > ::= >= |<= | == | != | || | &&
保留字:{“return”,“call”,“main”,“function”,“if”,“else”,“for”,“while”,“do”,“int”,“read”,“write”,“do”,“switch”,“case”,“break”,“continue”};
原理
状态图法
大致流程图如下
实现
scan.h
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<malloc.h>
#define keywordSum 17
#define singleMax 50
#define doubleMax 10
#define file_length 300
#define tokenMax 40
#define ERR_NUM 20
void sort(char *begin[]);
char* lower(char *temp,char *low);
int binselect(char *target,char **set,int low,int high);
char* str_copy(char *des,char *sour);
//保留字
char *keyword[keywordSum]={"return","call","main","function","if","else","for","while","do","int","read","write","do","switch","case","break","continue"};
//单分界符
char singleword[singleMax]="+-*(){};,:[]";
//双分界符首字符
char doubleword[doubleMax]="><=!";
char doubleword_add[doubleMax]="|&";//短路与 与
//输入输出文件名
char Scanin[file_length],Scanout[file_length];
//输入输出文件指针
FILE *fin_scan,*fout_scan;
int scanTEST(char *in,char *out){
//ch为每次读入的字符,token用于保存识别出的单词,es为错误代码
char ch,token[tokenMax];
char *err[ERR_NUM];
int errLine[ERR_NUM];
//错误行号 错误总数
int rowLine=1;//注释中也可能有换行符
int errSum=0;
int es=0;
/*
printf("输入源文件(路径+文件名):\n");
scanf("%s",Scanin);
printf("输入目标文件(路径+文件名):\n");
scanf("%s",Scanout);
*/
if((fin_scan=fopen(in,"r"))==NULL){
fclose(fin_scan);
printf("\n打开词法分析输入文件错误\n");
return -1;
}
if((fout_scan=fopen(out,"w+"))==NULL){
fclose(fout_scan);
printf("\n创建词法分析输出文件错误\n");
return -1;
}
printf("------------------\n");
printf("词法分析开始\n");
ch = getc(fin_scan);
while(ch!=EOF){
while(ch==' '||ch=='\n'||ch=='\t'){
if(ch=='\n'){
rowLine++;
}
ch=getc(fin_scan);
}
if(isalpha(ch)){//?字母
int i=0;
token[i++]=ch;
ch=getc(fin_scan);
while(isalnum(ch)){//组合保留字
token[i++]=ch;
ch=getc(fin_scan);
}
token[i]='\0';
//查保留字//折半查找//字典序
sort(keyword);//排序保留字表
char low_token[tokenMax];
int err=binselect(lower(token,low_token),keyword,0,keywordSum-1);
if(err==-1){//不是保留字
fprintf(fout_scan,"%s\t%s\t%d\n","ID",token,rowLine);
}
else{
fprintf(fout_scan,"%s\t%s\t%d\n",token,token,rowLine);
}
}
else if(isdigit(ch)){//?数字
//组合整数
int i = 0;
token[i++]=ch;
ch=getc(fin_scan);
while(isdigit(ch)){
token[i++]=ch;
ch=getc(fin_scan);
}
token[i]='\0';
fprintf(fout_scan,"%s\t%s\t%d\n","NUM",token,rowLine);
}
else if(strchr(singleword,ch)>0){//?纯单分界符
int i = 0;
token[i++]=ch;
token[i]='\0';
ch=getc(fin_scan);
fprintf(fout_scan,"%s\t%s\t%d\n",token,token,rowLine);
}
else if(strchr(doubleword,ch)>0){//?双分界符
int i = 0;
token[i++]=ch;
ch=getc(fin_scan);
if(ch=='='){
token[i++]='=';
token[i]='\0';
ch=getc(fin_scan);
}
else{
token[i]='\0';
}
fprintf(fout_scan,"%s\t%s\t%d\n",token,token,rowLine);
}
else if(strchr(doubleword_add,ch)>0){// || &&
int i = 0;
char before=ch;
token[i++]=ch;
ch=getc(fin_scan);
if(before==ch){
token[i++]=ch;
token[i]='\0';
ch=getc(fin_scan);
fprintf(fout_scan,"%s\t%s\t%d\n",token,token,rowLine);
}
else{
token[i]='\0';
err[errSum]=(char *)malloc(10*sizeof(char));
err[errSum]=str_copy(err[errSum],token);
errLine[errSum++]=rowLine;
}
}
else if(ch=='/'){//注释处理
int i=0;
char ch1;
ch=getc(fin_scan);
if(ch=='*'){
ch1=getc(fin_scan);
do{
ch=ch1;
ch1=getc(fin_scan);
if(ch=='\n'){
rowLine++;
}
}while((ch!='*' || ch1 !='/') && ch1!=EOF);
}else{
token[i++]='/';
token[i]='\0';
fprintf(fout_scan,"%s\t%s\t%d\n",token,token,rowLine);
}
}
else{//错误处理
if(ch==EOF){
break;
}
token[0]=ch;
token[1]='\0';
err[errSum]=(char *)malloc(10*sizeof(char));
err[errSum]=str_copy(err[errSum],token);
errLine[errSum]=rowLine;
errSum++;
ch=getc(fin_scan);
es=3;
}
}
if(errSum>0){
printf("词法分析发现错误,错误总数%d\n",errSum);
fprintf(fout_scan,"%s\t%d\n","ERRSUM",errSum);
return errSum;
}
printf("词法分析成功\n");
for(int i=0;i<errSum;i++){
fprintf(fout_scan,"%s\t%s\t%d\n","ERROR",err[i],errLine[i]);
}
fclose(fin_scan);
fclose(fout_scan);
return es;
}
//str_cpy
char* str_copy(char *des,char *sour){
if(sour==NULL || des==NULL){
printf("字符串复制出错\n");
return NULL;
}
char *temp=des;
int i;
for(i=0;sour[i]!='\0';i++){
temp[i]=sour[i];
}
temp[i]='\0';
return temp;
}
//字典序排列字符串
void sort(char *begin[]){
char *temp=NULL;
int MIN=0;
for(int i=0;i<keywordSum;i++){
MIN=i;
for(int j=i+1;j<keywordSum;j++){
if(strcmp(begin[MIN],begin[j])>0){
MIN=j;
}
}
temp=begin[i];
begin[i]=begin[MIN];
begin[MIN]=temp;
}
}
//大写转小写
char* lower(char *temp,char *low){
int i=0;
while(temp[i]!='\0'){
low[i]=tolower(temp[i]);
i++;
}
low[i]='\0';
return low;
}
//折半查找 :返回-1为失败
int binselect(char *target,char **set,int low,int high){
int mid=(low+high)/2;
if(low>high){
return -1;
}
if(strcmp(target,set[mid])>0){
return binselect(target,set,mid+1,high);
}
else if(strcmp(target,set[mid])<0){
return binselect(target,set,low,mid-1);
}
else{
return mid;
}
}
语法分析语义分析
语法规则
< program> —>{< fun_declaration>}< main_declaration>
< fun_declaration>—>function ID ‘(’[< para_list>]’)’< function_body>
< main_declaration>—>main ‘(’ ‘)’< function_body>
< para_list>—>int ID{, int ID}
< function_body>—>’{’< declaration_list>< statement_list>’}’
< declaration_list>—>{< declaration_stat>}
< declaration_stat>—>int ID < var_stat>|< arry_stat> { , ID < var_stat>|< arry_stat> }
< arry_stat>–>’[‘NUM’]’ [=’{’[NUM {,NUM} ]’}’]
< var_stat>—>[=NUM]
< statement_list>—>{< statement >}
< statement>—>< if_stat>|< while_stat>|< for_stat>|< read_stat>|< write-stat>|< compound_stat>
|< expression_stat>|< switch_stat> |< do_while>|< break_stat>|< continue>
< return_stat>—> return < expression> ;
< switch_stat>—>switch ‘(’< exprssion>’)’{’ {case NUM :< statement> < break_stat>} ‘}’
< do_while>—>do < statement> while ‘(’ < expression>’)’
< break_stat>—>break ;
< continue_stat>---->continue ;
< if_stat>—>if ‘(’< exprssion>’)’< statement>[else < statement>]
< while_stat> —>while’(’< expression>’)’< statement>
< for_stat>—>for’(’< expression> ; < expression> ; < expression >’)’< statement>
< read>—>read ID | ID ‘[’ < expression> ‘]’
< write>—>write < exprssion>
< compound_stat>—>’{’ < statement_list> ‘}’
< expression_stat>—>< expression> ;| ;
< call_stat>—>call ID ‘(’[< expression> {,< expression> }’)’
< expression>—>ID[’[’< expression>’]’]=< bool_expr> | < bool_expr>
< bool_expr>—>[!]< additive_expr>{ (>|<|>=|<=|==|!=| && | || ) < additive_expr> }
< additive_expr>—>< term>{(+|-)< term>}
< term>—>< factor>{(*|/)< factor>}
< factor>—>’(’< additive_expr>’)’|ID|NUM| ID’[’< expression>’]’| < call_stat>
原理
语法语义:递归子程序下降法
主要实现难点说明:
- 语法树的递归输出
- 符号表数据结构的设计
- 栈式结构的理解
- 栈式虚拟机指令的设计
实现
parse.h
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<conio.h>
#include<string.h>
#include<string>
#include<vector>
#include<map>
#define SIZE 500
#define maxCodeIndex 1000
using namespace std;
struct node{//语法树
string str;//节点标识
vector<node*> sons;//子树
string value;//值
node* addSon(string s){
node* son = new node();
son->str=s;
sons.push_back(son);
return son;
}
node* addSon(string k,string v){
node* son = new node();
son->str=k;
son->value=v;
sons.push_back(son);
return son;
}
}*root;
struct var{//变量
string name;//名字
int address;//偏移地址
int len;//长度,变量为0,数组为NUM
var(){
}
var (string n,int a,int l){
this->name = n;
this->address = a;
this->len = l;
}
};
struct fun{
int address;//入口地址
int num;//形参个数
int len_var;//变量总长度
map<string, var> vars;//变量表
fun(){
}
fun(int address){
this->address = address;
this->num=0;//创建函数 形参初值为0
this->len_var=0; //创建函数 变量总长度为0
}
};
int cx_n=0;//codeIndex
int offset_n=0;//当前偏移地址
int main_cx=0;//记录main的BR
struct{//中间代码
char operate[10];//操作符
int operate_data;//操作数
}codes[maxCodeIndex];
string fun_n;//当前function main
string temp_id;//记录之前id
map< string , fun > fun_list;//不同函数符号表
int insert_symbol(string name,string type,int len){//插入符号表,扫描到标识符定义出现
int es=0;
if(strcmp(type.c_str(),"var")==0){
map<string,var> &vars = fun_list[fun_n].vars;
if(vars.find(name)==vars.end())
vars[name] = var(name, offset_n++,len);//插入变量名,地址,长度
else{
return es=31;//变量重定义
}
}
if(strcmp(type.c_str(),"function")==0){//插入 function
if(fun_list.find(name)==fun_list.end()){// 之前未定义则插入
fun_list[name] = fun(cx_n);//插入函数入口地址
}
else{
return es=32;//函数重定义
}
}
return es;
}
int lookup(string name,int *position){//查找符号表
int es=0;
map<string,var> vars = fun_list[fun_n].vars;
if(vars.find(name)!=vars.end()){
*position=vars[name].address;
}
else
return es=33;//变量未定义
return es;
}
int getlen(string name){
map<string,var> vars = fun_list[fun_n].vars;
if(vars.find(name)!=vars.end())
return vars[name].len;
return -1;
}
char ScanFile[50];//词法分析结果
char word_k[50];//单词类别
char word_v[50];//单词本身值
char row[30];//单词行号
char parseFile[50];//语法分析结果
FILE *fp_word;//单词流文件指针
FILE *fout;
FILE *mid_code;//中间代码
FILE *sym;//符号表
//语法分析,输出语法树
char *space=" ";// 12个空格
char *link ="| ";
int L[100];//未遍历兄弟剩余个数
int program();
int fun_declaration(node* p);
int main_declaration(node* p);
int function_body(node* p);
int declaration_list(node* p);
int declaration_stat(node* p);
int statement_list(node* p);
int statement(node* p);
int if_stat(node* p);
int while_stat(node* p);
int for_stat(node* p);
int write_stat(node* p);
int read_stat(node* p);
int compound_stat(node* p);
int expression_stat(node* p);
int call_stat(node* p);
int expression(node* p);
int bool_expr(node* p);
int additive_expr(node* p);
int term(node* p);
int factor(node* p);
int switch_stat(node *p);
int do_while(node *p);
int break_stat(node *p);
int continue_stat(node *p);
int return_stat(node *p);
void printTree(node *root,int blk);
void read_f();
int yufa(char *cifa_r,char *yufashu_r);
/*语义分析函数*/
int program_(node* p);
int fun_declaration_(node* p);
int main_declaration_(node* p);
int function_body_(node* p);
int declaration_list_(node* p);
int declaration_stat_(node* p);
int statement_list_(node* p);
int statement_(node* p);
int if_stat_(node* p);
int while_stat_(node* p);
int for_stat_(node* p);
int write_stat_(node* p);
int read_stat_(node* p);
int compound_stat_(node* p);
int expression_stat_(node* p);
int call_stat_(node* p);
int expression_(node* p);
int bool_expr_(node* p);
int additive_expr_(node* p);
int term_(node* p);
int factor_(node* p);
int switch_stat_(node *p);
int do_while_(node *p);
int return_stat_(node *p);
int break_stat_(node *p);
int continue_stat_(node *p);
void printf_s();
int parseTEST(char *cifa_r,char *yufashu_r,char *fuhaobiao_r,char *midcodes_r){
int es = 0;
if(yufa(cifa_r,yufashu_r) == -1) return -1;//生成语法树
if((sym=fopen(fuhaobiao_r,"w"))==NULL){
fclose(sym);
printf("\n打开错误\n");
return -1;
}
if((mid_code=fopen(midcodes_r,"w+"))==NULL){
fclose(mid_code);
printf("\n打开错误\n");
return -1;
}
printf("\n------------------\n");
printf("语义分析开始\n");
es=program_(root);//
if(es>0){//报错
printf("语义分析出错\n",es);
switch(es){
case 31:printf("变量重定义!\n");break;
case 32:printf("函数重定义!\n");break;
case 33:printf("变量未定义!\n");break;
case 34:printf("数组初始化越界!\n");break;
case 35:printf("函数未定义!\n");break;
case 36:printf("形参设置错误!\n");break;
}
return -1;
}
else{//输出符号表,中间代码
printf("语义分析成功\n");
printf_s();
fclose(sym);
fclose(mid_code);
return 0;
}
}
int yufa(char *cifa_r,char *yufashu_r){
int es=0;
L[0]=0;//第0层不输出空位
if((fp_word=fopen(cifa_r,"r"))==NULL){
fclose(fp_word);
printf("\n打开错误\n");
return -1;
}
if((fout=fopen(yufashu_r,"w"))==NULL){
fclose(fout);
printf("\n打开错误\n");
return -1;
}
printf("\n------------------\n");
printf("语法分析开始\n");
es=program();
fclose(fp_word);
if(es==0){
printf("语法分析成功\n");
printTree(root,0);//输出语法树
fclose(fout);
printf("语法树输出成功\n");
return 0;
}
printf("语法分析终止,发现语法错误!\n错误行号:%s\t",row);
switch(es){
case 1:printf("expected main !\n");break;
case 2:printf("expected function ID !\n");break;
case 3:printf("expected ( !\n");break;
case 4:printf("expected ) !\n");break;
case 5:printf("expected { !\n");break;
case 6:printf("expected } !\n");break;
case 7:printf("expected ID !\n");break;
case 8:printf("expected ; !\n");break;
case 9:printf("expected ID !\n");break;
case 10:printf("expected NUM ID !\n");break;
case 11:printf("main() {} is not the last !\n");break;
case 12:printf("expected case or } !\n");break;
case 13:printf("expected NUM after case !\n");break;
case 14:printf("expected : !\n");break;
case 15:printf("expected while !\n");break;
case 16:printf("expected int !\n");break;
case 17:printf("expected ID after int !\n");break;
case 18:printf("expected break !\n");break;
case 19:printf("statement error !\n");break;
case 20:printf("expected NUM ! \n");break;
case 21:printf("expected ] ! \n");break;
}
return -1;
}
//非终结符结束之前需要重新读单词流
//非终结符开始之前需要准备好单词流
//终结符在程序中加入树
//非终结符在其自身函数内加入树
//<program--->{<fun_declaration>}<main_declaration>有分歧时需要先读一个字符进行判别
int program(){
int i,es=0;
root=new node();
root->str="<program>";
read_f();
while(stricmp(word_k,"function")==0){//function
es=fun_declaration(root);
if(es>0) return es;
}
if(stricmp(word_k,"main")){//main
es=1;//缺少main
return es;
}
es=main_declaration(root);
if(es>0) return es;
if(stricmp(word_k,"#")){//文件结束标志
return es=11;
}
return es;
}
//<fun_declaration>--->function ID '('[<para_list>]')'<function_body>
//<para_list>--->int ID{, int ID}
int para_list(node *p){
int es=0;
node *s=p->addSon("<para_list>");
s->addSon(word_k,word_v);//int
read_f();
if(stricmp(word_k,"ID")){
return es=7; //lack ID
}
s->addSon(word_k,word_v);
read_f();
while(stricmp(word_k,",")==0){
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"int")){
return es=16;//expect int
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"ID")){
return es=17;//expect ID
}
s->addSon(word_k,word_v);
read_f();
}
return es;
}
int fun_declaration(node *p){
int es=0;
node *s=p->addSon("<fun_declaration>");
s->addSon(word_k,word_v);//funtion
read_f();
if(stricmp(word_k,"ID")){//stricmp(word_k,"ID")!=0
es=2;//普通函数名错误
return es;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"(")){
es=3;//缺少(
return es;
}
s->addSon(word_k,word_v);
read_f();
/**参数**///<para_list>--->int ID{, int ID}
if(stricmp(word_k,"int")==0){
es=para_list(s);
if(es>0) return es;
}
if(stricmp(word_k,")")){
es=4;//缺少)
return es;
}
s->addSon(word_k,word_v);
read_f();
es=function_body(s);
return es;
}
//<function_body>--->'{'<declaration_list><statement_list>'}'
int function_body(node *p){
int es=0;
node *s=p->addSon("<function_body>");
if(stricmp(word_k,"{")){
es=5;//缺少{
return es;
}
s->addSon(word_k,word_v);
read_f();
es=declaration_list(s);//
if(es>0) return es;
es=statement_list(s);//
if(es>0) return es;
if(stricmp(word_k,"}")){//如果文件结束且 }
es=6;//缺少}
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<declaration_list>--->{<declaration_stat>}
int declaration_list(node *p){
int es=0;
node *s=p->addSon("<declaration_list>");
while(stricmp(word_k,"int")==0){//First集合包含INT
es=declaration_stat(s);
if(es>0) return es;
}
return es;
}
//<var_stat>--->[=NUM]
int var_stat(node *p){
int es=0;
node *s=p->addSon("<var_stat>");
s->addSon(word_k,word_v);// = 注意p
read_f();
if(stricmp(word_k,"NUM")){
return es=20;// num
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<arry_stat>-->'['NUM']' [='{'[NUM {,NUM} ]'}']
int arry(node *p){
int es=0;
node *s=p->addSon("<arry>");
s->addSon(word_k,word_v);// [
read_f();
if(stricmp(word_k,"NUM")){
return es=20;// num
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"]")){
return es=21;// ]
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"=")==0){
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"{")){
return es=5;// {
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"NUM")==0){
s->addSon(word_k,word_v);// NUM
read_f();
//<arry_stat>-->'['NUM']' [='{'[NUM]{,NUM}'}']
while(stricmp(word_k,",")==0){// ,
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"NUM")){
return es=20; //NUM
}
s->addSon(word_k,word_v);
read_f();
}
}
if(stricmp(word_k,"}")){
return es=6;// }
}
s->addSon(word_k,word_v);
read_f();
}
return es;
}
//<declaration_stat>--->int ID <var_stat>|<arry_stat> { , ID <var_stat>|<arry_stat> } ;
int declaration_stat(node *p){
int es=0;
node *s=p->addSon("<declaration_stat>");
s->addSon(word_k,word_v);//int
read_f();
if(stricmp(word_k,"ID")){
es=7;//缺少变量名
return es;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"=")==0){
es=var_stat(s);
if(es>0) return es;
}
else if(stricmp(word_k,"[")==0){
es=arry(s);
if(es>0) return es;
}
while(stricmp(word_k,",")==0){
s->addSon(word_k,word_v);// ,
read_f();
if(stricmp(word_k,"ID")){
return es=7; //ID
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"=")==0){// var_stat
es=var_stat(s);
if(es>0) return es;
}
else if(stricmp(word_k,"[")==0){// arry_stat
es=arry(s);
if(es>0) return es;
}
}
if(stricmp(word_k,";")){
es=8;//缺少;
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<statement_list>--->{<statement>}
int statement_list(node *p){
int es=0;
node *s=p->addSon("<statement_list>");
while(stricmp(word_k,"}")!=0){//staement_list的First集合不包含 }
es=statement(s);//文件结束:返回非0值,文件未结束,返回0值
if(es>0) return es;
}
return es;
}
//statement---><if_stat>|<while_stat>|<for_stat>|<read_stat>|<write-stat>|
// <compound_stat>|<expression_stat>|<switch_stat>
// |<do_while>|<break_stat>|<continue>
int statement(node *p){
int es=0;
node *s=p->addSon("<statement>");
if(stricmp(word_k,"if")==0 && es==0){
es=if_stat(s);
}
else if(stricmp(word_k,"while")==0 && es==0){
es=while_stat(s);
}
else if(stricmp(word_k,"for")==0 && es==0){
es=for_stat(s);
}
else if(stricmp(word_k,"read")==0 && es==0){
es=read_stat(s);
}
else if(stricmp(word_k,"write")==0 && es==0){
es=write_stat(s);
}
else if(stricmp(word_k,"{")==0 && es==0){//compound_stat
es=compound_stat(s);
}
else if(es==0 && (strcmp(word_k,"ID")==0||strcmp(word_k,"NUM")==0
||strcmp(word_k,"(")==0)||strcmp(word_k,";")==0 ||strcmp(word_k,"call")==0){//expression_stat
es=expression_stat(s);
}
else if(stricmp(word_k,"switch")==0 && es==0){
es=switch_stat(s);
}
else if(stricmp(word_k,"do")==0 && es==0){
es=do_while(s);
}
else if(stricmp(word_k,"return")==0 && es==0){
es=return_stat(s);
}
else if(stricmp(word_k,"break")==0 && es==0){
es=break_stat(s);
}
else if(stricmp(word_k,"continue")==0 && es==0){
es=continue_stat(s);
}
else{
return es=19;//statement failure
}
return es;
}
//<return_stat>---> return <expression> ;
int return_stat(node *p){
int es = 0;
node *s=p->addSon("<return_stat>");
s->addSon(word_k,word_v);//return
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,";")){
es=8;// ;
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<switch_stat>--->switch '(' ID ')'{' {case NUM :<stateement> <break_stat>} '}'
//<switch_stat>--->switch '('<expr>')'{' {case NUM :<stateement> <break_stat>} '}'
int switch_stat(node *p){
int es=0;
node *s=p->addSon("<switch_stat>");
s->addSon(word_k,word_v);//switch
read_f();
if(stricmp(word_k,"(")){
return es=3;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,")")){
return es=4;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"{")){
return es=5;
}
s->addSon(word_k,word_v);
read_f();
while(stricmp(word_k,"case")==0){
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"NUM")){
return es=13;//expect case num
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,":")){
return es=14;// expect :
}
s->addSon(word_k,word_v);
read_f();
es=statement(s);
if(es>0) return es;
if(stricmp(word_k,"break")){
return es=18;//expect break;
}
es=break_stat(s);
if(es>0) return es;
}
if(stricmp(word_k,"}")){
return es=12;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<do_while>--->do <statement> while '(' <expression>')'
int do_while(node *p){
int es=0;
node *s=p->addSon("<do_while>");
s->addSon(word_k,word_v);//do
read_f();
es=statement(s);
if(es>0) return es;
if(stricmp(word_k,"while")){
return es=15;// expect while _do
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"(")){
return es=3;// (
}
s->addSon(word_k,word_v);
read_f();
es= expression(s);
if(es>0) return es;
if(stricmp(word_k,")")){
return es=4;// (
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<break_stat>--->break ;
int break_stat(node *p){
int es=0;
node *s=p->addSon("<break_stat>");
s->addSon(word_k,word_v);//break;
read_f();
if(stricmp(word_k,";")){
return es=8;// ;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//continue_stat>---->continue ;
int continue_stat(node *p){
int es=0;
node *s=p->addSon("<continue_stat>");
s->addSon(word_k,word_v);//break;
read_f();
if(stricmp(word_k,";")){
return es=8;// ;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<if_stat>--->if '('<exprssion>')'<statement>[else <statement>]
int if_stat(node *p){
int es=0;
node *s=p->addSon("<if_stat>");
s->addSon(word_k,word_v);//if
read_f();
if(stricmp(word_k,"(")){
es=3;// (
return es;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,")")){
es=4;// )
return es;
}
s->addSon(word_k,word_v);
read_f();
es=statement(s);
if(es>0) return es;
if(stricmp(word_k,"else")==0){
s->addSon(word_k,word_v);
read_f();
es=statement(s);
if(es>0) return es;
}
return es;
}
//while_stat--->while'('<expression>')'<statement>
int while_stat(node *p){
int es=0;
node *s=p->addSon("<while_stat>");
s->addSon(word_k,word_v);//while
read_f();
if(stricmp(word_k,"(")){
es=3;
return es;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,")")){
es=4;
return es;
}
s->addSon(word_k,word_v);
read_f();
es=statement(s);
return es;
}
//<for_stat>--->for'('<expression> ; <expression> ; <expression>')'<statement>
int for_stat(node *p){
int es=0;
node *s=p->addSon("<for_stat>");
s->addSon(word_k,word_v);//for
read_f();
if(stricmp(word_k,"(")){
es=3;
return es;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);//1
if(es>0) return es;
if(stricmp(word_k,";")){
es=8;// ;
return es;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);//2
if(es>0) return es;
if(stricmp(word_k,";")){
es=8;// ;
return es;
}
s->addSon(word_k,word_v);
read_f();
es=expression(s);//3
if(stricmp(word_k,")")){
es=4;// )
return es;
}
s->addSon(word_k,word_v);
read_f();
es=statement(s);
return es;
}
//<read>--->read ID | ID '[' <expression> ']' ;
int read_stat(node *p){
int es=0;
node *s=p->addSon("<read_stat>");
s->addSon(word_k,word_v);//read
read_f();
if(stricmp(word_k,"ID")){
es=9;//缺少ID
return es;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"[")==0){//数组
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,"]")){
return es=21;// ]
}
s->addSon(word_k,word_v);
read_f();
}
if(stricmp(word_k,";")){
es=8;// ;
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<write>--->write <exprssion> ;
int write_stat(node *p){
int es=0;
node *s=p->addSon("<write_stat>");
s->addSon(word_k,word_v);//write
read_f();
es = expression(s);
if ( es>0 ) return es;
if(stricmp(word_k,";")){
es=8;// ;
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<compound_stat>--->'{' <statement_list> '}'
int compound_stat(node *p){
int es=0;
node *s=p->addSon("<compound_stat>");
s->addSon(word_k,word_v);// {
read_f();
es=statement_list(s);
if(es>0) return es;
if(stricmp(word_k,"}")){
es=6 ;// }
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
// expression_stat>---><expression> ;|;
int expression_stat(node *p){
int es=0;
node *s=p->addSon("<expression_stat>");
// ID NUM ( ;
if(stricmp(word_k,";")==0){
s->addSon(word_k,word_v);
read_f();
return es;
}
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,";")){
es=8;
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<call_stat>--->call ID '('')'
//<call_stat>--->call ID '('[<expression> {,<expression> }')'
int call_stat(node *p){
int es=0;
node *s=p->addSon("<call_stat>");
s->addSon(word_k,word_v);//call
read_f();
if(stricmp(word_k,"ID")){
es=9;//ID
return es;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"(")){
es=3;// (
return es;
}
s->addSon(word_k,word_v);
read_f();
/**参数**/
if(stricmp(word_k,")")!=0){
es=expression(s);
if(es>0) return es;
while(stricmp(word_k,",")==0){
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
}
}
if(stricmp(word_k,")")){
es=4;// )
return es;
}
s->addSon(word_k,word_v);
read_f();
return es;
}
//<expression>--->ID['['<expression>']']=<bool_expr> | <bool_expr> //非LL(1)文法
int expression(node *p){//由于First集冲突,需多读入一个字符 fseek() ftell()
int es=0;
int f_now=ftell(fp_word);//目前指针位置
char r_temp[30],k[50],v[50];
strcpy(r_temp,row);
strcpy(k,word_k);
strcpy(v,word_v);
node *s=p->addSon("<expression>");
// ID NUM ( call
if(stricmp(word_k,"call")==0){//增加函数因子
//printf("%s %s %s\n",word_k,word_v,row);
es=bool_expr(s);
if(es>0) return es;
return es;
}
if(stricmp(word_k,"!")!=0){
char temp_k[40];
char temp_v[40];
fscanf(fp_word,"%s\t%s\t%s\n",temp_k,temp_v,row);
if(stricmp(temp_k,"=")==0){
s->addSon(word_k,word_v);
s->addSon(temp_v);
read_f();
}
else if(stricmp(temp_k,"[")==0){// 数组
s->addSon(word_k,word_v);
s->addSon(temp_v);
char t_k[40],t_v[40];
fscanf(fp_word,"%s\t%s\t%s\n",word_k,word_v,row);
es=expression(s);//
if(es>0) return es;
if(stricmp(word_k,"]")) return es=21;
fscanf(fp_word,"%s\t%s\t%s\n",t_k,t_v,row);
if(stricmp(t_k,"=")==0){
s->addSon(word_k);
s->addSon(t_v);
read_f();
}
else{
// //删除 ID[<expression> 节点
s->sons.erase(s->sons.begin(),s->sons.begin()+3);
strcpy(row,r_temp);
strcpy(word_k,k);
strcpy(word_v,v);
fseek(fp_word,f_now,0);//指针回读
}
}
else{
fseek(fp_word,f_now,0);//指针回读
}
}
es=bool_expr(s);
if(es>0) return es;
}
//<bool_expr>---><additive_expr>{ (>|<|>=|<=|==|!=) <additive_expr> }
//<bool_expr>--->[!]<additive_expr>{ (>|<|>=|<=|==|!=| && | || ) <additive_expr> }
int bool_expr(node *p){
int es=0;
node *s=p->addSon("<bool_expr>");
if(stricmp(word_k,"!")==0){
s->addSon(word_k,word_v);
read_f();
}
es=additive_expr(s);
if(es>0) return es;
while(stricmp(word_k,">")==0 ||stricmp(word_k,"<")==0
||stricmp(word_k,">=")==0 ||stricmp(word_k,"<=")==0
||stricmp(word_k,"==")==0 ||stricmp(word_k,"!=")==0
||stricmp(word_k,"||")==0 ||stricmp(word_k,"&&")==0 ){
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"!")==0){
s->addSon(word_k,word_v);
read_f();
}
es=additive_expr(s);
if(es>0) return es;
}
return es;
}
//<additive_expr>---><term>{(+|-)<term>}
int additive_expr(node *p){
int es=0;
node *s=p->addSon("<additive_expr>");
es=term(s);
if(es>0){
return es;
}
while(stricmp(word_k,"+")==0 || stricmp(word_k,"-")==0){
s->addSon(word_k,word_v);
read_f();
es=term(s);
if(es>0) return es;
}
return es;
}
//<term>---><factor>{(*|/)<factor>}
int term(node *p){
int es=0;
node *s=p->addSon("<term>");
es=factor(s);
if(es>0) return es;
while(stricmp(word_k,"*")==0||stricmp(word_k,"/")==0){
s->addSon(word_k,word_v);
read_f();
es=factor(s);
if(es>0) return es;
}
return es;
}
//<factor>--->'('<additive_expr>')'|ID|NUM
//<factor>--->'('<additive_expr>')'|ID|NUM| ID'['<expression>']'| <call_stat> //一维数组
int factor(node *p){
int es=0;
node *s=p->addSon("<factor>");
if(stricmp(word_k,"(")==0){
s->addSon(word_k,word_v);
read_f();
es=additive_expr(s);
if(stricmp(word_k,")")){
es=4;
return es;// )
}
s->addSon(word_k,word_v);
read_f();
return es;
}
else if(stricmp(word_k,"call")==0){
es=call_stat(s);
if(es>0) return es;
}
else{
if(stricmp(word_k,"NUM")==0){
s->addSon(word_k,word_v);
read_f();
return es;
}
else if(stricmp(word_k,"ID")==0){
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,"[")==0){//数组
s->addSon(word_k,word_v);
read_f();
es=expression(s);
if(es>0) return es;
if(stricmp(word_k,"]")){
return es=21; // ]
}
s->addSon(word_k,word_v);
read_f();
}
}
else{
es=10;//缺少ID NUM
return es;
}
}
return es;
}
//<main_declaration>--->main '(' ')'<function_body>
int main_declaration(node *p){
int es=0;
node *s=p->addSon("<main_declaration>");
s->addSon(word_k,word_v);//main
read_f();
if(stricmp(word_k,"(")){
es=3;// (
return es;
}
s->addSon(word_k,word_v);
read_f();
if(stricmp(word_k,")")){
es=4;
return es;// )
}
s->addSon(word_k,word_v);
read_f();
es=function_body(s);
return es;
}
void read_f(){
if(feof(fp_word)==0){
fscanf(fp_word,"%s\t%s\t%s\n",word_k,word_v,row);
}
else{
strcpy(word_k,"#");strcpy(word_v,"#");
}
}
void printTree(node *now,int blk){//flag用来标记是否是最后一个孩子
int size=now->sons.size();
int i;
if(size==0){
for(i=0;i<blk;i++){
if(L[i]==0){
fprintf(fout,"%s",space);
}
if(L[i]>0){
fprintf(fout,"%s",link);
}
}
char temp[50];
fprintf(fout,"|+ %s\n",strcpy(temp,now->str.c_str()));
return ;
}
for(int j=0;j<blk;j++){
if(L[j]==0){
fprintf(fout,"%s",space);
}
if(L[j]>0){
fprintf(fout,"%s",link);
}
}
char temp[50];
fprintf(fout,"|-%s\n",strcpy(temp,now->str.c_str()));
for(i=0;i<size;i++){
L[blk+1]=size-i-1;
printTree(now->sons[i],blk+1);
}
}
//
//call ID ( <expr> ... )
int call_stat_(node *p){
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
int i=0;
node *temp=p->sons[i];
//获取ID
temp=p->sons[1];
//查找函数 入口地址
int entry=0;
if(fun_list.find(temp->value)==fun_list.end())
return es=35;//函数未定义
else
entry=fun_list[temp->value].address;
if(fun_list[temp->value].num != (size-4+1)/2 )//形参个数
return es=36;//形参设置错误
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data = 2;
if(size>4){//<expression>
for(int j=3;j<size;j++){
node *temp_1=p->sons[j];
if(temp_1->str=="<expression>"){
es=expression_(temp_1);
if(es>0) return es;
//设置形参
}
}
}
strcpy(codes[cx_n].operate,"CALL");
codes[cx_n++].operate_data = fun_list[temp->value].num;//形参个数
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data=fun_list[temp->value].len_var-fun_list[temp->value].num;//局部变量个数
strcpy(codes[cx_n].operate,"IPJMP");
codes[cx_n++].operate_data = entry;
return es;
}
int factor_(node *p){
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
int i=0;
node *temp=p->sons[i];
//printf("%d %s\n",es,temp->value.c_str());
// 孩子 个数 4 ( ID[<expr>] ) 个数 3 ( (additive) ) 个数 1 (ID NUM CALL)
if(size==3){
temp=p->sons[++i];//<additive>
es=additive_expr_(temp);//
if(es>0) return es;
}
else if(size==4){//数组新增指令 GET 根据栈顶地址找到数,将地址变成数值
int start=0;//数组起始地址
es=expression_(p->sons[2]);//<experssion>
if(es>0) return es;
temp=p->sons[0];//ID
es=lookup(temp->value,&start);
if(es>0) return es;
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data=start;
strcpy(codes[cx_n++].operate,"ADD");
strcpy(codes[cx_n++].operate,"GET");
}
else if(size==1){
temp=p->sons[0];//
int add=0;
if(temp->str=="ID"){
es=lookup(temp->value,&add);
//printf("tempID %s\n",temp->value.c_str());
if(es>0) return es;
strcpy(codes[cx_n].operate,"LOAD");
codes[cx_n++].operate_data=add;
}
else if(temp->str=="NUM"){
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data=atoi(temp->value.c_str());
}
else if(temp->str=="<call_stat>"){
es=call_stat_(temp);
if(es>0) return es;
}
}
return es;
}
int term_(node *p){
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
int i=0;
node *temp=p->sons[i];
es=factor_(temp);
if(es>0) return es;
if(size>1){
string opr;
while(i<size-2){//
temp=p->sons[++i];
opr=temp->str;// * /
temp=p->sons[++i];// FACTOR
es=factor_(temp);
if(es>0) return es;
if(opr=="*")
strcpy(codes[cx_n++].operate,"MULT");
if(opr=="/")
strcpy(codes[cx_n++].operate,"DIV");
}
}
return es;
}
int additive_expr_(node *p){
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
int i=0;
//printf("%d\n",size);
node *temp=p->sons[i];
es=term_(temp);//<term>
if(es>0) return es;
if(size>1){
string opr;
while(i<size-2){//
temp=p->sons[++i];
opr=temp->str;// + -
temp=p->sons[++i];// term
es=term_(temp);
if(es>0) return es;
if(opr=="+")
strcpy(codes[cx_n++].operate,"ADD");
if(opr=="-")
strcpy(codes[cx_n++].operate,"SUB");
}
}
return es;
}
int bool_expr_(node *p){
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
int i=0;
node *temp=p->sons[i];
if(temp->str=="!"){// 2
temp=p->sons[++i];//<additive>
es=additive_expr_(temp);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"NOT");//求反
}
else{// 1
es=additive_expr_(temp);
if(es>0) return es;
}
if(size>2){
string opr;
while(i<size-2){// { }
temp=p->sons[++i];// >= <= > < || &&
opr=temp->str;//保留运算符
temp=p->sons[++i];
if(temp->str=="!"){
temp=p->sons[++i];//<additive>
es=additive_expr_(temp);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"NOT");//求反
}
else{
es=additive_expr_(temp);
if(es>0) return es;
}
if(opr==">")
strcpy(codes[cx_n++].operate,"GT");//
if(opr=="<")
strcpy(codes[cx_n++].operate,"LES");//
if(opr==">=")
strcpy(codes[cx_n++].operate,"GE");//
if(opr=="<=")
strcpy(codes[cx_n++].operate,"LE");//
if(opr=="==")
strcpy(codes[cx_n++].operate,"EQ");//
if(opr=="!=")
strcpy(codes[cx_n++].operate,"NOTEQ");//
if(opr=="||")
strcpy(codes[cx_n++].operate,"OR");//
if(opr=="&&")
strcpy(codes[cx_n++].operate,"AND");//
}
}
return es;
}
int expression_(node *p){//每个expression执行完毕,栈顶都有一个结果数据
int es=0;
int size=p->sons.size();//根据孩子数量判断分支
node *temp=p->sons[0];
if(size==1){//bool
es=bool_expr_(p->sons[0]);
if(es>0) return es;
}
else {
if(size==3){//id = bool
temp=p->sons[2];//<bool>
//printf("%d\n",es);
es=bool_expr_(temp);
if(es>0) return es;
temp=p->sons[0];// id
int add=0;
es=lookup(temp->value,&add);
if(es>0) return es;
strcpy(codes[cx_n].operate,"STO");
codes[cx_n++].operate_data = add;
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data = 1;//栈顶向上移动一个单位
}
if(size==6){//id [<expression>] = bool
temp=p->sons[5];
es=bool_expr_(temp);//bool
if(es>0) return es;
temp=p->sons[2];
//printf("%s\n",temp->str.c_str());
es=expression_(temp);//expr
if(es>0) return es;
temp=p->sons[0];//id
int add=0;
es=lookup(temp->value,&add);
if(es>0) return es;
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data = add;
strcpy(codes[cx_n++].operate,"ADD");
strcpy(codes[cx_n++].operate,"PUT");
}
}
return es;
}
int expression_stat_(node *p){
int es=0;
int size=p->sons.size();
if(size==2){//<expression> ;
es=expression_(p->sons[0]);
if(es>0) return es;
//清空expr
strcpy(codes[cx_n].operate,"DOWN");
codes[cx_n++].operate_data = 1;
}
return es;
}
int if_stat_(node *p){
int es=0;
int brf=0;
int br=0;
int i=0;
int size=p->sons.size();
es=expression_(p->sons[2]);//<expr>
if(es>0) return es;
strcpy(codes[cx_n++].operate,"BRF");
brf=cx_n-1;//返填
es=statement_(p->sons[4]);//<stat>
if(es>0) return es;
if(size==5){ //没有else
codes[brf].operate_data=cx_n;
}
else{ //有 else
strcpy(codes[cx_n++].operate,"BR");
br=cx_n-1;//返填
codes[brf].operate_data=cx_n;//
es=statement_(p->sons[6]);
if(es>0) return es;
codes[br].operate_data=cx_n;//
}
return es;
}
int read_stat_(node *p){// read (ID | ID [ <EX> ]) ;
int es=0;
int offset=0;
int size = p->sons.size();
node *temp=p->sons[1]; //ID
es=lookup(temp->value,&offset);
if(es>0) return es;
if(size==3){
strcpy(codes[cx_n++].operate,"IN");
strcpy(codes[cx_n].operate,"STO");
codes[cx_n++].operate_data=offset;
}
else if(size==6){
temp = p->sons[3];//<expr>
strcpy(codes[cx_n++].operate,"IN");
es=expression_(temp);
if(es>0) return es;
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data=offset;
strcpy(codes[cx_n++].operate,"ADD");
strcpy(codes[cx_n++].operate,"PUT");
}
return es;
}
int while_stat_(node *p){
int es=0;
node *ex=p->sons[2];
node *s=p->sons[4];
int cxEntry=0,brf=0;
cxEntry=cx_n;
es=expression_(ex);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"BRF");
brf=cx_n-1;
es=statement_(s);
if(es>0) return es;
strcpy(codes[cx_n].operate,"BR");
codes[cx_n++].operate_data=cxEntry;
codes[brf].operate_data=cx_n;
return es;
}
int for_stat_(node *p){
int es=0;
node *ex_1=p->sons[2];
node *ex_2=p->sons[4];
node *ex_3=p->sons[6];
node *s=p->sons[8];
int brf=0,cxEntry_2=0;
es=expression_(ex_1);
if(es>0) return es;
//清除expr
strcpy(codes[cx_n].operate,"DOWN");
codes[cx_n++].operate_data = 1;
cxEntry_2=cx_n;///
es=expression_(ex_2);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"BRF");
brf=cx_n-1;///
es=statement_(s);
if(es>0) return es;
es=expression_(ex_3);
if(es>0) return es;
strcpy(codes[cx_n].operate,"DOWN");
codes[cx_n++].operate_data = 1;
strcpy(codes[cx_n].operate,"BR");
codes[cx_n++].operate_data=cxEntry_2;
codes[brf].operate_data=cx_n;
return es;
}
//<switch_stat>--->switch '(' <expr> ')'{' {case NUM :<statement> <break>} '}'
int switch_stat_(node *p){
int es=0;
int size = p->sons.size(); // 6 // >6
node *temp;
node *ex=p->sons[2];
int br[100]; // 无条件转移
int count=0; //记录break数量
es = expression_(ex);
if(es>0) return es;
if(size>6){//有case的情况 按顺序扫描扫描到 NUM时 处理
for(int i=4;i<size;i++){
temp=p->sons[i];
if(temp->str=="case"){
node *num=p->sons[++i];//NUM
i++;// :
node *s=p->sons[++i];//statement
node *bre=p->sons[++i];//break
strcpy(codes[cx_n++].operate,"CPY");//新增指令 CPY
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data = atoi(num->value.c_str());
strcpy(codes[cx_n++].operate,"EQ");
strcpy(codes[cx_n++].operate,"BRF");
int brf = cx_n-1;
es=statement_(s);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"BR");// 语法规则 break
br[count++]=cx_n-1;//反填
codes[brf].operate_data=cx_n;
}
}
for(int j=0;j<count;j++){//反填 br
codes[br[j]].operate_data = cx_n;
}
}
//清除<expr>
strcpy(codes[cx_n].operate,"DOWN");// top = top - 1
codes[cx_n++].operate_data = 1;
return es;
}
int do_while_(node *p){
int es=0;
node *s=p->sons[1];//<stat>
node *ex=p->sons[4];//<expr>
int sEntry=cx_n;
es=statement_(s);
if(es>0) return es;
es=expression_(ex);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"NOT");
strcpy(codes[cx_n].operate,"BRF");
codes[cx_n++].operate_data = sEntry;
return es;
}
int write_stat_(node *p){
int es=0;
node *ex=p->sons[1];//<expr>
es=expression_(ex);
if(es>0) return es;
strcpy(codes[cx_n++].operate,"OUT");
return es;
}
int compound_stat_(node *p){
int es=0;
es=statement_list_(p->sons[1]);//
if(es>0) return es;
return es;
}
int main_declaration_(node *p){
int es=0;
codes[main_cx].operate_data = cx_n;//反填
fun_n="main";
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data = 2; // enter
es=insert_symbol(fun_n,"function",1);//插入函数符号表
if(es>0) return es;
es=function_body_(p->sons[3]);//
if(es>0) return es;
return es;
}
int return_stat_(node *p){
int es = 0;
es=expression_(p->sons[1]);//<expr>
if(es>0) return es;//此处不需要清空<expr>
strcpy(codes[cx_n].operate,"RETURN");
codes[cx_n++].operate_data = 1; //主动return
return es;
}
int statement_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="<if_stat>"){
es=if_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<while_stat>"){
es=while_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<return_stat>"){
//printf("retu\n");
es=return_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<for_stat>"){
es=for_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<do_while>"){
es=do_while_(temp);
if(es>0) return es;
}
else if(temp->str=="<switch_stat>"){
es=switch_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<read_stat>"){
es=read_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<write_stat>"){
es=write_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<compound_stat>"){
es=compound_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<expression_stat>"){
//printf("expr\n");
es=expression_stat_(temp);
if(es>0) return es;
}
}
return es;
}
int statement_list_(node *p){
int es=0;
int size=p->sons.size();
//printf("%d\n",size);
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="<statement>"){
//printf("%d\n",size);
es=statement_(temp);
if(es>0) return es;
}
}
return es;
}
int arry_(node *p){
int es=0;
int count=0;//计数NUM出现次数
int offset=0;//数组首地址
int len=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="NUM"){
count++;
if(count==1){
//es=insert_symbol(temp_id,"var",atoi(temp->value.c_str()));//
fun_list[fun_n].vars[temp_id].len=atoi(temp->value.c_str());// 数组长度
lookup(temp_id,&offset);//获取数组首地址
len = atoi(temp->value.c_str());// 数组长度
if(fun_n=="main"){
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data = len - 1; // enter
}
offset_n=offset_n + atoi(temp->value.c_str()) - 1;// 数组
if(es>0) return es;
}
else{
//count - 2
if(count-1>len) return es=34;//数组初始化越界
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data=atoi(temp->value.c_str());//操作数
strcpy(codes[cx_n].operate,"STO");
codes[cx_n++].operate_data = offset+count-2;
if(es>0) return es;
}
}
}
return es;
}
int var_stat_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="NUM"){
strcpy(codes[cx_n].operate,"LOADI");
codes[cx_n++].operate_data=atoi(temp->value.c_str());//操作数
strcpy(codes[cx_n].operate,"STO");
es=lookup(temp_id, &codes[cx_n++].operate_data);//temp_id 为上次存储 id_name
if(es>0) return es;
}
}
return es;
}
int declaration_stat_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="ID"){
temp_id=temp->value;//变量名保存
if(fun_n=="main"){
strcpy(codes[cx_n].operate,"ENTER");
codes[cx_n++].operate_data = 1; // enter
}
es=insert_symbol(temp_id,"var",1);//
if(es>0) return es;
}
else if(temp->str=="<var_stat>"){
es=var_stat_(temp);
if(es>0) return es;
}
else if(temp->str=="<arry>"){
es=arry_(temp);
if(es>0) return es;
}
}
return es;
}
int declaration_list_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="<declaration_stat>"){
es=declaration_stat_(temp);
if(es>0) return es;
}
}
//此时变量和形参个数已经确定下来
fun_list[fun_n].len_var = offset_n;//记录形参加局部变量个数
return es;
}
int function_body_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="<declaration_list>"){
es=declaration_list_(temp);
if(es>0) return es;
}
else if(temp->str=="<statement_list>"){
es=statement_list_(temp);
if(es>0) return es;
}
}
//函数返回 return 0
strcpy(codes[cx_n].operate,"RETURN"); //主动return 操作数设为 1 ,默认return 操作数为0
codes[cx_n++].operate_data = 0;//默认函数表达式返回 0
return es;
}
int para_list_(node *p){
int es=0;
int count=0;//记录形参个数
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str=="ID"){//插入符号表
count++;
es=insert_symbol(temp->value,"var",1);//插入符号表
if(es>0) return es;
}
}
fun_list[fun_n].num=count;//设置形参个数
return es;
}
int fun_declaration_(node *p){
int es=0;
int size=p->sons.size();
for(int i=0;i<size;i++){
node *temp = p -> sons[i];
if(temp->str == "ID"){//函数名
//printf("%s\n",temp->value.c_str());
fun_n = temp->value;//当前函数名
//printf("%d\n",cx_n);
es=insert_symbol(fun_n,"function",1);//插入函数符号表
if(es>0) return es;
}
else if(temp->str=="<para_list>"){
es=para_list_(temp);
if(es>0) return es;
}
else if(temp->str=="<function_body>"){
es= function_body_(temp);
if(es>0) return es;
}
}
return es;
}
int program_(node *p){
int es=0;
int size=p->sons.size();
main_cx=cx_n;//记录 main
strcpy(codes[cx_n++].operate,"BR");//操作数等待返填
for(int i=0;i<size;i++){//遍历孩子
node *temp = p -> sons[i];
if(temp->str=="<fun_declaration>"){
offset_n = 0;//每次进入 新函数 置0
es = fun_declaration_(temp);
if (es > 0) return es;
}
else if(temp->str=="<main_declaration>"){
offset_n = 0;//每次进入 新函数 置0
es = main_declaration_(temp);
if (es > 0) return es;
}
}
return es;
}
void printf_s(){
map< string , fun > ::iterator iter;
iter=fun_list.begin();
while(iter != fun_list.end()) {
string name_f = iter->first;
fun _f = iter->second;
fprintf(sym,"=======================================\n");
fprintf(sym,"函数名\t函数地址\t函数总长\t函数形参数\n");
fprintf(sym,"%s\t%d\t%d\t%d\n",name_f.c_str(),_f.address,_f.len_var,_f.num);
fprintf(sym,"-----------------------------------------------------------------\n");
map<string, var> _vars = _f.vars;
map<string, var> ::iterator it;
it=_vars.begin();
fprintf(sym,"变量名\t变量地址\t变量长度\n");
while(it != _vars.end()){
string name_v = it->first;
var _v = it->second;
fprintf(sym,"%s\t%d\t%d\n",name_v.c_str(),_v.address,_v.len);
it++;
}
fprintf(sym,"=======================================\n");
iter++;
}
//输出code数组
for(int i=0;i<cx_n;i++){
fprintf(mid_code,"%s\t%d\n",codes[i].operate,codes[i].operate_data);
}
}
栈式虚拟机
虚拟机指令
见实现
原理
栈式动态内存分配
实现
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<map>
using namespace std;
map<string,int> Map;
typedef struct Code{
char opt[10];
int operand;
}Code;
enum e_opt{
LOAD,LOADI,STO,ADD,SUB,MULT,DIV,BR,BRF,EQ,NOTEQ,GT,LES,GE,LE,AND,OR,NOT,IN,OUT,
ENTER,RETURN,CALL,
IPJMP,CPY,GET,PUT,DOWN
};
void init(){
Map["LOAD"] = LOAD;
Map["LOADI"] = LOADI;
Map["STO"] = STO;
Map["ADD"] = ADD;
Map["SUB"] = SUB;
Map["MULT"] = MULT;
Map["DIV"] = DIV;
Map["BR"] = BR;
Map["BRF"] = BRF;
Map["EQ"] = EQ;
Map["NOTEQ"] = NOTEQ;
Map["GT"] = GT;
Map["LES"] = LES;
Map["GE"] = GE;
Map["LE"] = LE;
Map["AND"] = AND;
Map["OR"] = OR;
Map["NOT"] = NOT;
Map["IN"] = IN;
Map["OUT"] = OUT;
Map["ENTER"] = ENTER;
Map["RETURN"] = RETURN;
Map["CALL"] = CALL;
Map["IPJMP"] = IPJMP;
Map["CPY"] = CPY;
Map["GET"] = GET;
Map["PUT"] = PUT;
Map["DOWN"] = DOWN;
}
int runTEST(char *midcodes_r,char *stack_r){
int es = 0;
int numcodes=0;
Code c[1000];
FILE *fin_m;
FILE *fout_m;
Code instruction;
init();
if((fin_m=fopen(midcodes_r,"r"))==NULL){
fclose(fin_m);
printf("\n打开错误\n");
return -1;
}
if((fout_m=fopen(stack_r,"w"))==NULL){
fclose(fout_m);
printf("\n打开错误\n");
return -1;
}
printf("\n------------------\n");
printf("虚拟机开始\n");
while(feof(fin_m)==0){
char temp[10];
fscanf(fin_m,"%s\t%s\n",c[numcodes++].opt,temp);
c[numcodes-1].operand = atoi(temp);
//printf("count:%d |%s|%d\n",numcodes-1,c[numcodes-1].opt,c[numcodes-1].operand);
}
int stack[150],top=0,base=0,ip=0;
for(int i=0;i<150;i++){
stack[i] = 0;
}
stack[0]=0;
stack[1]=0;
do{
instruction = c[ip];
char str[10];
int n=c[ip].operand;
strcpy(str,c[ip].opt);
ip++;
switch(Map[instruction.opt]){
case LOAD:{
stack[top++]=stack[base+2+instruction.operand];
break;
}
case LOADI:{
stack[top++]=instruction.operand;
break;
}
case STO:{
stack[base+2+instruction.operand]=stack[--top];
break;
}
case ADD:{
top--;
stack[top-1]=stack[top-1]+stack[top];
break;
}
case SUB:{
top--;
stack[top-1]=stack[top-1]-stack[top];
break;
}
case MULT:{
top--;
stack[top-1]=stack[top-1]*stack[top];
break;
}
case DIV:{
top--;
stack[top-1]=stack[top-1]/stack[top];
break;
}
case BR:{
ip=instruction.operand;
break;
}
case BRF:{
top--;
if(stack[top]==0)
ip=instruction.operand;
break;
}
case EQ:{
top--;
stack[top-1]=(stack[top-1]==stack[top]);
break;
}
case NOTEQ:{
top--;
stack[top-1]=(stack[top-1]!=stack[top]);
break;
}
case GT:{
top--;
stack[top-1]=(stack[top-1]>stack[top]);
break;
}
case LES:{
top--;
stack[top-1]=(stack[top-1]<stack[top]);
break;
}
case GE:{
top--;
stack[top-1]=(stack[top-1]>=stack[top]);
break;
}
case LE:{
top--;
stack[top-1]=(stack[top-1]<=stack[top]);
break;
}
case AND:{
top--;
stack[top-1]=(stack[top-1] && stack[top]);
break;
}
case OR:{
top--;
stack[top-1]=(stack[top-1]||stack[top]);
break;
}
case NOT:{
stack[top-1]= !stack[top-1];
break;
}
case IN:{
printf("输入数据\n");
scanf("%d",&stack[top++]);
break;
}
case OUT:{
printf("程序输出:%d\n",stack[--top]);
break;
}
case ENTER:{
top = top + instruction.operand;
break;
}
case RETURN:{//函数返回指令 函数可以作为表达式
if(instruction.operand==0){//默认return
top=base;
ip=stack[top+1];
base = stack[top];
stack[top++] = 0;
}
if(instruction.operand==1){
int temp = stack[top-1];
top=base;
ip=stack[top+1];
base = stack[top];
stack[top++] = temp;
}
break;
}
case CALL:{ //函数调用指令
stack[top-2-instruction.operand]=base;
base=top-2-instruction.operand;
break;
}
case GET:{//将栈顶(地址)换成地址对应局部变量数据
stack[top-1]=stack[stack[top-1]+base+2];
break;
}
case IPJMP:{//IP跳转
stack[base+1]=ip;
ip=instruction.operand;
break;
}
case PUT:{//取 次栈顶数据 放入 栈顶(地址)对应的空间里
top--;
stack[stack[top]+base+2]=stack[top-1];
break;
}
case CPY:{//复制栈顶元素
stack[top]=stack[top-1];
top++;
break;
}
case DOWN:{//清除栈顶元素
top = top - instruction.operand;
break;
}
}
fprintf(fout_m,"#%s\t%d#",str,n);
for(int i=0;i<=top;i++){
fprintf(fout_m,"\t|%d|",stack[i]);
}
fprintf(fout_m,"\n");
}while(ip != 0);
fclose(fin_m);
fclose(fout_m);
printf("虚拟机结束\n");
return es;
}
MAIN
踩过的坑:文件流打开后,不用时一定要关闭文件流。
#include "scan.h"
#include "parse.h"
#include "mashine.h"
char *WORK_PATH[6] = { "C:\\Users\\Desktop\\compile_results\\source_3.txt",//源文件
"C:\\Users\\Desktop\\compile_results\\word_3.txt",//词法分析结果
"C:\\Users\\Desktop\\compile_results\\result_3.txt",//语法树结果
"C:\\Users\\Desktop\\compile_results\\symbol_3.txt",//符号表结果
"C:\\Users\\Desktop\\compile_results\\codes_3.txt",//中间代码结果
"C:\\Users\\Desktop\\compile_results\\stack_3.txt"//虚拟机栈运行结果
};
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void printTEST(){
printf("\t\t*******************************************\n");
printf("\t\t\t\tTEST_Compiler\n");
printf("\t\t*******************************************\n");
}
int main(int argc, char** argv) {
printTEST();
if(scanTEST(WORK_PATH[0],WORK_PATH[1]) != -1){//源文件 词法分析结果
if(parseTEST(WORK_PATH[1],WORK_PATH[2],WORK_PATH[3],WORK_PATH[4]) != -1){//词法分析结果 语法树结果 符号表结果 中间代码结果
return runTEST(WORK_PATH[4],WORK_PATH[5]);//中间代码结果 虚拟机栈运行结果
}
}
return -1;
}