/****************************************************/
/* File: tm.c */
/* The TM ("Tiny Machine") computer */
/* Compiler Construction: Principles and Practice */
/* Kenneth C. Louden */
/****************************************************/
#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);
op = opHALT ;
while ((op < opRALim)
&& (strncmp(opCodeTab[op], word, 4) != 0) )
op++ ;
if (strncmp(opCodeTab[op], word, 4) != 0)
return error("Illegal opcode", lineNo,loc);
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("B
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
TINY+语法分析.rar (23个子文件)
test2.tny 138B
GLOBALS.H 3KB
test1.tny 108B
SCAN.H 660B
TM.EXE 168KB
test2.TM 3KB
UTIL.C 7KB
SCAN.C 7KB
CODE.H 2KB
PARSE.H 484B
SYMTAB.H 1007B
CGEN.C 9KB
UTIL.H 1KB
CGEN.H 679B
PARSE.C 9KB
CODE.C 3KB
ANALYZE.C 6KB
MAIN.C 2KB
TINY.exe 180KB
ANALYZE.H 684B
TM.C 16KB
test1.TM 3KB
SYMTAB.C 4KB
共 23 条
- 1
资源评论
- stranchong2013-03-01不错 比较完全
- sivanwu2012-12-06这才是真正的完全版
- u0105572602013-07-01还不错哦,比较完全
- jironychen2012-12-19不错,很完全
- fsfyl13142013-01-23真正的完全版
taolrlin
- 粉丝: 1
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 台达DOP系列触摸屏与DVP系列PLC通信电缆连接手册-20160122.pdf
- 计算机二级考试心得体会
- 织梦同步WAP插件(V1.4)
- linux之centos7打包与压缩命令详解
- (资源包名是松下不必介意实际是台达)台达PLC例程源码板式家具封边机
- (资源包名是松下不必介意实际是台达)台达PLC例程源码PLS交替输出(单按钮启停)
- (资源包名是松下不必介意实际是台达)台达PLC例程源码PLF指令(车库红绿灯控制)
- 织梦DedeCMS文章归档插件UTF-8和GBK版本
- (资源包名是松下不必介意实际是台达)台达PLC例程源码PLC与6台VFD-B的通讯
- doublescreen,MAXhub会议系统软件
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功