Test语言编译器V0.8

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

一、词法分析

特点:

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

#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 + ]; // 存放识别单词
int frow, brow; // 符号起止行标记
int i, j, k, es; // 临时整型变量
char ch, ch1; // 临时字符变量
} using namespace Testscan; /*****************************
错误列表:
打开输入文件出错
打开输出文件出错
标识符过长
标识符命名不合法
******************************/ 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 ;
}
if ((fout = fopen(Scanout, "w")) == NULL) {
printf("创建词法分析输出文件出错!\n");
return ;
}
return ;
} char getNextChar() {
char ch = getc(fin);
if (ch == '\n') frow++;
return ch;
} int TESTscan() {
int es = Init();
if (es > ) return es; frow = brow = ;
ch = getNextChar();
while (ch != EOF) {
while (ch == ' ' || ch == '\n' || ch == '\t') {
ch = getNextChar();
} brow = frow;
if (ch == EOF) break; if (isalpha(ch)) { // 字母
j = ;
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 = ;
printf("ERROR(%d): 标识符\"%s\"超长\n", brow, token);
fprintf(fout, "%d\t%s\t%s\n", brow, "ERROR", token);
continue;
} k = ;
char str[MAXLENGTH + ];
for (i = ; 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 = ;
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) > ) { // 单分界符
token[] = ch;
token[] = '\0';
fprintf(fout, "%d\t%s\t%s\n", brow, token, token);
ch = getNextChar();
} else if (strchr(doubleword, ch) > ) { // 双分界符
token[] = ch;
ch = getNextChar();
if (ch == '=') {
token[] = ch;
token[] = '\0';
ch = getNextChar();
} else token[] = '\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[] = '/';
token[] = '\0';
fprintf(fout, "%d\t%s\t%s\n", brow, token, token);
}
} else if (ch == '\"') { // 字符串
j = ;
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[] = ch;
token[] = '\0';
if (ch < ) { //中文处理
ch = getNextChar();
token[] = ch;
token[] = '\0';
}
es = ;
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;
}

二、语法分析

特点:

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

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

(3)支持变量连续定义

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

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

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

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

#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 // 字符串最大长度 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 = ;
if ((fin = fopen(Scanin, "r")) == NULL) {
printf("\n打开%s错误!\n", Scanout);
es = ;
} if ((fout = fopen(Scanout, "w")) == NULL) {
printf("\n打开%s错误!\n", Scanout);
es = ;
} if (es == ) es = program();
printf("=====语法分析结果!======\n");
switch (es) {
case :
printf("语法分析成功!\n");
break;
case :
printf("打开文件失败!\n");
break;
case :
printf("ERROR(%d): \"%s\"前面缺少{\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少}\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少标识符\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少分号\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少(\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少)\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少操作数\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少主程序\n", wrow, token1);
break;
case :
printf("ERROR(%d): 主程序名错误!\n", wrow);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少while\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"已超出程序末尾\n", wrow, token1);
break;
case :
printf("ERROR(%d): else没有匹配的if\n", wrow);
}
fclose(fin);
fclose(fout);
return es;
} // <程序>::={<声明序列><语句序列>}
// program::={<declaration_list><statement_list>}
int program() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = declaration_list(); // 声明语句
if (es > ) return es; if (strcmp(token, "main")) return ; // main区
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "ID")) return ; // 程序名
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "{")) return ; // 判断是否'{'
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement_list(); // 语句序列
if (es > ) return es;
if (strcmp(token, "}")) return ; // 判断是否'}'
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "EOF")) return ; // 超出程序末尾
return es;
} // <声明序列>::=<声明序列><声明语句>|<声明语句>
// <declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list() {
int es = ;
while (strcmp(token, "int") == ) {
es = declaration_stat();
if (es > ) return es;
}
return es;
} // <声明语句>::=int<变量>;
// <declaration_stat>::=int ID;
int declaration_stat() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
while () { // 支持连续定义
if (strcmp(token, "ID")) return ; // 不是标识符
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, ",") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
} else break;
}
if (strcmp(token, ";")) return ; // 缺少分号
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 = ;
while (strcmp(token, "}")) {
es = statement();
if (es > ) return es;
if (strcmp(token, "EOF") == ) {
return ; // 缺少}
}
}
return es;
} // <语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
// <statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement() {
int es = ;
if ((strcmp(token, "if") == || strcmp(token, "else") == )) es = if_stat(); // <IF语句>
else if (strcmp(token, "while") == ) es = while_stat(); // <while语句>
else if (strcmp(token, "for") == ) es = for_stat(); // <for语句>
else if (strcmp(token, "do") == ) es = do_while_stat(); // do_while语句
else if (strcmp(token, "read") == ) es = read_stat(); // <read语句>
else if (strcmp(token, "write") == ) es = write_stat(); // <write语句>
else if (strcmp(token, "{") == ) es = compound_stat(); // <复合语句>
else if ((strcmp(token, "ID") == || strcmp(token, "NUM") == || strcmp(token, "(") == ) ||
strcmp(token, ";") == )
es = expression_stat(); // <表达式语句>
return es;
} // <IF语句>::=if(<表达式>)<语句>[else<语句>]
// <IF_stat>::=if(<expr>)<statement>[else<statement>]
int if_stat() {
if (strcmp(token, "else") == ) return ; // else未匹配if
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement(); // 语句
if (es > ) return es; if (strcmp(token, "else") == ) { // else部分处理
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement();
if (es > ) return es;
}
return es;
} // <复合语句>::={<语句序列>}
// <compound_stat>::={<statement_list>}
int compound_stat() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement_list(); // 语句序列
if (es > ) 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 = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "{")) return ; // 缺少左括号
es = statement(); //语句
if (es > ) return es;
printf("%s %s\n", token, token1);
if (strcmp(token, "while")) return ; // 缺少while fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1); es = expression(); // 表达式
if (es > ) return es; if (strcmp(token, ")")) return ; // 缺少右括号
if (es > ) 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 = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement();
if (es > ) return es;
return es;
} // <for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>
// <for_stat>::=for(<expr>,<expr>,<expr>)<statement>
// <for_stat>::=for (<expression>;
int for_stat() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ";")) return ; // 缺少分号 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ";")) return ; // 缺少分号 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement();
if (es > ) return es;
return es;
} // <read_语句>::=read<变量>;
// <read_stat>::=read ID;
int read_stat() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "ID")) return ; // 缺少标识符 fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, ";")) return ; // 缺少分号
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 = ;
fscanf(fin, "%d %s ", &wrow, token);
printf("%s ", token);
if (strcmp(token, "STR") == ) { // 输出字符串
fgets(token1, , fin);
printf("%s", token1);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, ";")) return ; // 缺少分号
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 > ) return es;
if (strcmp(token, ";")) return ; // 缺少分号
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 = ;
if (strcmp(token, ";") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
return es;
}
es = expression();
if (es > ) return es;
if (strcmp(token, ";") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
return es;
} else {
return ; // 缺少分号
}
} // <表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
// <expr>::=ID=<bool_expr>|<bool_expr>
int expression() {
int es = , fileadd;
char token2[MAXLENGTH + ], token3[MAXLENGTH + ];
if (strcmp(token, "ID") == ) {
fileadd = ftell(fin); // 记住当前文件位置
fscanf(fin, "%d %s %s\n", &wrow, token2, token3);
printf("%s %s\n", token2, token3); if (strcmp(token2, "=") == ) { //'='
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = bool_expr();
if (es > ) return es;
} else { // "=="
fseek(fin, fileadd, ); // 若非'='则文件指针回到'='前的标识符
es = bool_expr();
if (es > ) return es;
}
} else {
es = bool_expr();
}
return es;
} // <布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
// <bool_expr>::=<additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
int bool_expr() {
int es = ;
es = additive_expr();
if (es > ) return es;
if (strcmp(token, ">") == || strcmp(token, ">=") == || strcmp(token, "<") == ||
strcmp(token, "<=") == || strcmp(token, "==") == || strcmp(token, "!=") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token); // 保存运算符
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = additive_expr();
if (es > ) return es;
}
return es;
} // <算术表达式>::=<项>{(+|-)<项>}
// <additive_expr>::=<term>{(+|-)< term >}
// < additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr() {
int es = ;
es = term();
if (es > ) return es;
while (strcmp(token, "+") == || strcmp(token, "-") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = term();
if (es > ) return es;
}
return es;
} // <项>::=<因子>{(*|/)<因子>}
// < term >::=<factor>{(*| /)< factor >}
// < term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)}
int term() {
int es = ;
es = factor();
if (es > ) return es;
while (strcmp(token, "*") == || strcmp(token, "/") == || strcmp(token, "%") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = factor();
if (es > ) return es;
}
return es;
} // <因子>::=(<算术表达式>)|<标识符>|<无符号整数>
// < factor >::=(<additive_expr>)| ID|NUM
int factor() {
int es = ;
if (strcmp(token, "(") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression(); // 表达式
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
} else {
if (strcmp(token, "ID") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
return es;
} else if (strcmp(token, "NUM") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
return es;
} else {
return ; // 缺少操作数
}
}
return es;
}

三、语义分析

特点同上

#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 = , labelp = , datap = ; 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 = ;
if ((fin = fopen(Scanin, "r")) == NULL) {
printf("\n打开%s错误!\n", Scanout);
es = ;
} if ((fout = fopen(Scanout, "w")) == NULL) {
printf("\n打开%s错误!\n", Scanout);
es = ;
} if (es == ) es = program();
printf("=====语法分析结果!======\n");
switch (es) {
case :
printf("语义分析成功!\n");
break;
case :
printf("打开文件失败!\n");
break;
case :
printf("ERROR(%d): \"%s\"前面缺少{\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少}\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少标识符\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少分号\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少(\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少)\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少操作数\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少主程序\n", wrow, token1);
break;
case :
printf("ERROR(%d): 主程序名错误!\n", wrow);
break;
case :
printf("ERROR(%d): \"%s\"前面缺少while\n", wrow, token1);
break;
case :
printf("ERROR(%d): 符号表溢出\n", wrow);
break;
case :
printf("ERROR(%d): 变量\"%s\"重复定义\n", wrow, token1);
break;
case :
printf("ERROR(%d): 变量\"%s\"未声明\n", wrow, token1);
break;
case :
printf("ERROR(%d): \"%s\"已超出程序末尾\n", wrow, token1);
break;
case :
printf("ERROR(%d): else没有匹配的if\n", wrow);
}
fclose(fin);
fclose(fout);
return es;
} // 插入符号表
int name_def(char *name) {
if (vartablep >= MAXVARTABLEP) return ; // 符号表溢出
for (int i = vartablep - ; i >= ; i--) {
if (strcmp(vartable[i].name, name) == ) {
return ; // 变量重复定义
}
}
strcpy(vartable[vartablep].name, name);
vartable[vartablep++].address = datap++;
return ;
} // 查询符号表返回地址
int lookup(char *name, int *paddress) {
for (int i = ; i < vartablep; i++) {
if (strcmp(vartable[i].name, name) == ) {
*paddress = vartable[i].address;
return ;
}
}
return ; // 变量未声明
} // <程序>::={<声明序列><语句序列>}
// program::={<declaration_list><statement_list>}
int program() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = declaration_list(); // 声明语句
if (es > ) return es; printf(" 符号表\n"); // 符号表输出
printf(" 名字 地址\n");
for (int i = ; i < vartablep; i++)
printf("%10s%10d\n", vartable[i].name, vartable[i].address); if (strcmp(token, "main")) return ; // main区
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "ID")) return ; // 程序名
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "{")) return ; // 判断是否'{'
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement_list(); // 语句序列
if (es > ) return es;
if (strcmp(token, "}")) return ; // 判断是否'}'
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "EOF")) return ; // 超出程序末尾
fprintf(fout, " STOP\n"); // 产生停止指令
return es;
} // <声明序列>::=<声明序列><声明语句>|<声明语句>
// <declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list() {
int es = ;
while (strcmp(token, "int") == ) {
es = declaration_stat();
if (es > ) 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 = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
while () { // 支持连续定义
if (strcmp(token, "ID")) return ; // 不是标识符
es = name_def(token1); //插入到符号表
if (es > ) return es;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, ",") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
} else break;
}
if (strcmp(token, ";")) return ; // 缺少分号
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 = ;
while (strcmp(token, "}")) {
es = statement();
if (es > ) return es;
if (strcmp(token, "EOF") == ) {
return ; // 缺少}
}
}
return es;
} // <语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
// <statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement() {
int es = ;
if ((strcmp(token, "if") == || strcmp(token, "else") == )) es = if_stat(); // <IF语句>
else if (strcmp(token, "while") == ) es = while_stat(); // <while语句>
else if (strcmp(token, "for") == ) es = for_stat(); // <for语句>
else if (strcmp(token, "do") == ) es = do_while_stat(); // do_while语句
else if (strcmp(token, "read") == ) es = read_stat(); // <read语句>
else if (strcmp(token, "write") == ) es = write_stat(); // <write语句>
else if (strcmp(token, "{") == ) es = compound_stat(); // <复合语句>
else if ((strcmp(token, "ID") == || strcmp(token, "NUM") == || strcmp(token, "(") == ) ||
strcmp(token, ";") == )
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") == ) return ; // else未匹配if
int es = , label1, label2;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号
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 > ) return es; label2 = labelp++; // 用label2记住要转向的标号
fprintf(fout, " BR LABEL%d\n", label2);
fprintf(fout, "LABEL%d:\n", label1); // 设置label1记住的标号 if (strcmp(token, "else") == ) { // else部分处理
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement();
if (es > ) return es;
}
fprintf(fout, "LABEL%d:\n", label2); // 设置label2记住的标号
return es;
} // <复合语句>::={<语句序列>}
// <compound_stat>::={<statement_list>}
int compound_stat() {
int es = ;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = statement_list(); // 语句序列
if (es > ) 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 = , 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 ; // 缺少左括号
es = statement(); // 语句
if (es > ) return es;
printf("%s %s\n", token, token1);
if (strcmp(token, "while")) return ; //缺少while fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1); es = expression(); // 表达式
if (es > ) return es;
label2 = labelp++;
fprintf(fout, " BRF LABEL%d\n", label2);
fprintf(fout, " BR LABEL%d\n", label1); if (strcmp(token, ")")) return ; // 缺少右括号
if (es > ) 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 = , 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 ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号 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 > ) 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 = , label1, label2, label3, label4;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "(")) return ; // 缺少左括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression();
if (es > ) return es;
if (strcmp(token, ";")) return ; //缺少分号 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 > ) return es;
label2 = labelp++;
fprintf(fout, " BRF LABEL%d\n", label2);
label3 = labelp++;
fprintf(fout, " BR LABEL%d\n", label3);
if (strcmp(token, ";")) return ; // 缺少分号 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 > ) return es;
fprintf(fout, " BR LABEL%d\n", label1);
if (strcmp(token, ")")) return ; // 缺少右括号 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 > ) 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 = , address;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
if (strcmp(token, "ID")) return ; // 缺少标识符 es = lookup(token1, &address);
if (es > ) 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 ; // 缺少分号
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 = ;
fscanf(fin, "%d %s ", &wrow, token);
printf("%s ", token);
if (strcmp(token, "STR") == ) { // 输出字符串
fgets(token1, , 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 ; // 缺少分号
// 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 > ) return es;
if (strcmp(token, ";")) return ; // 缺少分号
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 = ;
if (strcmp(token, ";") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
return es;
}
es = expression();
if (es > ) return es;
if (strcmp(token, ";") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
return es;
} else {
return ; //缺少分号
}
} // <表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
// <expr>::=ID=<bool_expr>|<bool_expr>
// <expression>::=ID↑n@LOOK↓n↑d@ASSIGN=<bool_expr>@STO↓d |<bool_expr>
int expression() {
int es = , fileadd;
char token2[MAXLENGTH + ], token3[MAXLENGTH + ];
if (strcmp(token, "ID") == ) {
fileadd = ftell(fin); // 记住当前文件位置
fscanf(fin, "%d %s %s\n", &wrow, token2, token3);
printf("%s %s\n", token2, token3); if (strcmp(token2, "=") == ) { //'='
int address;
es = lookup(token1, &address);
if (es > ) return es;
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = bool_expr();
if (es > ) return es;
fprintf(fout, " STO %d\n", address);
fprintf(fout, " POP\n");
} else { //"=="
fseek(fin, fileadd, ); // 若非'='则文件指针回到'='前的标识符
es = bool_expr();
if (es > ) 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 = ;
es = additive_expr();
if (es > ) return es;
if (strcmp(token, ">") == || strcmp(token, ">=") == || strcmp(token, "<") == ||
strcmp(token, "<=") == || strcmp(token, "==") == || strcmp(token, "!=") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token); // 保存运算符
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = additive_expr();
if (es > ) return es; if (strcmp(token2, ">") == ) fprintf(fout, " GT\n");
if (strcmp(token2, ">=") == ) fprintf(fout, " GE\n");
if (strcmp(token2, "<") == ) fprintf(fout, " LES\n");
if (strcmp(token2, "<=") == ) fprintf(fout, " LE\n");
if (strcmp(token2, "==") == ) fprintf(fout, " EQ\n");
if (strcmp(token2, "!=") == ) fprintf(fout, " NOTEQ\n");
}
return es;
} // <算术表达式>::=<项>{(+|-)<项>}
// <additive_expr>::=<term>{(+|-)< term >}
// < additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr() {
int es = ;
es = term();
if (es > ) return es;
while (strcmp(token, "+") == || strcmp(token, "-") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = term();
if (es > ) return es; if (strcmp(token2, "+") == ) fprintf(fout, " ADD\n");
if (strcmp(token2, "-") == ) fprintf(fout, " SUB\n");
}
return es;
} // <项>::=<因子>{(*|/)<因子>}
// < term >::=<factor>{(*| /)< factor >}
// < term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)}
int term() {
int es = ;
es = factor();
if (es > ) return es;
while (strcmp(token, "*") == || strcmp(token, "/") == || strcmp(token, "%") == ) {
char token2[MAXLENGTH + ];
strcpy(token2, token);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = factor();
if (es > ) return es; if (strcmp(token2, "*") == ) fprintf(fout, " MULT\n");
if (strcmp(token2, "/") == ) fprintf(fout, " DIV\n");
if (strcmp(token2, "%") == ) 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 = ;
if (strcmp(token, "(") == ) {
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
es = expression(); // 表达式
if (es > ) return es;
if (strcmp(token, ")")) return ; // 缺少右括号
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
printf("%s %s\n", token, token1);
} else {
if (strcmp(token, "ID") == ) {
int address;
es = lookup(token1, &address); // 查符号表获取地址
if (es > ) 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") == ) {
fprintf(fout, " LOADI %s\n", token1);
fscanf(fin, "%d %s %s\n", &wrow, token, token1);
return es;
} else {
return ; // 缺少操作数
}
}
return es;
}

四、模拟机(解释器)

特点:

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

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

#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[];
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 = , i = , j = , stacktop = ;
memset(data, -INF, sizeof(data));
if ((fin = fopen(Scanin, "r")) == NULL) {
printf("\n打开%s错误!\n", code);
return ;
} codecnt = ;
i = fscanf(fin, "%s", &code[codecnt]);
while (!feof(fin)) { // 读入
i = strlen(code[codecnt]) - ;
strncpy(lno, code[codecnt], );
lno[] = '\0';
if (strcmp(lno, "OUTS") == ) { // 带空格字符串处理
codecnt++;
getc(fin); // 跳过空格
fgets(code[codecnt], , fin);
i = strlen(code[codecnt]) - ;
code[codecnt][i] = '\0';
} else if (code[codecnt][i] == ':') { // LABEL,已消除":"冲突
i = i - ;
strncpy(lno, &code[codecnt][], i);
lno[i] = '\0';
label[atoi(lno)] = codecnt; // 用label数组记住每个标号的地址
code[codecnt][] = ':';
code[codecnt][] = '\0';
strcat(code[codecnt], lno);
j++;
}
codecnt++;
i = fscanf(fin, "%s", &code[codecnt]);
}
fclose(fin); for (i = ; i < codecnt; i++) { // 处理
int l = strlen(code[i]);
// printf("%d %s %d\n",i,code[i],l);
if ((l > ) && (code[i][] == 'A')) {
strncpy(lno, &code[i][], l - );
lno[i] = '\0';
itoa(label[atoi(lno)], code[i], );
}
} i = ;
while (i < codecnt) { // 运行
if (strcmp(code[i], "LOAD") == ) { // LOAD D将D中的内容加载到操作数栈
i++;
stack[stacktop] = data[atoi(code[i])];
stacktop++;
} else if (strcmp(code[i], "LOADI") == ) { // LOADI a将常量a压入操作数栈
i++;
stack[stacktop] = atoi(code[i]);
stacktop++;
} else if (strcmp(code[i], "STO") == ) { // STO D将操作数栈栈顶单元内容存入D,且栈顶单元内容保持不变
i++;
data[atoi(code[i])] = stack[stacktop - ];
} else if (strcmp(code[i], "STI") == ) { // STI D 将操作数栈栈顶单元内容存入D,且栈顶单元内容出栈
i++;
data[atoi(code[i])] = stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "POP") == ) { // POP出栈
stacktop--;
} else if (strcmp(code[i], "ADD") == ) { // ADD将次栈顶单元与栈顶单元内容出栈并相加,和置于栈顶
stack[stacktop - ] = stack[stacktop - ] + stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "SUB") == ) { // SUB将次栈顶单元减去栈顶单元内容并出栈,差置于栈顶
stack[stacktop - ] = stack[stacktop - ] - stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "MULT") == ) { // MULT将次栈顶单元与栈顶单元内容出栈并相乘,积置于栈顶
stack[stacktop - ] = stack[stacktop - ] * stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "DIV") == ) { // DIV将次栈顶单元与栈顶单元内容出栈并相除,商置于栈顶
stack[stacktop - ] = stack[stacktop - ] / stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "MOD") == ) { // MOD将次栈顶单元模栈顶单元内容并出栈,余数置于栈顶
stack[stacktop - ] = stack[stacktop - ] % stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "BR") == ) { // BR lab无条件转移到lab
i++;
i = atoi(code[i]);
} else if (strcmp(code[i], "BRF") == ) { // BRF lab检查栈顶单元逻辑值,若为假则转移到lab
i++;
if (stack[stacktop - ] == ) i = atoi(code[i]);
stacktop--;
} else if (strcmp(code[i], "EQ") == ) { // EQ将栈顶两单元做等于比较,并将结果真或假置于栈顶
stack[stacktop - ] = stack[stacktop - ] == stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "NOTEQ") == ) { // NOTEQ将栈顶两单元做不等于比较,并将结果真或假置于栈顶
stack[stacktop - ] = stack[stacktop - ] != stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "GT") == ) { // GT次栈顶大于栈顶操作数,则栈顶置1,否则置0
stack[stacktop - ] = stack[stacktop - ] > stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "LES") == ) { // LES次栈顶小于栈顶操作数,则栈顶置1,否则置0
stack[stacktop - ] = stack[stacktop - ] < stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "GE") == ) { // GE次栈顶大于等于栈顶操作数,则栈顶置1,否则置0
stack[stacktop - ] = stack[stacktop - ] >= stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "LE") == ) { // LE 次栈顶小于等于栈顶操作数,则栈顶置1,否则置0
stack[stacktop - ] = stack[stacktop - ] <= stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "AND") == ) { // AND 将栈顶两单元做逻辑与运算,并将结果真或假置于栈顶
stack[stacktop - ] = stack[stacktop - ] && stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "OR") == ) { // OR将栈顶两单元做逻辑或运算,并将结果真或假置于栈顶
stack[stacktop - ] = stack[stacktop - ] || stack[stacktop - ];
stacktop--;
} else if (strcmp(code[i], "NOT") == ) { // NOT将栈顶的逻辑值取反
stack[stacktop - ] = !stack[stacktop - ];
} else if (strcmp(code[i], "IN") == ) { // IN从标准输入设备读入一个整型数据,并入栈
scanf("%d", &stack[stacktop]);
stacktop++;
} else if (strcmp(code[i], "OUT") == ) { // OUT将栈顶单元内容出栈,并输出到标准输出
printf("%d\n", stack[stacktop - ]);
stacktop--;
} else if (strcmp(code[i], "OUTS") == ) { // OUTS 字符串输出
i++;
printf("%s\n", code[i]);
} else if (strcmp(code[i], "STOP") == ) { // STOP 停止执行
break;
}
i++;
}
return es;
}

五、主程序

#include <stdio.h>

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

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

Test语言编译器V0.8

Test语言编译器V0.8

后面又改了下,如图:

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

Test语言编译器V0.8

Test语言编译器V0.8

Test语言编译器V0.8

Test语言编译器V0.8

上一篇:Python IDLE 清屏工具


下一篇:怎样使用万用表来测试板子上的TX和RX引脚