- 论坛徽章:
- 0
|
/**********************[[水乐天作品]]****************************/
/******************模拟编译系统(演示版)**********************/
/*********************版本号:0.0130************************/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "conio.h"
#include "alloc.h"
#include "graphics.h"
#include "Svga64k.h"
#include "fcntl.h"
#include "malloc.h"
#include "io.h"#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100/*存储空间初始分配量*/
#define STACKINCREMENT 20/*存储空间分配增量*/char*Messages[]=
{
/*语句类型信息列表*/
/*错误!*/
"(0)Error!",
/*说明语句*/
"(1)Explain language sentence!",
/*函数*/
"(2)Fouction!",
/*表达式*/
"(3)Expression!",
/*内存不足*/
"(4)EMS memory not enough!",
/*正常无类型*/
"(5)nomal"
};typedef struct
{
int *pBase;/*在构造之前和销毁之后,base的值为NULL*/
int *pTop;/*栈顶指针*/
int StackSize;/*当前已分配的存储空间,以元素为单位*/
}Stack;struct Kind
{
char Int_name[32];
int Int_value ;
}
;
/*用来模拟储存变量的内存*/struct Result
{
int Int ;
}
;
/*用来模拟储存结果的内存*/
struct Kind kind[10];
struct Result result ;char Source_text[100][600];
/*源文件数组*/
char Temp_text[600];
/*临时存放数组*/
char Clean_text[600];
/*临时存放脱去空格与关键字的数组*/
int Type=0 ;
/*语句的类型*/
char Type_name[32];
/*语句的类型名*/
int Embody=1 ;
/*语句具体类型*/const int MaxWordLen=32 ;
typedef int BOOLEAN;char Count[600];/*临时存放表达式的数组*/
int Count_i=-1;
char Operator[8]="+-*/()#";/*合法的操作符存储在字符串中*/
char Optr;/*操作符*/
int Opnd=-1;/*操作符*/
int Number_Result;/*操作结果*/int huge Return_SVGA64K(void)
{
return(0);
/* 返回各种分辨率的对应编号 0~6 宏定义参见 Svga64k.h */
}/*16Mrgb像素类型*/
typedef struct
{
unsigned char b ;
unsigned char g ;
unsigned char r ;
}
rgb16M ;void putpoint65536(int x,int y,rgb16M color)
{
setrgbpalette(1026,color.r>;>;3,color.g>;>;2,color.b>;>;3);
putpixel(x,y,0);
}/*以下是有关运算使用到的函数*/
Stack InitStack();
void DestoryStack(Stack *S);
int GetTop(Stack S);
int Push(Stack *S,int e);
int Pop(Stack *S,int *e);
char CheckPriority(char operator_1,char operator_2);
void GetInput(void);
int Calc(int a,char theta,int b);
BOOLEAN EvaluateExpression();void readme(void);
/*显示说明的函数*/
void Judge_type(void);
/*判断语句类型*/
void Judge_embody(void);
/*具体判断是什么语句*/
void No_key(void);
/*脱掉空格和关键字的函数*/
void No_space(void);
/*仅脱掉空格的函数*/
void Choice(void);
/*选择语句执行函数*/
void Run_program(int);
/*模拟运行程序的函数*/
void Run_Int(void);
/*模拟运行int的函数*/
void Run_Printf(void);
/*模拟运行printf()的函数*/
void Evaluate(void);
/*进行四则运算的函数*/
void No_line(void);/*这是程序执行时的标准参数写法,argc是参数的个数,argv表示参数具体的字串*/
void main(int argc,char*argv[])
{
FILE*fsource,*ftarget ;
/*两个文件指针分别指向源文件和目标文件*/
int i,ln,end ;
char line[600];
if(argc<3)
{
/*程序使用方法是:xx 原文件名 目标文件名 (假设程序编译为xx.exe)*/
readme();
getch();
exit(1);
}
/*使用fopen打开源文件失败的处理*/
if((fsource=fopen(argv[1],"rt")==NULL)
{
printf("Can't open source file %s.\n",argv[1]);
exit(1);
}
/*使用fopen打开目标文件失败的处理*/
if((ftarget=fopen(argv[2],"wt")==NULL)
{
printf("Can't open target file %s.\n",argv[2]);
exit(1);
}
ln=0 ;
/*以下是从源文件中逐行读出内容并存入Source_text[][]直到文件结束*/
while(fgets(line,512,fsource)!=NULL)
{
stpcpy(Source_text[ln],line);
ln++;
/*逐行读源文件*/
}
fclose(fsource);
for(i=0;i<=ln;i++)
{
printf("%s",Source_text);
}
printf("\n-------------------------------------------------------------------\n" end=1 ;
/*以下是向目标文件中逐行写入内容直到全部写完*/
while(end<=ln+1)
{
fprintf(ftarget,"%d: %s",end++,Source_text[end-1]);
/*加上行号写入目标文件*/
}
Run_program(ln);
/*开始模拟运行程序*/
fprintf(ftarget,"\n-------------------------------------------------------------------\n",end++,Source_text[end-1]);
fprintf(ftarget,"Ok!\nResult is:%d",result.Int);
fclose(ftarget);
printf("\nOperation accomplished.\n"
getch();
}
/*显示说明的函数*/
void readme(void)
{
int width,height,i=DETECT,j=0,x0,y0,fp ;
char fix ;
rgb16M*buffer ;
installuserdriver("Svga64K",Return_SVGA64K);
/*对于svga64k必需执行该函数以安装BGI驱动*/
initgraph(&i,&j,""
/* 执行TC默认的BGI初始化函数 */
if((fp=open("readme.bmp",O_RDONLY|O_BINARY))==-1)
{
puts("Can't find file " "readme.bmp" "."
printf("Incorrect Argument Numbers.\nUsagex Source_file Target_file\n"
exit(1);
}
lseek(fp,18,SEEK_SET);
read(fp,&width,4);
read(fp,&height,4);
fix=width%4 ;
x0=(320-width)/2 ;
y0=(200-height)/2 ;
lseek(fp,54,SEEK_SET);
buffer=(rgb16M*)malloc(width*sizeof(rgb16M));
for(j=height-1;j>;=0;j--)
{
read(fp,buffer,width*sizeof(rgb16M));
lseek(fp,fix,SEEK_CUR);
for(i=0;i<width;i++)
putpoint65536(x0+i,y0+j,buffer);
}
free(buffer);
close(fp);
getch();
closegraph();
}
/*模拟运行的主函数*/
void Run_program(int ln)
{
int i ;
char a=176,b=2;
for(i=0;i<=ln;i++)
{
stpcpy(Temp_text,Source_text);
printf("\n\n%d :",i);
Judge_type();
/*判断语句类型*/
Judge_embody();
/*具体判断是什么语句*/
if(Type!=3)
{
No_key();
}
else
{
No_space();
}
/*脱掉空格和关键字*/
Choice();
/*根据相应的类型进行选择*/
Type=0 ;
/*语句的类型*/
Embody=1 ;
/*语句具体类型*/
printf("\nPress any key continue...",b,a,a,a,b);
getch();
}
/*显示完成信息*/
clrscr();
printf("%c%c%c%c%c%c%c\n",a,a,a,a,a,a,a);
printf("%c%c%c%c%c%c%c\n",a,a,a,a,a,b,a);
printf("%c%c%c%c%c%c%c\n",a,a,a,a,b,a,a);
printf("%c%c%c%c%c%c%c\n",a,b,a,b,a,a,a);
printf("%c%c%c%c%c%c%c\n",a,a,b,a,a,a,a);
printf("%c%c%c%c%c%c%c\n",a,a,a,a,a,a,a);
printf("\n"
printf(" \1 OK!\n"
" \1 All done!\n"
" \1 Thank you for use!!!\n"
}
/*检验语句基本类型的函数*/
void Judge_type(void)
{
register int i=0,j=0,in_word=0 ;
char*Prompt="\nThe type of this sentence is:" ;
char*TestWord ;
char c ;
char*IsLegal(char*CheckWord);
TestWord=(char*)malloc(sizeof(char)*MaxWordLen);
/*TestWord存放用户输入*/
if(!TestWord)
return ;
for(i=0;(c=Temp_text)!='\0';i++)
if(c==' ')
{
if(in_word==1)
{
in_word=0 ;
TestWord[j]='\0' ;
j=0 ;
if((IsLegal(TestWord))!=Messages[5])
printf("%s %s",Prompt,IsLegal(TestWord));
}
}
else
{
TestWord[j]=c ;
in_word=1 ;
j++;
}
free(TestWord);
/*释放分配的内存区域*/
}
/*此函数检验语句的类型*/
char*IsLegal(char*CheckWord)
{
char*KeyWords[]=
{
"auto","break","case","char","continue","const","default",
"do","double","else","enum","extern","float","for","goto",
"if","int","long","noalias","register","return","short",
"signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while","defined",
"define","undef","include","ifdef","ifndef","endif","line",
"error","elif","pragma"
}
;
/*C关键字列表*/
char*Functions[]=
{
"close","creat","eof","fclose","fcloseall","feof","fopen",
"ferror","fgetchar","fgets","fprintf","fputc","fputchar",
"fseek","get","putch","putc","printf","open","putchar",
"puts","read","scanf","abs","acos","asin","math","atan",
"atan2","atof","atoi","atol","ceil","dos","cosh","ecvt",
"exp","fabs","floor","fmod","frexp","itoa","labs","ldexp",
"log","log10","modf","pow","rand","sin","sqrt","srand",
"strtod","strlol","tan","tanh","ultoa","memset","strcpy",
"struct","strchr","strcmp","calloc","isalnum","isalpha",
"toascii","tolower","tollpper","exit"
}
;
/*C主要函数列表*/
char*Operation[]=
{
"+","-","*","/","="
}
;
/*运算符列表*/
register int i ;
char*WordTemp ;
WordTemp=(char*)malloc(MaxWordLen*sizeof(char));
if(!WordTemp)return Messages[4];
/*判断其类型是否为关键字*/
for(i=0;i<44;i++)
{
if(!strcmp(CheckWord,KeyWords))
{
Type=1 ;
stpcpy(Temp_text,CheckWord);
return Messages[1];
}
}
/*判断其类型是否为函数*/
for(i=0;i<69;i++)
{
if(!strcmp(CheckWord,Functions))
{
Type=2 ;
stpcpy(Temp_text,CheckWord);
return Messages[2];
}
}
/*判断其类型是否为运算表达式*/
for(i=0;i<5;i++)
{
if(!strcmp(CheckWord,Operation))
{
Type=3 ;
Embody=1 ;
return Messages[3];
}
}
free(WordTemp);
return Messages[5];
}
/*进行具体语句类型判断的函数*/
void Judge_embody(void)
{
int i=1 ;
char*KeyWords[]=
{
"","int"
}
;
/*C关键字列表*/
char*Functions[]=
{
"","printf"
}
;
/*C主要函数列表*/
if(Type==1)
for(i=1;!strcmp(Type_name,KeyWords);i++)
Embody=i ;
if(Type==2)
for(i=1;!strcmp(Type_name,Functions);i++)
Embody=i ;
printf("\n(%d,%d)Type analysis succeed!\n",Type,Embody);
}
/*去除关键字和空格的函数*/
void No_key(void)
{
int i=0,j=0,hold=0 ;
i=strlen(Type_name);
/*取关键字最后一个字符*/
for(j=0;Type_name[i-1]!=Temp_text[j];j++)
;
/*查找这个字符在字符串中的首位址*/
for(i=j+1;Temp_text!=';';i++)
if(Temp_text!=' ')
{
Clean_text[hold]=Temp_text;
hold++;
}
/*脱空格,脱关键字*/
Clean_text[hold+1]='\0' ;
}
/*单纯去除空格的函数*/
void No_space(void)
{
int i=0,hold=0 ;
for(i=0;Temp_text!=';';i++)
if(Temp_text!=' ')
{
Clean_text[hold]=Temp_text;
hold++;
}
/*脱空格*/
Clean_text[hold+1]='\0' ;
}
/*进行选择的函数*/
void Choice(void)
{
void(*Function_name[5][2])(void)=
{
{
NULL,No_line
}
/*首位为空*/
,
{
NULL,Run_Int
}
/*存放关键字的指向函数的指针*/
,
{
NULL,Run_Printf
}
/*存放函数的指向函数的指针*/
,
{
NULL,Evaluate
}
/*存放用于运算的指向函数的指针*/
}
;
(*Function_name[Type])();
}
/*模拟int的函数*/
void Run_Int(void)
{
int i=0,j=0,hold=0,in_word=0 ;
char c ;
c=Clean_text[0];
do
{
if((c==',')||(c=='\0'))
{
if(in_word==1)
{
in_word=0 ;
kind[hold].Int_name[j]='\0' ;
hold++;
j=0 ;
}
}
else
{
kind[hold].Int_name[j]=c ;
in_word=1 ;
j++;
}
i++;
}
while((c=Clean_text)!='\0');
printf("\nInteger is:"
for(i=0;i<=hold;i++)
printf(" %s ",kind.Int_name);
}
/*模拟printf()的函数*/
void Run_Printf(void)
{
int i=0,j=0,k=0,in_word=0,hold=0 ;
char temp[32];
char c ;
c=Clean_text[0];
do
{
if((c==',')||(c==')')||(c=='\"'))
{
if(in_word==1)
{
in_word=0 ;
temp[j]='\0' ;
j=0 ;
if(!strcmp(temp,"%d"))
{
hold=1 ;
}
;
if(hold==1)
for(k=0;k<=10;k++)
if(!strcmp(temp,kind[k].Int_name))
result.Int=kind[k].Int_value ;
/*如果是变量则把变量的值付给结果*/
}
}
else
{
temp[j]=c ;
in_word=1 ;
j++;
}
i++;
}
while((c=Clean_text)!='\0');
printf("printf :%d",result.Int);
}
/*进行运算的函数*/
void Evaluate(void)
{
int i=0,j=0,k,f,temp=0,in_word=0;
char c='';
char c1[32]={""},c2[10]={""};
/*找到空格的位置*/
for(temp=0;Clean_text[temp]!='=';temp++)
;
i=temp+1;
c=Clean_text;
do
{
/*判断是否是运算中用到的关键字*/
if(
(c=='+')||(c=='-')||(c=='/')||(c=='*')||
(c==')')||(c=='(')||(c=='\0')||(c>;='0'&&c<='9')
)
{
/*如果是则判断是否是变量,并把关键字存入变量之中*/
if(in_word==1)
{
in_word=0 ;
c1[j]='\0' ;
j=0 ;
for(k=0;k<=10;k++)
if(!strcmp(c1,kind[k].Int_name))
{
itoa(kind[k].Int_value,c2, 10);
strcat(Count,c2);
}
}
f=strlen(Count);
Count[f]=c;
}
/*如果不是则字符入串*/
else
{
c1[j]=c ;
in_word=1 ;
j++;
}
i++;
c=Clean_text;
/*因为为了把最后一位的字符加入所以i-1*/
}while(Clean_text[i-1]!='\0');
/*在字符串最后加入结束标记#*/
k=strlen(Count);
Count[k-1]='#';
Count[k]='\0';
/*开始进行运算*/
EvaluateExpression();
/*输出运算过程*/
printf("=%d\n",Number_Result);
/*清空c1*/
stpcpy(c1,"");
/*找到=之前的标识符*/
for(i=0;i<temp;i++)
c1=Clean_text;
c1[i+1]='\0';
/*显示结果标识符的值*/
for(k=0;k<=10;k++)
if(!strcmp(c1,kind[k].Int_name))
{
kind[k].Int_value=Number_Result;
printf("%s=%d\n",kind[k].Int_name,kind[k].Int_value);
}
}
/*运算符间的优先关系*/
char PriorityTable[7][7]=
{
{'>;','>;','<','<','<','>;','>;'},
{'>;','>;','<','<','<','>;','>;'},
{'>;','>;','>;','>;','<','>;','>;'},
{'>;','>;','>;','>;','<','>;','>;'},
{'<','<','<','<','<','=','o'},
{'>;','>;','>;','>;','o','>;','>;'},
{'<','<','<','<','<','o','='},
};
/* 数据对象的操作方法 */
/* 构造一个空栈,如果返回值为0,则表示初始化失败 */
Stack InitStack()/*这是个效率低的方法*/
{
Stack S;
S.pBase=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!S.pBase)
{/*内存分配失败*/
printf("内存分配失败,程序中止运行\n");
exit(-1);
}
else
{
S.pTop=S.pBase;
S.StackSize=STACK_INIT_SIZE;
}
return S;
}
/* 销毁栈S,S不再存在 */
void DestoryStack(Stack *S)
{
if(S->;pBase)
{
free(S->;pBase);
S->;pTop=S->;pBase=NULL;
}
}
/* 若栈不空,则用e返回S的栈顶元素 */
/* 注:由于应用的特殊,可以不检查栈是否为空 */
int GetTop(Stack S)
{
return *(S.pTop-1);
}
/* 插入元素e为新的栈顶元素,如果成功则返回1,否则返回0 */
int Push(Stack *S,int e)
{
if(S->;pTop-S->;pBase==S->;StackSize)
{/* 栈满,追加存储空间 */
S->;pBase=(int*)realloc(S->;pBase,S->;StackSize+STACKINCREMENT*sizeof(int));
if(!S->;pBase)
return 0;/* 存储分配失败 */
S->;pTop=S->;pBase+S->;StackSize;
S->;StackSize+=STACKINCREMENT;
}
*(S->;pTop++)=e;
return 1;
}
int Pop(Stack *S,int *e)
{/* 若栈不空,则删除S的栈顶元素,用e 返回其值,并返回1;否则返回0 */
if(S->;pTop==S->;pBase)
return 0;
*e=*--(S->;pTop);
return 1;
}
/* 主函数及其它函数的实现 */
/* 比较两个数学符号operator_1,operator_2的计算优先权,在算符优先关系表中查找相应的关系并返回'<','=',或'>;' */
char CheckPriority(char operator_1,char operator_2)
{
int i,j;/* 用来查询算符间优先关系表的下标 */
/* char *ptr; */
i=strchr(Operator,operator_1)-Operator;/* 找到传入操作符在字符串Operators中的相对位置 */
j=strchr(Operator,operator_2)-Operator;
/* 返回算符优先关系表中相应值 */
return PriorityTable[j];
}
BOOLEAN IsOperator(char ch)
{/* 判断一个字符是否为打操作符 */
if(strchr(Operator,ch))
return TRUE;
else
return FALSE;
}
/* 从数组中获得字符 */
void GetInput(void)
{
char Buffer[20];/* 键盘输入缓冲区,用来处理输入多位数的情况 */
char ch;/* 存放键盘输入 */
int index;/* 存放Buffer的下标 */
index=0;
Count_i+=1;
ch=Count[Count_i];/* 从键盘读入一个字符 */
while(ch!='#'&&!IsOperator(ch))
{/* 如果字符是回车符或是操作符,循环结束 */
if(ch>;='0'&&ch<='9')
{/* 将字符回显到屏幕 */
printf("%c",ch);
Buffer[index]=ch;
index++;
}
Count_i+=1;
ch=Count[Count_i];
}
if(ch=='#')
Optr='#';/* 输入的表达式以#结束 */
else
{
Optr=ch;
printf("%c",ch);
}
if(index>;0)
{
Buffer[index]='\0';
Opnd=atoi((Buffer));
}
else
Opnd=-1;/* 程序不支持输入负数,当Opnd为负数时,表示输入的字符为操作符 */
}
/* 计算形如a+b之类的表达式,theta为操作符,a,b为操作数 */
int Calc(int a,char theta,int b)
{
switch(theta)
{
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
default:
if(b==0)/* 除数为零的情况 */
{
printf("除数不能为");
return 0;/* 返回0用以显示 */
}
else
return a/b;
}
}
/*表达式求值*/
BOOLEAN EvaluateExpression()
{
int temp;/* 临时变量 */
int itheta;/* 存放出栈的操作符的变量add by me */
int a,b;/* 存放表达式运算时的中间值 */
int topOpnd;/* 栈顶操作数 */
char topOptr;/* 栈顶操作符 */
Stack OPTR=InitStack();/* 操作符栈 */
Stack OPND=InitStack();/* 操作数栈 */
if(!Push(&OPTR,'#'))/* 操作符栈中的第一个为#字符 */
return FALSE;
GetInput();/* 从获得字符 */
while(Optr!='#'||GetTop(OPTR)!='#')
{/* 如果Optr>;=0,表示有操作数输入 */
if(Opnd>;=0)Push(&OPND,Opnd);
switch(CheckPriority(GetTop(OPTR),Optr))
{
case '<':/* 栈顶元素优先权低 */
if(!Push(&OPTR,Optr))return FALSE;
GetInput();
break;
case '=':/* 脱括号并接收键盘输入 */
Pop(&OPTR,&temp);GetInput();
break;
case '>;':/* 退栈并将运算结果入栈 */
/* 先用itheta得到操作符在赋给theta */
Pop(&OPTR,&itheta);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND,Calc(a,itheta,b));
Opnd=-1;
break;
}
}
/* 本算法中,当输入只有一个操作数然后就输入回车符时, */
/* OPND.pTop==OPND.pBase */
/* 如果OPND.pTop==OPND.pBase并且Opnd<0,则说明用户 */
/* 未输入任何操作和操作符而直接输入#,程序直接 */
/* 退出运行 */
if(OPND.pTop==OPND.pBase&&Opnd<0)
{
printf("\n\nThank you choice!\n");
exit(1);
}
else if(OPND.pTop==OPND.pBase)
Number_Result=Opnd;
else
{
Number_Result=GetTop(OPND);
DestoryStack(&OPND);
DestoryStack(&OPTR);
}
return TRUE;
}
/*对于没有语句的处理*/
void No_line(void)
{
printf("Can't find line");
} |
|