当前位置: 首页 > ai >正文

编译原理实验 之 TINY 解释测试目标代码

文章目录

  • 实验
    • 任务1
    • 任务2

  • 本次的实验是在前三次TINYC的基础上的一个测试,所以完成前三次的实验是基础

编译原理 之 实验一
编译原理实验 之 Tiny C语言编译程序实验 语法分析
编译原理实验 之 TINY 之 语义分析(第二次作业

  • 首先将新的文件复制到先前的目录下面

需要复制的文件

在这里插入图片描述

整体的实验目录

在这里插入图片描述

实验要求

本次实验任务:
1、联调,给出sample.tny程序运行结果截图
2、自行编写Tiny C语言源程序,上交源代码,有运行结果的截图。

实验

任务1

直接对原本的那个sample.tny进行测试

其实那个TM.c我还修改了一下,应该是不用修改的,如果修改的话,可以直接复制我下面的代码

/****************************************************/
/* File: tm.c                                       */
/* The TM ("Tiny Machine") computer                 */
/****************************************************/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif/******* const *******/
#define   IADDR_SIZE  1024 /* increase for large programs */
#define   DADDR_SIZE  1024 /* increase for large programs */
#define   NO_REGS 8
#define   PC_REG  7#define   LINESIZE  121
#define   WORDSIZE  20/******* type  *******/typedef enum {opclRR,     /* reg operands r,s,t */opclRM,     /* reg r, mem d+s */opclRA      /* reg r, int d+s */} OPCLASS;typedef enum {/* RR instructions */opHALT,    /* RR     halt, operands are ignored */opIN,      /* RR     read into reg(r); s and t are ignored */opOUT,     /* RR     write from reg(r), s and t are ignored */opADD,    /* RR     reg(r) = reg(s)+reg(t) */opSUB,    /* RR     reg(r) = reg(s)-reg(t) */opMUL,    /* RR     reg(r) = reg(s)*reg(t) */opDIV,    /* RR     reg(r) = reg(s)/reg(t) */opRRLim,   /* limit of RR opcodes *//* RM instructions */opLD,      /* RM     reg(r) = mem(d+reg(s)) */opST,      /* RM     mem(d+reg(s)) = reg(r) */opRMLim,   /* Limit of RM opcodes *//* RA instructions */opLDA,     /* RA     reg(r) = d+reg(s) */opLDC,     /* RA     reg(r) = d ; reg(s) is ignored */opJLT,     /* RA     if reg(r)<0 then reg(7) = d+reg(s) */opJLE,     /* RA     if reg(r)<=0 then reg(7) = d+reg(s) */opJGT,     /* RA     if reg(r)>0 then reg(7) = d+reg(s) */opJGE,     /* RA     if reg(r)>=0 then reg(7) = d+reg(s) */opJEQ,     /* RA     if reg(r)==0 then reg(7) = d+reg(s) */opJNE,     /* RA     if reg(r)!=0 then reg(7) = d+reg(s) */opRALim    /* Limit of RA opcodes */} OPCODE;typedef enum {srOKAY,srHALT,srIMEM_ERR,srDMEM_ERR,srZERODIVIDE} STEPRESULT;typedef struct {int iop  ;int iarg1  ;int iarg2  ;int iarg3  ;} INSTRUCTION;/******** vars ********/
int iloc = 0 ;
int dloc = 0 ;
int traceflag = FALSE;
int icountflag = FALSE;INSTRUCTION iMem [IADDR_SIZE];
int dMem [DADDR_SIZE];
int reg [NO_REGS];char * opCodeTab[]= {"HALT","IN","OUT","ADD","SUB","MUL","DIV","????",/* RR opcodes */"LD","ST","????", /* RM opcodes */"LDA","LDC","JLT","JLE","JGT","JGE","JEQ","JNE","????"/* RA opcodes */};char * stepResultTab[]= {"OK","Halted","Instruction Memory Fault","Data Memory Fault","Division by 0"};char pgmName[20];
FILE *pgm  ;char in_Line[LINESIZE] ;
int lineLen ;
int inCol  ;
int num  ;
char word[WORDSIZE] ;
char ch  ;
int done  ;/********************************************/
int opClass( int c )
{ if      ( c <= opRRLim) return ( opclRR );else if ( c <= opRMLim) return ( opclRM );else                    return ( opclRA );
} /* opClass *//********************************************/
void writeInstruction ( int loc )
{ printf( "%5d: ", loc) ;if ( (loc >= 0) && (loc < IADDR_SIZE) ){ printf("%6s%3d,", opCodeTab[iMem[loc].iop], iMem[loc].iarg1);switch ( opClass(iMem[loc].iop) ){ case opclRR: printf("%1d,%1d", iMem[loc].iarg2, iMem[loc].iarg3);break;case opclRM:case opclRA: printf("%3d(%1d)", iMem[loc].iarg2, iMem[loc].iarg3);break;}printf ("\n") ;}
} /* writeInstruction *//********************************************/
void getCh (void)
{ if (++inCol < lineLen)ch = in_Line[inCol] ;else ch = ' ' ;
} /* getCh *//********************************************/
int nonBlank (void)
{ while ((inCol < lineLen)&& (in_Line[inCol] == ' ') )inCol++ ;if (inCol < lineLen){ ch = in_Line[inCol] ;return TRUE ; }else{ ch = ' ' ;return FALSE ; }
} /* nonBlank *//********************************************/
int getNum (void)
{ int sign;int term;int temp = FALSE;num = 0 ;do{ sign = 1;while ( nonBlank() && ((ch == '+') || (ch == '-')) ){ temp = FALSE ;if (ch == '-')  sign = - sign ;getCh();}term = 0 ;nonBlank();while (isdigit(ch)){ temp = TRUE ;term = term * 10 + ( ch - '0' ) ;getCh();}num = num + (term * sign) ;} while ( (nonBlank()) && ((ch == '+') || (ch == '-')) ) ;return temp;
} /* getNum *//********************************************/
int getWord (void)
{ int temp = FALSE;int length = 0;if (nonBlank ()){ while (isalnum(ch)){ if (length < WORDSIZE-1) word [length++] =  ch ;getCh() ;}word[length] = '\0';temp = (length != 0);}return temp;
} /* getWord *//********************************************/
int skipCh ( char c  )
{ int temp = FALSE;if ( nonBlank() && (ch == c) ){ getCh();temp = TRUE;}return temp;
} /* skipCh *//********************************************/
int atEOL(void)
{ return ( ! nonBlank ());
} /* atEOL *//********************************************/
int error( char * msg, int lineNo, int instNo)
{ printf("Line %d",lineNo);if (instNo >= 0) printf(" (Instruction %d)",instNo);printf("   %s\n",msg);return FALSE;
} /* error *//********************************************/
int readInstructions (void)
{ OPCODE op;int arg1, arg2, arg3;int loc, regNo, lineNo;for (regNo = 0 ; regNo < NO_REGS ; regNo++)reg[regNo] = 0 ;dMem[0] = DADDR_SIZE - 1 ;for (loc = 1 ; loc < DADDR_SIZE ; loc++)dMem[loc] = 0 ;for (loc = 0 ; loc < IADDR_SIZE ; loc++){ iMem[loc].iop = opHALT ;iMem[loc].iarg1 = 0 ;iMem[loc].iarg2 = 0 ;iMem[loc].iarg3 = 0 ;}lineNo = 0 ;while (! feof(pgm)){ fgets( in_Line, LINESIZE-2, pgm  ) ;inCol = 0 ; lineNo++;lineLen = strlen(in_Line)-1 ;if (in_Line[lineLen]=='\n') in_Line[lineLen] = '\0' ;else in_Line[++lineLen] = '\0';if ( (nonBlank()) && (in_Line[inCol] != '*') ){ if (! getNum())return error("Bad location", lineNo,-1);loc = num;if (loc > IADDR_SIZE)return error("Location too large",lineNo,loc);if (! skipCh(':'))return error("Missing colon", lineNo,loc);if (! getWord ())return error("Missing opcode", lineNo,loc);int opInt = static_cast<int>(opHALT);while ((opInt < opRALim) && (strncmp(opCodeTab[opInt], word, 4) != 0))opInt++;op = static_cast<OPCODE>(opInt);switch ( opClass(op) ){ case opclRR :/***********************************/if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )return error("Bad first register", lineNo,loc);arg1 = num;if ( ! skipCh(','))return error("Missing comma", lineNo, loc);if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )return error("Bad second register", lineNo, loc);arg2 = num;if ( ! skipCh(',')) return error("Missing comma", lineNo,loc);if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )return error("Bad third register", lineNo,loc);arg3 = num;break;case opclRM :case opclRA :/***********************************/if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )return error("Bad first register", lineNo,loc);arg1 = num;if ( ! skipCh(','))return error("Missing comma", lineNo,loc);if (! getNum ())return error("Bad displacement", lineNo,loc);arg2 = num;if ( ! skipCh('(') && ! skipCh(',') )return error("Missing LParen", lineNo,loc);if ( (! getNum ()) || (num < 0) || (num >= NO_REGS))return error("Bad second register", lineNo,loc);arg3 = num;break;}iMem[loc].iop = op;iMem[loc].iarg1 = arg1;iMem[loc].iarg2 = arg2;iMem[loc].iarg3 = arg3;}}return TRUE;
} /* readInstructions *//********************************************/
STEPRESULT stepTM (void)
{ INSTRUCTION currentinstruction  ;int pc  ;int r,s,t,m  ;int ok ;pc = reg[PC_REG] ;if ( (pc < 0) || (pc > IADDR_SIZE)  )return srIMEM_ERR ;reg[PC_REG] = pc + 1 ;currentinstruction = iMem[ pc ] ;switch (opClass(currentinstruction.iop) ){ case opclRR :/***********************************/r = currentinstruction.iarg1 ;s = currentinstruction.iarg2 ;t = currentinstruction.iarg3 ;break;case opclRM :/***********************************/r = currentinstruction.iarg1 ;s = currentinstruction.iarg3 ;m = currentinstruction.iarg2 + reg[s] ;if ( (m < 0) || (m > DADDR_SIZE))return srDMEM_ERR ;break;case opclRA :/***********************************/r = currentinstruction.iarg1 ;s = currentinstruction.iarg3 ;m = currentinstruction.iarg2 + reg[s] ;break;} /* case */switch ( currentinstruction.iop){ /* RR instructions */case opHALT :/***********************************/printf("HALT: %1d,%1d,%1d\n",r,s,t);return srHALT ;/* break; */case opIN :/***********************************/do{ printf("Enter value for IN instruction: ") ;fflush (stdin);fflush (stdout);gets(in_Line);lineLen = strlen(in_Line) ;inCol = 0;ok = getNum();if ( ! ok ) printf ("Illegal value\n");else reg[r] = num;}while (! ok);break;case opOUT :  printf ("OUT instruction prints: %d\n", reg[r] ) ;break;case opADD :  reg[r] = reg[s] + reg[t] ;  break;case opSUB :  reg[r] = reg[s] - reg[t] ;  break;case opMUL :  reg[r] = reg[s] * reg[t] ;  break;case opDIV :/***********************************/if ( reg[t] != 0 ) reg[r] = reg[s] / reg[t];else return srZERODIVIDE ;break;/*************** RM instructions ********************/case opLD :    reg[r] = dMem[m] ;  break;case opST :    dMem[m] = reg[r] ;  break;/*************** RA instructions ********************/case opLDA :    reg[r] = m ; break;case opLDC :    reg[r] = currentinstruction.iarg2 ;   break;case opJLT :    if ( reg[r] <  0 ) reg[PC_REG] = m ; break;case opJLE :    if ( reg[r] <=  0 ) reg[PC_REG] = m ; break;case opJGT :    if ( reg[r] >  0 ) reg[PC_REG] = m ; break;case opJGE :    if ( reg[r] >=  0 ) reg[PC_REG] = m ; break;case opJEQ :    if ( reg[r] == 0 ) reg[PC_REG] = m ; break;case opJNE :    if ( reg[r] != 0 ) reg[PC_REG] = m ; break;/* end of legal instructions */} /* case */return srOKAY ;
} /* stepTM *//********************************************/
int doCommand (void)
{ char cmd;int stepcnt=0, i;int printcnt;int stepResult;int regNo, loc;do{ printf ("Enter command: ");fflush (stdin);fflush (stdout);gets(in_Line);lineLen = strlen(in_Line);inCol = 0;}while (! getWord ());cmd = word[0] ;switch ( cmd ){ case 't' :/***********************************/traceflag = ! traceflag ;printf("Tracing now ");if ( traceflag ) printf("on.\n"); else printf("off.\n");break;case 'h' :/***********************************/printf("Commands are:\n");printf("   s(tep <n>      "\"Execute n (default 1) TM instructions\n");printf("   g(o            "\"Execute TM instructions until HALT\n");printf("   r(egs          "\"Print the contents of the registers\n");printf("   i(Mem <b <n>>  "\"Print n iMem locations starting at b\n");printf("   d(Mem <b <n>>  "\"Print n dMem locations starting at b\n");printf("   t(race         "\"Toggle instruction trace\n");printf("   p(rint         "\"Toggle print of total instructions executed"\" ('go' only)\n");printf("   c(lear         "\"Reset simulator for new execution of program\n");printf("   h(elp          "\"Cause this list of commands to be printed\n");printf("   q(uit          "\"Terminate the simulation\n");break;case 'p' :/***********************************/icountflag = ! icountflag ;printf("Printing instruction count now ");if ( icountflag ) printf("on.\n"); else printf("off.\n");break;case 's' :/***********************************/if ( atEOL ())  stepcnt = 1;else if ( getNum ())  stepcnt = abs(num);else   printf("Step count?\n");break;case 'g' :   stepcnt = 1 ;     break;case 'r' :/***********************************/for (i = 0; i < NO_REGS; i++){ printf("%1d: %4d    ", i,reg[i]);if ( (i % 4) == 3 ) printf ("\n");}break;case 'i' :/***********************************/printcnt = 1 ;if ( getNum ()){ iloc = num ;if ( getNum ()) printcnt = num ;}if ( ! atEOL ())printf ("Instruction locations?\n");else{ while ((iloc >= 0) && (iloc < IADDR_SIZE)&& (printcnt > 0) ){ writeInstruction(iloc);iloc++ ;printcnt-- ;}}break;case 'd' :/***********************************/printcnt = 1 ;if ( getNum  ()){ dloc = num ;if ( getNum ()) printcnt = num ;}if ( ! atEOL ())printf("Data locations?\n");else{ while ((dloc >= 0) && (dloc < DADDR_SIZE)&& (printcnt > 0)){ printf("%5d: %5d\n",dloc,dMem[dloc]);dloc++;printcnt--;}}break;case 'c' :/***********************************/iloc = 0;dloc = 0;stepcnt = 0;for (regNo = 0;  regNo < NO_REGS ; regNo++)reg[regNo] = 0 ;dMem[0] = DADDR_SIZE - 1 ;for (loc = 1 ; loc < DADDR_SIZE ; loc++)dMem[loc] = 0 ;break;case 'q' : return FALSE;  /* break; */default : printf("Command %c unknown.\n", cmd); break;}  /* case */stepResult = srOKAY;if ( stepcnt > 0 ){ if ( cmd == 'g' ){ stepcnt = 0;while (stepResult == srOKAY){ iloc = reg[PC_REG] ;if ( traceflag ) writeInstruction( iloc ) ;stepResult = stepTM ();stepcnt++;}if ( icountflag )printf("Number of instructions executed = %d\n",stepcnt);}else{ while ((stepcnt > 0) && (stepResult == srOKAY)){ iloc = reg[PC_REG] ;if ( traceflag ) writeInstruction( iloc ) ;stepResult = stepTM ();stepcnt-- ;}}printf( "%s\n",stepResultTab[stepResult] );}return TRUE;
} /* doCommand *//********************************************/
/* E X E C U T I O N   B E G I N S   H E R E */
/********************************************/main( int argc, char * argv[] )
{ if (argc != 2){ printf("usage: %s <filename>\n",argv[0]);exit(1);}strcpy(pgmName,argv[1]) ;if (strchr (pgmName, '.') == NULL)strcat(pgmName,".tm");pgm = fopen(pgmName,"r");if (pgm == NULL){ printf("file '%s' not found\n",pgmName);exit(1);}/* read the program */if ( ! readInstructions ())exit(1) ;/* switch input file to terminal *//* reset( input ); *//* read-eval-print */printf("TM  simulation (enter h for help)...\n");dodone = ! doCommand ();while (! done );printf("Simulation done.\n");return 0;
}
  • 如果修改了这个TM.c,那就需要编译一下
gcc TM.C -o TM
  • OK,接下来就是正式的测试

  • 首先需要修改这个main.c程序,下面的main.c已经是修改好了的,可以直接复制来用

/****************************************************/
/* File: main.c                                     */
/* Main program for TINY compiler                   */
/****************************************************/#include "globals.h"/* set NO_PARSE to FALSE to enable the parser */
#define NO_PARSE FALSE
/* set NO_ANALYZE to FALSE to enable semantic analysis */
#define NO_ANALYZE FALSE
/* set NO_CODE to TRUE to disable code generation */
#define NO_CODE FALSE#include "util.h"
#if NO_PARSE
#include "scan.h"
#else
#include "parse.h"
#if !NO_ANALYZE
#include "analyze.h"
#if !NO_CODE
#include "cgen.h"
#endif
#endif
#endif/* allocate global variables */
int lineno = 0;
FILE * source;
FILE * listing;
FILE * code;/* allocate and set tracing flags */
int EchoSource = TRUE;
int TraceScan = FALSE;     // 禁用词法分析输出
int TraceParse = TRUE;     // 启用语法分析输出
int TraceAnalyze = TRUE;   // 启用语义分析输出
int TraceCode = FALSE;
int Error = FALSE;int main(int argc, char * argv[])
{ TreeNode * syntaxTree;char pgm[120]; /* source code file name */if (argc != 2){ fprintf(stderr,"usage: %s <filename>\n",argv[0]);exit(1);}strcpy(pgm,argv[1]) ;if (strchr (pgm, '.') == NULL)strcat(pgm,".tny");source = fopen(pgm,"r");if (source==NULL){ fprintf(stderr,"File %s not found\n",pgm);exit(1);}listing = stdout; /* send listing to screen */fprintf(listing,"\nTINY COMPILATION: %s\n",pgm);
#if NO_PARSEwhile (getToken()!=ENDFILE);           /* ʷʷ */
#elsesyntaxTree = parse();                  /* ﷨ */if (TraceParse) {fprintf(listing,"\nSyntax tree:\n");printTree(syntaxTree);}#if !NO_ANALYZE                          /* ֣ע͵ */if (! Error){ if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n");buildSymtab(syntaxTree);if (TraceAnalyze) fprintf(listing,"\nChecking Types...\n");typeCheck(syntaxTree);if (TraceAnalyze) fprintf(listing,"\nType Checking Finished\n");}
#if !NO_CODEif (! Error){ char * codefile;int fnlen = strcspn(pgm,".");codefile = (char *) calloc(fnlen+4, sizeof(char));strncpy(codefile,pgm,fnlen);strcat(codefile,".tm");code = fopen(codefile,"w");if (code == NULL){ printf("Unable to open %s\n",codefile);exit(1);}codeGen(syntaxTree, codefile);fclose(code);}
#endif
#endif
#endiffclose(source);return 0;
}
  • 编译程序,其余的程序和上次一样
   gcc main.c util.c scan.c parse.c analyze.c symtab.c cgen.c code.c -o tiny
  • 使用TINY编译器编译sample.tny,会生成这个sample.tm文件
./tiny sample.tny
  • 运行TM虚拟机,并加载sample.tm文件
./TM sample.tm

在这里插入图片描述

  • 然后就输入g

在这里插入图片描述

  • 注意这是一个测试阶乘的程序,所以,你输入一个数字,就可以输出结果

在这里插入图片描述

  • 如果想要退出这个虚拟机,按CTRL+C即可

任务2

2、自行编写Tiny C语言源程序,上交源代码,有运行结果的截图。

Attention!

  • 发现ai写的会报错,会一直报错!
  • 所以十分建议在原本的SAMPLE.TNY的基础上,自己修改!

之前的SAMPLE.TNY是计算阶乘的,你只需要让ai修改一下,换一个功能,然后按照任务1的流程进行测试即可

在这里插入图片描述

http://www.xdnf.cn/news/13259.html

相关文章:

  • 【多智能体】受木偶戏启发实现多智能体协作编排
  • 研发效能利器之驭码CodeRider
  • JAVA语言的学习(Day_1)
  • 2025盘古石杯决赛【计算机取证】
  • 【docker n8n】本地台式机A部署后,其他电脑B、C如何访问n8n?
  • 第二十二章 USB 全速设备接口(USB)
  • P4 QT项目----串口助手(4.2)
  • 力扣HOT100之堆:215. 数组中的第K个最大元素
  • crackme008
  • 7zip超详细安装教程(含最新版本)压缩软件使用全解析
  • 【LangChain】1 模型,提示和输出解释器
  • STM32外部中断(寄存器和hal库实现)
  • 机房断电后 etcd 启动失败的排查与快速恢复实录
  • YOLOv11 | 注意力机制篇 | EMAttention与C2PSA机制的协同优化
  • 从0到1:HBase安装与操作指南
  • 3.vue3核心语法
  • 中马泰语言电商系统:打开东南亚电商市场的多语言钥匙
  • 【第二十三章 IAP】
  • Vim 替换命令完整学习笔记
  • 一次消谐器:高效抑制铁磁谐振
  • 对DOM操作 与 jQuery的简单理解(通俗
  • DeepSeek生成流程图
  • 6.10 Mysql 事务 锁 面试题
  • 【Dv3Admin】系统视图角色管理API文件解析
  • 2025蓝奏云软件库合集分享链接汇总:极刻云搜 - 一站式获取海量资源
  • Linux下V2Ray安装配置指南
  • axios访问后台时,返回404
  • chrome插件中如何使用midscene.js
  • Leetcode 3577. Count the Number of Computer Unlocking Permutations
  • LeetCode 240 搜索二维矩阵 II