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

📄 tinyc.c

📁 一个非常小的C语言编译器!!! !!! !!! !!!!
💻 C
📖 第 1 页 / 共 2 页
字号:
//=========================================////  Tiny C Implementation   "tinyC.C"      ////=========================================////                          Tan Watanabe, UEC (tan@cs.uec.ac.jp)//              modified by Mitsugu G. Suzuki (gian@cs.uec.ac.jp)//    with some advice with Mr. Musaraki#include "sub.h"#include "arm.h"#include "mips.h"//-- Global variables --//  FILE    *inFile, *prtFile, *objFile;  SymbolP subCurrent;      // Current subprogram name  int     returnStmt;      // 1 if return stmt, 0 if other executable stmt.//-- Forward declarations --//  void     DeclStatement(SymbolP pTypeName);  void     VarDecl      (SymbolP pTypeName, SymbolP pSymName);  void     FuncDecl     (SymbolP pTypeName, SymbolP lSymName);   int      ExecStatement(SymbolP pSymp);  void     Block        ();  Reg_symP Variable     (SymbolP pSymp, Reg_symP pRegCand, Ac_lrT pType);  Reg_symP Factor       (Reg_symP pRegCand);   Reg_symP Term         (Reg_symP pRegCand);  Reg_symP Expression   (Reg_symP pRegCand);  void     Condition    (SymbolP pFalseLab);  int      IfStatement  ();  Reg_symP SubCall      (SymbolP pSymp);  void     WhileStatement();  void     Expect       (SymbolP pSymp);//-------- Main program of the Tiny C compiler --------//int main( int  pCount,    // Command parameter count.          char *pArg[])   // Command parameter (source program file name).{  SymbolP lSymbolP, lSymName,  lTypeName;  char    lObjFile[TKN_lim];        // Object file name.  int     i;    if (pCount > 1) {                 // Make object file name by replacing the    strcpy(&lObjFile[0], pArg[1]);  // extension name (.c) of source to ".s"    for (i = 0; (lObjFile[i] != '\0')&&(lObjFile[i] != '.'); i++);    lObjFile[i+1] = 's';    lObjFile[i+2] = '\0';    printf("Compile %s (object file %s)\n", pArg[1], lObjFile);  }  inFile  = fopen(pArg[1],   "r");   if (inFile == NULL) {    printf("Source file %s can not be opened.\n", pArg[1]);    return 1;  }  prtFile = stdout;  objFile = fopen(lObjFile,   "w");  sym_string.Initiation(); // String table class             StringT.  tkn_curr.Initiation();   // Token class                    Token.  sym_tbl.Initiation();    // Symbol table class             SymbolT.  reg_tbl.Initiation();    // Register information class     RegInf.  ac_head.Initiation();    // Abstract register machine code Rcode.  mrg_reg.Initiation();    // Machine register class         MachineReg.  sym_curr = NULL;  sym_tempVar = 0;   // Reset the number of generated temporal variables.  GenCode(acS, opProg, NULL, NULL, NULL, NULL, 0);          // Heading part.  while (sym_curr != sym_eof) {         // Loop until EOF.    sym_curr = sym_tbl.Get('?');        // Get the next symbol.    if ((sym_curr->Kind() == tknType))  // Should begin with type key word.      DeclStatement(sym_curr);          // Process the declaration.  }  GenCode(acN, opPend, NULL, NULL, NULL, NULL, 0);   // Trailing part.  sym_tbl.PrintAll();                   // Print the symbol table.  fclose(inFile);  fclose(objFile);  return 0;} //---- main end ----////--------------------//void DeclStatement(     // Process a declaration statement.  SymbolP pTypeName)    //   Type name.          // At entry, type name or type key word or Id is read.          // At exit, ';' or '{' is read.{  SymbolP lSymName, lTypeName, lTypeKey;  int     lSymNameProcessed;          // true: name part is already processed.  sym_curr = sym_tbl.Get('?');        // Get the next symbol.  if (sym_curr != sym_scolon) {    lSymName = sym_curr;              // Variable or function name.    sym_curr = sym_tbl.Get('?');      // Get the next symbol.  }  if (sym_curr == sym_lpar) {         // '('. Function decl.     FuncDecl(pTypeName, lSymName);  }else if ((sym_curr == sym_comma)||(sym_curr == sym_lbracket)||            (sym_curr == sym_scolon)) {      lSymNameProcessed = false;    GenCode(acC, opSect, NULL, NULL, NULL, NULL, acSectData);    if (sym_curr != sym_scolon)      do {         // VariableDecl::= TypeName VarSpec {"," VarSpec} ...";"        VarDecl(pTypeName, lSymName); // Variable declaration.        lSymNameProcessed = true;        if (sym_curr == sym_comma) {          lSymName = sym_tbl.Get('a');          sym_curr = sym_tbl.Get('?');          lSymNameProcessed = false;        }      } while ((sym_curr == sym_comma)||(sym_curr == sym_lbracket));    if (sym_curr == sym_scolon) {      if ((lSymNameProcessed == false)&&(lSymName != NULL)&&          (lSymName->Kind() == tknId))         VarDecl(pTypeName, lSymName);    }    Expect(sym_scolon);            // Semicolon is expected.  }     // else-end (variable decl)} //---- DeclStatement end ----////--------------------//  // Process a variable declaration.void VarDecl(         // VarSpec::= VarName {"[" ArraySize "]"}  SymbolP pTypeName,  //   Type name symbol pointer.  SymbolP pSymName)   //   Variable name.          // At entry, '[' or ',' or ';' next to variable name is read.          // At exit , ',' or ';' is read.{  SymbolP lVarName, lArraySizep;  VarInfP lVar;    lVarName = pSymName;  if (lVarName->IsIdentifier()) {  // Process Variable name part.    lVarName->KindSet(tknVar);    lVarName->VTypeSet(pTypeName);    lVarName->SizeSet(pTypeName->Size());    lVar = new VarInf;    lVarName->VarPSet(lVar);    lVar->ElemCountSet(1);  }  // end-if (tknId)  else    lVarName->Error(100, "Id expected \n");  if (sym_curr == sym_lbracket) {  // Array variable with '['.    lArraySizep = sym_tbl.Get('0');    lVar->ElemCountSet(lArraySizep->IValue());    lVarName->SizeSet((lVarName->Size())*(lVar->ElemCount()));    sym_curr = sym_tbl.Get(']');    sym_curr = sym_tbl.Get('?');    // Read comma or semicolon.  }  // end-if (array var)  GenCode(acS, opLabel, NULL, NULL, NULL, lVarName, 0);  GenCode(acC, opDword, NULL, NULL, NULL, NULL, lVarName->Size());} //---- VarDecl end ----////--------------------//void FuncDecl(           // Process a function declaration.  SymbolP pTypeName,     //   Type name pointer.  SymbolP pFuncName)     //   Function name pointer.          // Return the parent node under which opSubp is attached.          // At entry, '(' is read. At exit, '}' or ';' is read.          // FunctionDef::= TypeName FuncName "(" TypeName ParamSpec          //                {{"," TypeName ParamSpec} ... } ")"  [Block|";"]          // ParamSpec  ::= ParamName {"[" ArraySize "]"}{  SymbolP  lParamList, lParamType, lParamName, lDim;  FuncInfP lFunc;  VarInfP  lParamInf;  int      lParamC;  int      lArrSiz;    lFunc = new FuncInf;  subCurrent = pFuncName;  subCurrent->KindSet(tknFunc);  subCurrent->VTypeSet(pTypeName);  subCurrent->FuncPSet(lFunc);  GenCode(acS, opSubp, NULL, NULL, NULL, subCurrent, 0);  lParamC = 0;  lParamList = subCurrent;  sym_curr = sym_tbl.Get('?');           // Read parameter type or ')'.  while (sym_curr->Kind() == tknType) {  // If parameter type.    lParamType = sym_curr;               // Get paramter name.    sym_curr->Get('a');    if (sym_curr->Kind() == tknId) {     // sym_curr is a parameter name.      lParamC++;      lParamName = sym_curr;      if (lParamC == 1)           lParamList->FuncP()->ParamChainSet(lParamName);      else lParamList->VarP()->ParamChainSet(lParamName);      lParamName->KindSet(tknParam);      lParamName->VTypeSet(lParamType);      lParamName->SizeSet(lParamType->Size());      lParamInf = new VarInf;      lParamName->VarPSet(lParamInf);      lParamInf->IndexSet(lParamC);      lParamInf->ElemCountSet(1);        // Set default.      sym_curr = sym_tbl.Get('?');       // Read the next.      if (sym_curr == sym_lbracket) {    // Array parameter.        lDim = sym_tbl.Get('?');         // Array size or ']'	if (lDim->Kind() == tknIntC) {	  lArrSiz = lDim->IValue();	  if (lArrSiz == 1) lArrSiz = 2;	  sym_curr = sym_tbl.Get(']');	} else if (lDim == sym_rbracket) {	  lArrSiz = 0x7fffffff;	} else {	  lDim->Error(120, "IntConst or ] expected.");	}	lParamInf->ElemCountSet(lArrSiz);	lParamName->SizeSet((lParamName->Size())* lArrSiz);        sym_curr = sym_tbl.Get('?');     // Read comma or semicolon.      }  //---- end-if (array var)      GenCode(acS, opLabel, NULL, NULL, NULL, lParamName, 0);      GenCode(acC, opDparam, NULL, NULL, NULL, NULL, lParamName->Size());      lParamList = lParamName;    } //---- Param name end    if (sym_curr == sym_comma)      sym_curr = sym_tbl.Get('a');     // Read the next.  };         subCurrent->FuncP()->ParamCountSet(lParamC);  Expect(sym_rpar);                    // ')' is expected.  sym_curr = sym_tbl.Get('?');         // Read '{'.  if (sym_curr == sym_lbrace) {        // Function body is given.    reg_tbl.RegFreeAll();    GenCode(acS, opExport, NULL, NULL, NULL, subCurrent, 0);    GenCode(acC, opSect,   NULL, NULL, NULL, NULL, acSectText);    GenCode(acS, opProlog, NULL, NULL, NULL, subCurrent, 0);    returnStmt = 0;        // Reset return flag.    Block();               // Process the function body.    if (returnStmt == 0) { // If previous statement is not "return"      GenCode(acS,  opEpilog, NULL, NULL, NULL, subCurrent, 0);      GenCode(acRs, opReturn, NULL, NULL, NULL, subCurrent, 0);    }    GenCode(acS,  opEnd,    NULL, NULL, NULL, subCurrent, 0);    Expect(sym_rbrace);    // '}' is expected.  }} //---- FuncDecl end ----////--------------------//void Expect(            // Expect pSym as current or next input token.  SymbolP pSym)         //   Symbol pointer of the expected symbol.          // If unexpected symbol appears, skip symbols until pSym appears.{  if (sym_curr == pSym)    return;  sym_curr = sym_tbl.Get('?');  if (sym_curr != pSym) {    sym_curr->Error(110, " encountered. ");    fprintf(prtFile, " %s expected.\n", pSym->NameStr());    while ((sym_curr != pSym)&&(sym_curr != sym_eof))      sym_curr = sym_tbl.Get('?');  }} //---- Expect end ----////--------------------//  // Process a block.void Block()              // Block::= "{" Statement ... "}"      // At entry, '{' is read. At exit, '}' is read.{  Reg_symP lRegCond;  int      lNextRead;    sym_curr = sym_tbl.Get('?'); // First token of the first statement.  while ((sym_curr->Kind() != tknEof)&&(sym_curr != sym_rbrace)) {    lNextRead = ExecStatement(sym_curr);    if (lNextRead == 0)      sym_curr = sym_tbl.Get('?');  }  Expect(sym_rbrace);} //---- Block end ----////--------------------//int ExecStatement(    // Process an executable statement.  SymbolP pSymp)      //   First symbol of the statement.       // At entry, 1st symbol is read. 

⌨️ 快捷键说明

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