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 + 2]; // 存放识别单词 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 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; }
二、语法分析
特点:
(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 = 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; }
三、语义分析
特点同上
#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; }
四、模拟机(解释器)
特点:
(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[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; }
五、主程序
#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"); } } } }
另外用QT写了一个简单界面,如图所示:
后面又改了下,如图:
(额、V1.0改成了V0.8,不要在意这些细节)
趁着还有梦想、将AC进行到底~~~by 452181625