Test语言编译器V0.8

时间:2023-02-03 23:04:27

感觉这个挺好耍的,书上的代码有错误,而且功能有限。

一、词法分析

特点:

(1)可对中文进行识别:
(2)暂不支持负数,可以在读入‘-'时进行简单标记后就能对简单负数进行识别了。

Test语言编译器V0.8Test语言编译器V0.8
#include <iostream>
#include
<cstdio>
#include
<cctype>
#include
<cstring>
using namespace std;
#define KEYWORDNUM 9 //关键字个数
#define MAXLENGTH 39 //标识符最大长度
#define MAXFILENAME 100 //文件名最大长度

namespace Testscan{
FILE
*fin,*fout;
char Scanin[MAXFILENAME],Scanout[MAXFILENAME];
char *keyword[KEYWORDNUM]={"if","else","for","while","do","int","read","write","main"};
char singleword[]="+-*%(){};,:";
char doubleword[]="><=!";
char token[MAXLENGTH+2]; //存放识别单词
int frow,brow; //符号起止行标记
int i,j,k,es; //临时整型变量
char ch,ch1; //临时字符变量
}
using namespace Testscan;
/******************************/
/* 错误列表:
1 打开输入文件出错
2 打开输出文件出错
3 标识符过长
4 标识符命名不合法
*/
/******************************/

int Init()
{
//printf("请输入源程序文件名(包括路径):\n");
//scanf("%s", Scanin);
//printf("请输入词法分析输出文件名(包括路径):\n");
//scanf("%s", Scanout);

strcpy(Scanin,
"C:\\Users\\Administrator\\Desktop\\in.txt");
strcpy(Scanout,
"C:\\Users\\Administrator\\Desktop\\out1.txt");

if ((fin=fopen(Scanin,"r"))==NULL){
printf(
"打开词法分析输入文件出错!\n");
return 1;
}
if ((fout=fopen(Scanout,"w"))==NULL){
printf(
"创建词法分析输出文件出错!\n");
return 2;
}
return 0;
}
char getNextChar()
{
char ch=getc(fin);
if(ch=='\n') frow++;
return ch;
}
int TESTscan()
{
int es=Init();
if(es>0) return es;

frow
=brow=1;
ch
=getNextChar();
while (ch!=EOF)
{
while(ch==' ' || ch=='\n' || ch=='\t'){
ch
=getNextChar();
}

brow
=frow;
if (ch==EOF) break;

if (isalpha(ch)){ //字母
j=0;
token[j
++]=ch;
bool isLong=false; //超长标记
ch=getNextChar();
while (isalnum(ch)){ //字母+数字
token[j++]=ch;
ch
=getNextChar();
if (j>MAXLENGTH){
isLong
=true;
while (isalnum(ch)){ //超长,自动截断
ch=getNextChar();
}
}
}
token[j]
='\0';
if (isLong==true){ //标识符太长
es=3;
printf(
"ERROR(%d): 标识符\"%s\"超长\n",brow,token);
fprintf(fout,
"%d\t%s\t%s\n",brow,"ERROR",token);
continue;
}

k
=0;
char str[MAXLENGTH+2];
for (i=0;i<strlen(token);i++){ //小写化
str[i]=tolower(token[i]);
}
str[i]
='\0';
while (k<KEYWORDNUM && strcmp(str,keyword[k]))
k
++;
if (k>=KEYWORDNUM)
fprintf(fout,
"%d\t%s\t%s\n",brow,"ID",token);
else
fprintf(fout,
"%d\t%s\t%s\n",brow,str,token);
}

else if (isdigit(ch)){ //数字
j=0;
token[j
++]=ch;
ch
=getNextChar();
while (isdigit(ch)){
token[j
++]=ch;
ch
=getNextChar();
}
token[j]
='\0';
fprintf(fout,
"%d\t%s\t%s\n",brow,"NUM",token);
}

else if (strchr(singleword,ch)>0){ //单分界符
token[0]=ch;
token[
1]='\0';
fprintf(fout,
"%d\t%s\t%s\n",brow,token,token);
ch
=getNextChar();
}

else if (strchr(doubleword,ch)>0){ //双分界符
token[0]=ch;
ch
=getNextChar();
if (ch=='='){
token[
1]=ch;
token[
2]='\0';
ch
=getNextChar();
}
else token[1]='\0';
fprintf(fout,
"%d\t%s\t%s\n",brow,token,token);
}

else if (ch=='/'){ //注释
ch=getNextChar();
if (ch=='*'){
ch1
=getNextChar();
do{ //删除注释
ch=ch1;
ch1
=getNextChar();
}
while ((ch!='*' || ch1!='/') && ch1!=EOF);
ch
=getNextChar();
}
else{
token[
0]='/';
token[
1]='\0';
fprintf(fout,
"%d\t%s\t%s\n",brow,token,token);
}
}

else if (ch=='\"'){ //字符串
j=0;
ch
=getNextChar();
while (ch!='\"'){
token[j
++]=ch;
ch
=getNextChar();
}
token[j]
='\0';
fprintf(fout,
"%d\t%s\t%s\n",brow,"STR",token);
ch
=getNextChar();
}

else{ //命名不规范
token[0]=ch;
token[
1]='\0';
if(ch<0){ //中文处理
ch=getNextChar();
token[
1]=ch;
token[
2]='\0';
}
es
=4;
fprintf(fout,
"%d\t%s\t%s\n",brow,"ERROR",token);
printf(
"ERROR(%d): 符号\"%s\"不规范\n",brow,token);
ch
=getNextChar();
}
}
fprintf(fout,
"%d\tEOF\tEOF\n",brow);
fclose(fin);
fclose(fout);
return es;
}
View Code

 

二、语法分析

特点:

(1)修正书上代码中存在的大量错误

(2)增加对复合语句的处理

(3)支持变量连续定义

(4)支持字符串(可带空白字符)的输出

(5)报错具体到行中的具体位置

(6)无除0报错,首先除0报错不属于语法分析,其次通过改正也只能报5/0这种显式错误,不能报9/(3+2-5)这种错误,因此意义不大

(7)无死循环错误,首先不属于语法分析,其次现在没有一种程序设计语言能报这种错误,循环中可根据条件改变变量的值,是不可预知的

Test语言编译器V0.8Test语言编译器V0.8
#include <stdio.h>
#include
<ctype.h>
#include
<conio.h>
#include
<string.h>
#include
<windows.h>

int TESTparse();
int program();
int compound_Stat();
int statement();
int expression_Stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int do_while_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int expression_stat();

#define MAXFILENAME 100 //文件名最大长度
#define MAXLENGTH 40 //字符串最大长度

using namespace Testparse1{
int wrow; //错误行号
FILE *fin,*fout; //输入输出文件的指针
char token[MAXLENGTH],token1[MAXLENGTH]; //token保存单词符号,token1保存单词值
char Scanin[MAXFILENAME],Scanout[MAXFILENAME]; //输入输出文件名
}
using namespace Testparse1;
int TESTparse()
{
int es=0;
if ((fin=fopen(Scanin,"r"))==NULL){
printf(
"\n打开%s错误!\n",Scanout);
es
=10;
}

if ((fout=fopen(Scanout,"w"))==NULL){
printf(
"\n打开%s错误!\n",Scanout);
es
=10;
}

if (es==0) es=program();
printf(
"=====语法分析结果!======\n");
switch(es)
{
case 0: printf("语法分析成功!\n");break;
case 10:printf("打开文件失败!\n");break;
case 1: printf("ERROR(%d): \"%s\"前面缺少{\n",wrow,token1);break;
case 2: printf("ERROR(%d): \"%s\"前面缺少}\n",wrow,token1);break;
case 3: printf("ERROR(%d): \"%s\"前面缺少标识符\n",wrow,token1);break;
case 4: printf("ERROR(%d): \"%s\"前面缺少分号\n",wrow,token1);break;
case 5: printf("ERROR(%d): \"%s\"前面缺少(\n",wrow,token1);break;
case 6: printf("ERROR(%d): \"%s\"前面缺少)\n",wrow,token1);break;
case 7: printf("ERROR(%d): \"%s\"前面缺少操作数\n",wrow,token1);break;
case 9: printf("ERROR(%d): \"%s\"前面缺少主程序\n",wrow,token1);break;
case 11:printf("ERROR(%d): 主程序名错误!\n",wrow);break;
case 12:printf("ERROR(%d): \"%s\"前面缺少while\n",wrow,token1);break;
case 25:printf("ERROR(%d): \"%s\"已超出程序末尾\n",wrow,token1);break;
case 26:printf("ERROR(%d): else没有匹配的if\n",wrow);
}
fclose(fin);
fclose(fout);
return es;
}

//<程序>::={<声明序列><语句序列>}
//program::={<declaration_list><statement_list>}
int program()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=declaration_list(); //声明语句
if (es>0) return es;

if (strcmp(token,"main")) return 9; //main区
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"ID")) return 11; //程序名
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"{")) return 1; //判断是否'{'
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement_list(); //语句序列
if (es>0) return es;
if (strcmp(token,"}")) return 2; //判断是否'}'
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"EOF")) return 25; //超出程序末尾
return es;
}

//<声明序列>::=<声明序列><声明语句>|<声明语句>
//<declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list()
{
int es=0;
while (strcmp(token,"int")==0){
es
=declaration_stat();
if (es>0) return es;
}
return es;
}

//<声明语句>::=int<变量>;
//<declaration_stat>::=int ID;
int declaration_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
while (1){ //支持连续定义
if (strcmp(token,"ID")) return 3; //不是标识符
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,",")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
}
else break;
}
if (strcmp(token,";") ) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<语句序列>::=<语句序列><语句>|<语句>
//<statement_list>::=<statement_list><statement>|<statement>
int statement_list()
{
int es=0;
while (strcmp(token,"}")){
es
=statement();
if (es>0) return es;
if (strcmp(token,"EOF")==0){
return 2; //缺少}
}
}
return es;
}

//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
//<statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement()
{
int es=0;
if ((strcmp(token,"if")==0 || strcmp(token,"else")==0)) es=if_stat();//<IF语句>
else if (strcmp(token,"while")==0) es=while_stat();//<while语句>
else if (strcmp(token,"for")==0) es=for_stat();//<for语句>
else if (strcmp(token,"do")==0) es=do_while_stat(); //do_while语句
else if (strcmp(token,"read")==0) es=read_stat();//<read语句>
else if (strcmp(token,"write")==0) es=write_stat();//<write语句>
else if (strcmp(token,"{")==0) es=compound_stat();//<复合语句>
else if ((strcmp(token,"ID")==0 || strcmp(token,"NUM")==0 || strcmp(token,"(")==0) || strcmp(token,";")==0) es=expression_stat();//<表达式语句>
return es;
}

//<IF语句>::=if(<表达式>)<语句>[else<语句>]
//<IF_stat>::=if(<expr>)<statement>[else<statement>]
int if_stat()
{
if (strcmp(token,"else")==0) return 26; //else未匹配if
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement(); //语句
if (es>0) return es;

if (strcmp(token,"else")==0){ //else部分处理
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
}
return es;
}

//<复合语句>::={<语句序列>}
//<compound_stat>::={<statement_list>}
int compound_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement_list(); //语句序列
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

// <do_whilie语句>::do{语句序列}while(表达式)
// <do_whilie_stat>::do{statment_list}while(expression)
int do_while_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"{")) return 1; //缺少左括号
es=statement(); //语句
if (es>0) return es;
printf(
"%s %s\n",token,token1);
if(strcmp(token,"while")) return 12; //缺少while

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);

es
=expression(); //表达式
if (es>0) return es;

if (strcmp(token,")")) return 6; //缺少右括号
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<while语句>::=while(<表达式>)<语句>
//<while_stat>::=while(<expr>)<statement >
int while_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
return es;
}

//<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>
//<for_stat>::=for(<expr>,<expr>,<expr>)<statement>
//<for_stat>::=for (<expression>;
int for_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,";")) return 4; //缺少分号

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,";")) return 4; //缺少分号

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
return es;
}

//<read_语句>::=read<变量>;
//<read_stat>::=read ID;
int read_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"ID")) return 3; //缺少标识符

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,";")) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<write_语句>::=write <表达式>;
//<write_stat>::=write <expression>;
//<write_STR>::write <STR>;
int write_stat()
{
int es=0;
fscanf(fin,
"%d %s ",&wrow,token);
printf(
"%s ",token);
if (strcmp(token,"STR")==0){ //输出字符串
fgets(token1,1024,fin);
printf(
"%s",token1);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,";")) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
fscanf(fin,
"%s",&token1);
printf(
"%s\n",token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,";")) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<表达式语句>::=<<表达式>;|;
//<expression_stat>::=<expression>;|;
int expression_stat()
{
int es=0;
if (strcmp(token,";")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
es
=expression();
if (es>0) return es;
if (strcmp(token,";")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
else{
return 4; //缺少分号
}
}

//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
//<expr>::=ID=<bool_expr>|<bool_expr>
int expression()
{
int es=0,fileadd;
char token2[MAXLENGTH+2],token3[MAXLENGTH+2];
if (strcmp(token,"ID")==0){
fileadd
=ftell(fin); //记住当前文件位置
fscanf(fin,"%d %s %s\n",&wrow,token2,token3);
printf(
"%s %s\n",token2,token3);

if (strcmp(token2,"=")==0){ //'='
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=bool_expr();
if (es>0) return es;
}
else{ //"=="
fseek(fin,fileadd,0); //若非'='则文件指针回到'='前的标识符
es=bool_expr();
if (es>0) return es;
}
}
else{
es
=bool_expr();
}
return es;
}

//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
//<bool_expr>::=<additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
int bool_expr()
{
int es=0;
es
=additive_expr();
if (es>0) return es;
if (strcmp(token,">")==0 || strcmp(token,">=")==0 || strcmp(token,"<")==0 ||
strcmp(token,
"<=")==0 || strcmp(token,"==")==0 || strcmp(token,"!=")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
//保存运算符
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=additive_expr();
if (es>0) return es;
}
return es;
}

//<算术表达式>::=<项>{(+|-)<项>}
//<additive_expr>::=<term>{(+|-)< term >}
//< additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr()
{
int es=0;
es
=term();
if (es>0) return es;
while (strcmp(token,"+")==0 || strcmp(token,"-")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=term();
if (es>0) return es;
}
return es;
}

//<项>::=<因子>{(*|/)<因子>}
//< term >::=<factor>{(*| /)< factor >}
//< term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)}
int term()
{
int es=0;
es
=factor();
if (es>0) return es;
while (strcmp(token,"*")==0 || strcmp(token,"/")==0 || strcmp(token,"%")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=factor();
if (es>0) return es;
}
return es;
}

//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>
//< factor >::=(<additive_expr>)| ID|NUM
int factor()
{
int es=0;
if (strcmp(token,"(")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression(); //表达式
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
}
else{
if (strcmp(token,"ID")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
else if (strcmp(token,"NUM")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
return es;
}
else{
return 7; //缺少操作数
}
}
return es;
}
View Code

 

三、语义分析

特点同上

Test语言编译器V0.8Test语言编译器V0.8
#include <stdio.h>
#include
<ctype.h>
#include
<conio.h>
#include
<string.h>
#include
<windows.h>

int TESTparse();
int program();
int compound_Stat();
int statement();
int expression_Stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int do_while_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int expression_stat();

#define MAXVARTABLEP 500 //定义符号表的容量
#define MAXFILENAME 100 //文件名最大长度
#define MAXLENGTH 40 //字符串最大长度

namespace Testparse{
struct Table //定义符号表结构
{
char name[MAXLENGTH];
int address;
}vartable[MAXVARTABLEP];
int vartablep=0,labelp=0,datap=0;

int wrow; //错误行号
FILE *fin,*fout; //输入输出文件的指针
char token[MAXLENGTH],token1[MAXLENGTH]; //token保存单词符号,token1保存单词值
char Scanin[MAXFILENAME],Scanout[MAXFILENAME]; //输入输出文件名
}
using namespace Testparse;
int TESTparse()
{
//system("C:\\Users\\Administrator\\Desktop\\test.exe");
strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\out1.txt");
strcpy(Scanout,
"C:\\Users\\Administrator\\Desktop\\out2.txt");


int es=0;
if ((fin=fopen(Scanin,"r"))==NULL){
printf(
"\n打开%s错误!\n",Scanout);
es
=10;
}

if ((fout=fopen(Scanout,"w"))==NULL){
printf(
"\n打开%s错误!\n",Scanout);
es
=10;
}

if (es==0) es=program();
printf(
"=====语法分析结果!======\n");
switch(es)
{
case 0: printf("语义分析成功!\n");break;
case 10:printf("打开文件失败!\n");break;
case 1: printf("ERROR(%d): \"%s\"前面缺少{\n",wrow,token1);break;
case 2: printf("ERROR(%d): \"%s\"前面缺少}\n",wrow,token1);break;
case 3: printf("ERROR(%d): \"%s\"前面缺少标识符\n",wrow,token1);break;
case 4: printf("ERROR(%d): \"%s\"前面缺少分号\n",wrow,token1);break;
case 5: printf("ERROR(%d): \"%s\"前面缺少(\n",wrow,token1);break;
case 6: printf("ERROR(%d): \"%s\"前面缺少)\n",wrow,token1);break;
case 7: printf("ERROR(%d): \"%s\"前面缺少操作数\n",wrow,token1);break;
case 9: printf("ERROR(%d): \"%s\"前面缺少主程序\n",wrow,token1);break;
case 11:printf("ERROR(%d): 主程序名错误!\n",wrow);break;
case 12:printf("ERROR(%d): \"%s\"前面缺少while\n",wrow,token1);break;
case 21:printf("ERROR(%d): 符号表溢出\n",wrow);break;
case 22:printf("ERROR(%d): 变量\"%s\"重复定义\n",wrow,token1);break;
case 23:printf("ERROR(%d): 变量\"%s\"未声明\n",wrow,token1);break;
case 25:printf("ERROR(%d): \"%s\"已超出程序末尾\n",wrow,token1);break;
case 26:printf("ERROR(%d): else没有匹配的if\n",wrow);
}
fclose(fin);
fclose(fout);
return es;
}

//插入符号表
int name_def(char *name)
{
if (vartablep>=MAXVARTABLEP) return 21; //符号表溢出
for (int i=vartablep-1;i>=0;i--){
if (strcmp(vartable[i].name,name)==0){
return 22; //变量重复定义
}
}
strcpy(vartable[vartablep].name,name);
vartable[vartablep
++].address=datap++;
return 0;
}

//查询符号表返回地址
int lookup(char *name,int *paddress)
{
for (int i=0;i<vartablep;i++){
if (strcmp(vartable[i].name,name)==0){
*paddress=vartable[i].address;
return 0;
}
}
return 23; //变量未声明
}

//<程序>::={<声明序列><语句序列>}
//program::={<declaration_list><statement_list>}
int program()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=declaration_list(); //声明语句
if (es>0) return es;

printf(
" 符号表\n"); //符号表输出
printf(" 名字 地址\n");
for(int i=0;i<vartablep;i++)
printf(
"%10s%10d\n",vartable[i].name,vartable[i].address);

if (strcmp(token,"main")) return 9; //main区
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"ID")) return 11; //程序名
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"{")) return 1; //判断是否'{'
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement_list(); //语句序列
if (es>0) return es;
if (strcmp(token,"}")) return 2; //判断是否'}'
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"EOF")) return 25; //超出程序末尾
fprintf(fout," STOP\n"); //产生停止指令
return es;
}

//<声明序列>::=<声明序列><声明语句>|<声明语句>
//<declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list()
{
int es=0;
while (strcmp(token,"int")==0){
es
=declaration_stat();
if (es>0) return es;
}
return es;
}

//<声明语句>::=int<变量>;
//<declaration_stat>::=int ID;
//<declaration_stat>↓vartablep,datap,codep ->int ID↑n@name-def↓n,t;
int declaration_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
while (1){ //支持连续定义
if (strcmp(token,"ID")) return 3; //不是标识符
es=name_def(token1); //插入到符号表
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,",")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
}
else break;
}
if (strcmp(token,";") ) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<语句序列>::=<语句序列><语句>|<语句>
//<statement_list>::=<statement_list><statement>|<statement>
int statement_list()
{
int es=0;
while (strcmp(token,"}")){
es
=statement();
if (es>0) return es;
if (strcmp(token,"EOF")==0){
return 2; //缺少}
}
}
return es;
}

//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
//<statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement()
{
int es=0;
if ((strcmp(token,"if")==0 || strcmp(token,"else")==0)) es=if_stat();//<IF语句>
else if (strcmp(token,"while")==0) es=while_stat();//<while语句>
else if (strcmp(token,"for")==0) es=for_stat();//<for语句>
else if (strcmp(token,"do")==0) es=do_while_stat(); //do_while语句
else if (strcmp(token,"read")==0) es=read_stat();//<read语句>
else if (strcmp(token,"write")==0) es=write_stat();//<write语句>
else if (strcmp(token,"{")==0) es=compound_stat();//<复合语句>
else if ((strcmp(token,"ID")==0 || strcmp(token,"NUM")==0 || strcmp(token,"(")==0) || strcmp(token,";")==0) es=expression_stat();//<表达式语句>
return es;
}

//<IF语句>::=if(<表达式>)<语句>[else<语句>]
//<IF_stat>::=if(<expr>)<statement>[else<statement>]
//if (<expression>)@BRF↑label1 <statement > @BR↑label2 @SETlabel↓label1
//[ else < statement >] @SETlabel↓label2
// 其中动作符号的含义如下
// @BRF↑label1 :输出 BRF label1,
// @BR↑label2:输出 BR label2,
// @SETlabel↓label1:设置标号label1
// @SETlabel↓label2:设置标号label2
int if_stat()
{
if (strcmp(token,"else")==0) return 26; //else未匹配if
int es=0,label1,label2;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号
label1=labelp++; //用label1记住条件为假时要转向的标号
fprintf(fout," BRF LABEL%d\n",label1);

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement(); //语句
if (es>0) return es;

label2
=labelp++; //用label2记住要转向的标号
fprintf(fout," BR LABEL%d\n",label2);
fprintf(fout,
"LABEL%d:\n",label1); //设置label1记住的标号

if (strcmp(token,"else")==0){ //else部分处理
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
}
fprintf(fout,
"LABEL%d:\n",label2); //设置label2记住的标号
return es;
}

//<复合语句>::={<语句序列>}
//<compound_stat>::={<statement_list>}
int compound_stat()
{
int es=0;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement_list(); //语句序列
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

// <do_whilie语句>::do{语句序列}while(表达式)
// <do_whilie_stat>::do{statment_list}while(expression)
int do_while_stat()
{
int es=0,label1,label2;
label1
=labelp++;
fprintf(fout,
"LABEL%d:\n",label1); //设置label1标号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"{")) return 1; //缺少左括号
es=statement(); //语句
if (es>0) return es;
printf(
"%s %s\n",token,token1);
if(strcmp(token,"while")) return 12; //缺少while

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);

es
=expression(); //表达式
if (es>0) return es;
label2
=labelp++;
fprintf(fout,
" BRF LABEL%d\n",label2);
fprintf(fout,
" BR LABEL%d\n",label1);

if (strcmp(token,")")) return 6; //缺少右括号
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
fprintf(fout,
"LABEL%d:\n",label2); //设置label2标号
return es;
}

//<while语句>::=while(<表达式>)<语句>
//<while_stat>::=while(<expr>)<statement >
//<while_stat>::=while @SET↑labellabel1(<expression>) @BRF↑label2
// <statement >@BR↓label1 @SETlabel↓label2
//动作解释如下:
//@SETlabel↑label1:设置标号label1
//@BRF↑label2 :输出 BRF label2,
//@BR↓label1:输出 BR label1,
//@SETlabel↓label2:设置标号label2
int while_stat()
{
int es=0,label1,label2;
label1
=labelp++;
fprintf(fout,
"LABEL%d:\n",label1); //设置label1标号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号

label2
=labelp++;
fprintf(fout,
" BRF LABEL%d\n",label2);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
fprintf(fout,
" BR LABEL%d\n",label1);
fprintf(fout,
"LABEL%d:\n",label2); //设置label2标号
return es;
}

//<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>
//<for_stat>::=for(<expr>,<expr>,<expr>)<statement>
//<for_stat>::=for (<expression>;
//@SETlabel↑label1< expression >@BRF↑label2@BR↑label3;
//@SETlabel↑label4 < expression >@BR↓label1)
//@SETlabel↓label3 <语句 >@BR↓label4@SETlabel↓label2
//动作解释:
// @SETlabel↓label1:设置标号label1
// @BRF↑label2 :输出 BRF label2,
// @BR↑label3:输出 BR label3,
// @SETlabel↓label4:设置标号label4
// @BR↑label1:输出 BR label1,
// @SETlabel↓label3:设置标号label3
// @BR↑label4:输出 BR label4,
// @SETlabel↓label2:设置标号label2
int for_stat()
{
int es=0,label1,label2,label3,label4;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"(")) return 5; //缺少左括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,";")) return 4; //缺少分号

label1
=labelp++;
fprintf(fout,
"LABEL%d:\n",label1); //设置label1标号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
label2
=labelp++;
fprintf(fout,
" BRF LABEL%d\n",label2);
label3
=labelp++;
fprintf(fout,
" BR LABEL%d\n",label3);
if (strcmp(token,";")) return 4; //缺少分号

label4
=labelp++;
fprintf(fout,
"LABEL%d:\n",label4); //设置label4标号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression();
if (es>0) return es;
fprintf(fout,
" BR LABEL%d\n",label1);
if (strcmp(token,")")) return 6; //缺少右括号

fprintf(fout,
"LABEL%d:\n",label3); //设置label3标号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=statement();
if (es>0) return es;
fprintf(fout,
" BR LABEL%d\n",label4);
fprintf(fout,
"LABEL%d:\n",label2); //设置label2标号
return es;
}

//<read_语句>::=read<变量>;
//<read_stat>::=read ID;
//<read_stat>::=read ID↑n LOOK↓n↑d @IN@STI↓d;
//动作解释:
//@LOOK↓n↑d:查符号表n,给出变量地址d; 没有,变量没定义
//@IN:输出IN
//@STI↓d:输出指令代码STI d
int read_stat()
{
int es=0,address;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,"ID")) return 3; //缺少标识符

es
=lookup(token1,&address);
if (es>0) return es;
fprintf(fout,
" IN \n");
fprintf(fout,
" STO %d\n",address);
fprintf(fout,
" POP\n");

fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,";")) return 4; //缺少分号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<write_语句>::=write <表达式>;
//<write_stat>::=write <expression>;
//<write_STR>::write <STR>;
//动作解释:
//@ OUT:输出 OUT
int write_stat()
{
int es=0;
fscanf(fin,
"%d %s ",&wrow,token);
printf(
"%s ",token);
if (strcmp(token,"STR")==0){ //输出字符串
fgets(token1,1024,fin);
printf(
"%s",token1);
fprintf(fout,
" OUTS %s",token1); //由于字符串不参与运算,单独考虑,定义OUTS为输出字符串指令
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
if (strcmp(token,";")) return 4; //缺少分号
//fprintf(fout," OUT\n");
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
fscanf(fin,
"%s",&token1);
printf(
"%s\n",token1);
es
=expression();
if (es>0) return es;
if (strcmp(token,";")) return 4; //缺少分号
fprintf(fout," OUT\n");
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}

//<表达式语句>::=<<表达式>;|;
//<expression_stat>::=<expression>;|;
int expression_stat()
{
int es=0;
if (strcmp(token,";")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
es
=expression();
if (es>0) return es;
if (strcmp(token,";")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
else{
return 4; //缺少分号
}
}

//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
//<expr>::=ID=<bool_expr>|<bool_expr>
//<expression>::=ID↑n@LOOK↓n↑d@ASSIGN=<bool_expr>@STO↓d |<bool_expr>
int expression()
{
int es=0,fileadd;
char token2[MAXLENGTH+2],token3[MAXLENGTH+2];
if (strcmp(token,"ID")==0){
fileadd
=ftell(fin); //记住当前文件位置
fscanf(fin,"%d %s %s\n",&wrow,token2,token3);
printf(
"%s %s\n",token2,token3);

if (strcmp(token2,"=")==0){ //'='
int address;
es
=lookup(token1,&address);
if (es>0) return es;
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=bool_expr();
if (es>0) return es;
fprintf(fout,
" STO %d\n",address);
fprintf(fout,
" POP\n");
}
else{ //"=="
fseek(fin,fileadd,0); //若非'='则文件指针回到'='前的标识符
es=bool_expr();
if (es>0) return es;
}
}
else{
es
=bool_expr();
}
return es;
}

//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
//<bool_expr>::=<additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
//<bool_expr>::=<additive_expr>
//|< additive_expr >><additive_expr>@GT
//|< additive_expr ><<additive_expr>@LES
//|< additive_expr >>=<additive_expr >@GE
//|< additive_expr ><=< additive_expr >@LE
//|< additive_expr >==< additive_expr >@EQ
//|< additive_expr >!=< additive_expr >@NOTEQ
int bool_expr()
{
int es=0;
es
=additive_expr();
if (es>0) return es;
if (strcmp(token,">")==0 || strcmp(token,">=")==0 || strcmp(token,"<")==0 ||
strcmp(token,
"<=")==0 || strcmp(token,"==")==0 || strcmp(token,"!=")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
//保存运算符
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=additive_expr();
if (es>0) return es;

if (strcmp(token2,">")==0) fprintf(fout," GT\n");
if (strcmp(token2,">=")==0) fprintf(fout," GE\n");
if (strcmp(token2,"<")==0) fprintf(fout," LES\n");
if (strcmp(token2,"<=")==0) fprintf(fout," LE\n");
if (strcmp(token2,"==")==0) fprintf(fout," EQ\n");
if (strcmp(token2,"!=")==0) fprintf(fout," NOTEQ\n");
}
return es;
}

//<算术表达式>::=<项>{(+|-)<项>}
//<additive_expr>::=<term>{(+|-)< term >}
//< additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr()
{
int es=0;
es
=term();
if (es>0) return es;
while (strcmp(token,"+")==0 || strcmp(token,"-")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=term();
if (es>0) return es;

if (strcmp(token2,"+")==0) fprintf(fout," ADD\n");
if (strcmp(token2,"-")==0) fprintf(fout," SUB\n");
}
return es;
}

//<项>::=<因子>{(*|/)<因子>}
//< term >::=<factor>{(*| /)< factor >}
//< term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)}
int term()
{
int es=0;
es
=factor();
if (es>0) return es;
while (strcmp(token,"*")==0 || strcmp(token,"/")==0 || strcmp(token,"%")==0){
char token2[MAXLENGTH+2];
strcpy(token2,token);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=factor();
if (es>0) return es;

if (strcmp(token2,"*")==0) fprintf(fout," MULT\n");
if (strcmp(token2,"/")==0) fprintf(fout," DIV\n");
if (strcmp(token2,"%")==0) fprintf(fout," MOD\n");
}
return es;
}

//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>
//< factor >::=(<additive_expr>)| ID|NUM
//< factor >::=(< expression >)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i
int factor()
{
int es=0;
if (strcmp(token,"(")==0){
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
es
=expression(); //表达式
if (es>0) return es;
if (strcmp(token,")")) return 6; //缺少右括号
fscanf(fin,"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
}
else{
if (strcmp(token,"ID")==0){
int address;
es
=lookup(token1,&address); //查符号表,获取地址
if (es>0) return es; //变量没声明
fprintf(fout," LOAD %d\n",address);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
printf(
"%s %s\n",token,token1);
return es;
}
else if (strcmp(token,"NUM")==0){
fprintf(fout,
" LOADI %s\n",token1);
fscanf(fin,
"%d %s %s\n",&wrow,token,token1);
return es;
}
else{
return 7; //缺少操作数
}
}
return es;
}
View Code

 

四、模拟机

特点:

(1)支持字符串(可带空白字符)输出

(2)消除LABEL:中:与带:字符串的冲突

Test语言编译器V0.8Test语言编译器V0.8
#include <iostream>
#include
<cstdio>
#include
<cctype>
#include
<cstdlib>
#include
<cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXFILENAME 100
#define MAXCODENUM 1000
#define MAXCODELENGTH 100
#define MAXDATANUM 1000
#define MAXLABELNUM 100
#define MAXSTACK 1000

namespace Testmachine{
FILE
*fin; //用于指向输入文件的指针
char Scanin[MAXFILENAME]; //用于接收输入的文件名
char code[MAXCODENUM][MAXCODELENGTH]; //代码存放数组
int data[MAXDATANUM]; //data[i]表示i地址的数值
int label[MAXLABELNUM]; //LABEL数组
int stack[MAXSTACK],stacktop; //操作栈
char lno[10];
int codecnt;
int i,j,es;
}
using namespace Testmachine;
int TESTmachine()
{
//printf("请输入目标文件名(包括路径):\n");
//system("C:\\Users\\Administrator\\Desktop\\test4.exe");
strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\out2.txt");

es
=0,i=0,j=0,stacktop=0;
memset(data,
-INF,sizeof(data));
if ((fin=fopen(Scanin,"r"))==NULL){
printf(
"\n打开%s错误!\n",code);
return 10;
}

codecnt
=0;
i
=fscanf(fin,"%s",&code[codecnt]);
while (!feof(fin)){ //读入
i=strlen(code[codecnt])-1;
strncpy(lno,code[codecnt],
5);
lno[
5]='\0';
if (strcmp(lno,"OUTS")==0){ //带空格字符串处理
codecnt++;
getc(fin);
//跳过空格
fgets(code[codecnt],1024,fin);
i
=strlen(code[codecnt])-1;
code[codecnt][i]
='\0';
}
else if (code[codecnt][i]==':'){ //LABEL,已消除":"冲突
i=i-5;
strncpy(lno,
&code[codecnt][5],i);
lno[i]
='\0';
label[atoi(lno)]
=codecnt; //用label数组记住每个标号的地址
code[codecnt][0]=':';
code[codecnt][
1]='\0';
strcat(code[codecnt],lno);
j
++;
}
codecnt
++;
i
=fscanf(fin,"%s",&code[codecnt]);
}
fclose(fin);

for (i=0;i<codecnt;i++){ //处理
int l=strlen(code[i]);
//printf("%d %s %d\n",i,code[i],l);
if ((l>1) && (code[i][1]=='A')){
strncpy(lno,
&code[i][5],l-5);
lno[i]
='\0';
itoa(label[atoi(lno)],code[i],
10);
}
}

i
=0;
while (i<codecnt) //运行
{
if (strcmp(code[i],"LOAD")==0){ //LOAD D将D中的内容加载到操作数栈
i++;
stack[stacktop]
=data[atoi(code[i])];
stacktop
++;
}
else if (strcmp(code[i],"LOADI")==0){ //LOADI a将常量a压入操作数栈
i++;
stack[stacktop]
=atoi(code[i]);
stacktop
++;
}
else if (strcmp(code[i],"STO")==0){ //STO D将操作数栈栈顶单元内容存入D,且栈顶单元内容保持不变
i++;
data[atoi(code[i])]
=stack[stacktop-1];
}
else if (strcmp(code[i],"STI")==0){ //STI D 将操作数栈栈顶单元内容存入D,且栈顶单元内容出栈
i++;
data[atoi(code[i])]
=stack[stacktop-1];
stacktop
--;
}
else if(strcmp(code[i],"POP")==0){ //POP出栈
stacktop--;
}

else if (strcmp(code[i],"ADD")==0){ //ADD将次栈顶单元与栈顶单元内容出栈并相加,和置于栈顶
stack[stacktop-2]=stack[stacktop-2]+stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"SUB")==0){ //SUB将次栈顶单元减去栈顶单元内容并出栈,差置于栈顶
stack[stacktop-2]=stack[stacktop-2]-stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"MULT")==0){ //MULT将次栈顶单元与栈顶单元内容出栈并相乘,积置于栈顶
stack[stacktop-2]=stack[stacktop-2]*stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"DIV")==0){ //DIV将次栈顶单元与栈顶单元内容出栈并相除,商置于栈顶
stack[stacktop-2]=stack[stacktop-2]/stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"MOD")==0){ //MOD将次栈顶单元模栈顶单元内容并出栈,余数置于栈顶
stack[stacktop-2]=stack[stacktop-2]%stack[stacktop-1];
stacktop
--;
}


else if (strcmp(code[i],"BR")==0){ //BR lab无条件转移到lab
i++;
i
=atoi(code[i]);
}
else if (strcmp(code[i],"BRF")==0){ //BRF lab检查栈顶单元逻辑值,若为假则转移到lab
i++;
if (stack[stacktop-1]==0) i=atoi(code[i]);
stacktop
--;
}
else if (strcmp(code[i],"EQ")==0){ //EQ将栈顶两单元做等于比较,并将结果真或假置于栈顶
stack[stacktop-2]=stack[stacktop-2]==stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"NOTEQ")==0){ //NOTEQ将栈顶两单元做不等于比较,并将结果真或假置于栈顶
stack[stacktop-2]=stack[stacktop-2]!=stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"GT")==0){ //GT次栈顶大于栈顶操作数,则栈顶置1,否则置0
stack[stacktop-2]=stack[stacktop-2]>stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"LES")==0){ //LES次栈顶小于栈顶操作数,则栈顶置1,否则置0
stack[stacktop-2]=stack[stacktop-2]<stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"GE")==0){ //GE次栈顶大于等于栈顶操作数,则栈顶置1,否则置0
stack[stacktop-2]=stack[stacktop-2]>=stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"LE")==0){ //LE 次栈顶小于等于栈顶操作数,则栈顶置1,否则置0
stack[stacktop-2]=stack[stacktop-2]<=stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"AND")==0){ //AND 将栈顶两单元做逻辑与运算,并将结果真或假置于栈顶
stack[stacktop-2]=stack[stacktop-2] && stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"OR")==0){ //OR将栈顶两单元做逻辑或运算,并将结果真或假置于栈顶
stack[stacktop-2]=stack[stacktop-2]||stack[stacktop-1];
stacktop
--;
}
else if (strcmp(code[i],"NOT")==0){ //NOT将栈顶的逻辑值取反
stack[stacktop-1]=!stack[stacktop-1];
}

else if (strcmp(code[i],"IN")==0){ //IN从标准输入设备(键盘)读入一个整型数据,并入栈
scanf("%d",&stack[stacktop]);
stacktop
++;
}
else if (strcmp(code[i],"OUT")==0){ //OUT将栈顶单元内容出栈,并输出到标准输出设备上(显示器)
printf("%d\n",stack[stacktop-1]);
stacktop
--;
}
else if (strcmp(code[i],"OUTS")==0){ //OUTS 字符串输出
i++;
printf(
"%s\n",code[i]);
}

else if (strcmp(code[i],"STOP")==0){ //STOP 停止执行
break;
}
i
++;
}
return es;
}
View Code

 

五、主程序

Test语言编译器V0.8Test语言编译器V0.8
#include <stdio.h>

extern int TESTscan();
extern int TESTparse();
extern int TESTmachine();

int main()
{
int es=0;
es
=TESTscan();
if (es>0){
printf(
"词法分析有错,编译停止!\n");
}
else{
printf(
"词法分析成功!\n");
es
=TESTparse();
if(es>0){
printf(
"语义分析有错,编译停止!\n");
}
else{
printf(
"语义分析成功!\n");
es
=TESTmachine();
if(es>0){
printf(
"启动模拟机失败\n");
}
}
}
}
View Code

 

另外用QT写了一个简单界面,如图所示:

Test语言编译器V0.8

Test语言编译器V0.8

 

后面又改了下,如图:

(额、V1.0改成了V0.8,不要在意这些细节)

Test语言编译器V0.8

Test语言编译器V0.8

Test语言编译器V0.8

Test语言编译器V0.8