/****************************************************/
/* 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
没有合适的资源?快使用搜索试试~ 我知道了~
做编译原理作业和毕业设计的同学可以下载c-tiny编译器
共26个文件
h:9个
c:9个
exe:2个
5星 · 超过95%的资源 需积分: 9 48 下载量 140 浏览量
2010-04-09
11:17:19
上传
评论 3
收藏 54KB RAR 举报
温馨提示
同学们,我是在上编译原理课,老师布置的作业,自己改进了一个编译器。是用c语言实现的tiny编译器
资源推荐
资源详情
资源评论
收起资源包目录
源代码.rar (26个子文件)
源代码
GLOBALS.H 3KB
YACC
GLOBALS.H 3KB
TINY.Y 5KB
SAMPLE.TM 920B
SCAN.H 659B
TM.EXE 14KB
MAKEFILE 1KB
UTIL.C 5KB
TINY.EXE 40KB
SCAN.C 6KB
CODE.H 2KB
PARSE.H 484B
SYMTAB.H 959B
CGEN.C 7KB
UTIL.H 1KB
CGEN.H 679B
PARSE.C 5KB
CODE.C 3KB
LEX
TINY.L 2KB
SAMPLE.TNY 263B
ANALYZE.C 4KB
MAIN.C 2KB
ANALYZE.H 652B
TM.C 16KB
README.DOS 2KB
SYMTAB.C 3KB
共 26 条
- 1
资源评论
- wyzxw_12013-12-10很好的资源,正是我要的
- 静静静静静静静静静2014-03-15额 不是我想要的 怪我没插好 谢谢作者
- plaiyuanyuan2015-02-21学习一下,对以后有用
- dbjcai2013-05-20写的很好的小型编译器,对学习编译原理很有作用
myhometown1
- 粉丝: 0
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功