⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm.c

📁 一个简化的编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************//* 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("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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -