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

📄 1.cpp

📁 用C写的简易C编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers


#include <windows.h>
#include <string>
#include <fstream>
#include <list>
#include <stack>
#include <ctype.h>
using namespace std;


class Symbol  
{
public:
 int line;
 string word;
 char group;
 Symbol();
 Symbol(const Symbol &b);
 virtual ~Symbol();
 operator =(const Symbol &b);
 string code;
};

class Label  
{
public:
 Label();
 virtual ~Label();
 string text;
private:
 int n;
 static int next();
 static int _label;
};

class Action
{
public:
 static int lookUp(char v,int s);
private:
 Action();
 ~Action();
 static int Table[54][19];
 static string vs;
};

class Goto
{
public:
 static int lookUp(char v,int s);
private:
 Goto();
 ~Goto();
 static int Table[54][9];
 static string vs;
};


class Compiler  
{
public:
 optimize();
 string code;
 char nextChar();
 preProcess();//预处理器
 parser();//语法分析器
 Symbol *lexer();//词法分析器
 void emitter();//生成器
 Compiler(string CmdLine);
 virtual ~Compiler();
 err(int no,int line);
 int hasError;//错误发生状态

private:
 int lookup(string m);
 char currentChar;
 string fileName;
 int line;//行数状态
 Compiler();
 int hasFile;//源文件打开状态
 int needOutSuppose;//输出支持状态
 ifstream in;//输入CRR文件
 ofstream log;//输出日志文件
 ofstream out;//输出ASM文件
 list<string> symbolList;//符号表
};


Compiler::Compiler(string CmdLine)
{
 line=1;
 hasError=0;
 needOutSuppose=0;
 hasFile=0;
 fileName=CmdLine;
 log.open((fileName + "_Log.txt").c_str(),ios::out);
 //char c; //测试nextChar()
 //do{c=nextChar();log<<c;}while(c!='#');log<<endl;
}

Compiler::Compiler()
{

}

Compiler::~Compiler()
{
 log.close();
}

Symbol *Compiler::lexer()
{
 char c;
 int s=1;
 Symbol *r;
 r=new Symbol();
 c=currentChar;
 while(s){
  switch(s){
  case 1:
   if(c=='\x0A')line++;
   else if(isspace(c))
    s=1;
   else if(isalpha(c)||c=='_'){
    s=2;
    r->word=c;
   }
   else if(isdigit(c)){
    s=3;
    r->word=c;
   }
   else{
    switch(c){
    case '+':
    case '-':
     s=0;
     r->word=c;
     r->group='+';
     r->line=line;
     break;
    case '*':
    case '%':
     s=0;
     r->word=c;
     r->group='*';
     r->line=line;
     break;
    case '&':
    case '|':
     r->word=c;
     s=4;
     break;
    case '>':
    case '<':
     r->word=c;
     s=5;
     break;
    case '!':
     r->word=c;
     s=6;
     break;
    case '=':
     r->word=c;
     s=7;
     break;
    case ',':
    case ';':
    case '{':
    case '}':
    case '(':
    case ')':
    case '$':
     s=0;
     r->word=c;
     r->group=c;
     r->line=line;
     break;
    case '/':
     r->word=c;
     s=8;
     break;
    case '#':
     s=11;
     break;
    default:
     s=1;
     err(1,line);
    }
   }
   c=nextChar();
   break;
  case 2:
   if(isalnum(c)||c=='_'){
    s=2;
    r->word+=c;
    c=nextChar();
   }
   else{
    s=0;
    r->line=line;
    if(r->word=="int")
     r->group='z';
    else if(r->word=="if")
     r->group='i';
    else if(r->word=="else")
     r->group='e';
    else if(r->word=="do")
     r->group='d';
    else if(r->word=="while")
     r->group='w';
    else if(r->word=="return")
     r->group='r';
    else
     r->group='@';
   }
   break;
  case 3:
   if(isdigit(c)){
    s=3;
    r->word+=c;
    c=nextChar();
   }
   else if(isalpha(c)||c=='_'){
    s=2;
    r->word+=c;
    err(2,line);
    c=nextChar();
   }
   else{
    s=0;
    r->line=line;
    r->group='n';
   }
   break;
  case 4:
   if((r->word.c_str())[0]==c){
    s=0;
    r->word+=c;
    r->group='&';
    r->line=line;
    c=nextChar();
   }
   else {
    s=1;
    err(3,line);
   }
   break;
  case 5: 
   if(c=='='){
    r->word+=c;
    c=nextChar();
   }
   s=0;
   r->line=line;
   r->group='>';
   break;
  case 6:
   if(c=='='){
    r->word+=c;
    r->group='>';
    c=nextChar();
   }
   else{
    r->group='!';
   }
   s=0;
   r->line=line;
   break;
  case 7:
   if(c=='='){
    r->word+=c;
    r->group='>';
    c=nextChar();
   }
   else{
    r->group='=';
   }
   s=0;
   r->line=line;
   break;
  case 8:
   if(c=='*'){
    s=9;
    r->word="";
    c=nextChar();
   }
   else{
    r->line=line;
    r->group='*';
    s=0;
   }
   break;
  case 9:
   if(c=='*')
    s=10;
   else
    s=9;
   c=nextChar();
   break;
  case 10:
   if(c=='/')
    s=1;
   else if(c=='*')
    s=10;
   else
    s=9;
   c=nextChar();
   break;
  case 11:
   if(c=='\n'){
    s=1;
    line++;
   }
   else
    s=11;
   c=nextChar();
   break;
  default:
   s=1;
   err(0,line);
   c=nextChar();
  }
 }
 currentChar=c;
 log<<"词法分析:"<<r->word<<endl;
 return r;
}

Compiler::parser()
{
 log<<endl;
 log<<"*******************************************"<<endl;
 log<<"语法分析开始..."<<endl;
 if(hasFile)
 in.open((fileName+".crr").c_str(),ios::in);
 currentChar=nextChar();//词法分析器初始化

// Symbol *s=NULL; //测试lexer()
// do{
//  if(s!=NULL)
//   delete s;
//  s=lexer();
//  log<<s->word;
//  log<<"    ";
//  log<<s->group;
//  log<<'\t';
//  log<<s->line;
//  log<<endl;
// }while(s->group!='#');
// delete s;

 int r,s=1,t=1;
 Symbol *ip,*iq,*it=NULL;
 Symbol *s1,*s2,*s3,*s4,*s5,*s6,*s7,*m;
 Label *l1,*l2;
 stack<int> ss;
 stack<Symbol *> sos;
 ss.push(s);
 ip=lexer();
 while(t){
  s=ss.top();
  t=Action::lookUp(ip->group,s);
  if(t>0){
   sos.push(ip);
   ss.push(t);
   if(it==NULL)
    ip=lexer();
   else
    ip=it;
   it=NULL;
  }
  else if(t<0)
  {
   switch(-t)
   {
   case 1://OK
    //D->@()S
    log<<"语法分析:D->@()S"<<endl;
    ss.pop();
    ss.pop();
    ss.pop();
    ss.pop();
    s4=sos.top();
    sos.pop();
    s3=sos.top();
    sos.pop();
    s2=sos.top();
    sos.pop();
    s1=sos.top();
    sos.pop();
    m=new Symbol;
    m->group='D';
    m->line=s1->line;
    sos.push(m);
    //动作
    if(s1->word!="main")
     err(5,s1->line);
    code=s4->code;
    delete s1;
    delete s2;
    delete s3;
    delete s4;
    break;
   case 2://OK
    //S->@=E;
    log<<"语法分析:S->@=E;"<<endl;
    ss.pop();
    ss.pop();
    ss.pop();
    ss.pop();
    s4=sos.top();
    sos.pop();
    s3=sos.top();
    sos.pop();
    s2=sos.top();
    sos.pop();
    s1=sos.top();
    sos.pop();
    m=new Symbol;
    m->group='S';
    m->line=s1->line;
    sos.push(m);
    //动作
    if(lookup(s1->word))
     m->code=s3->code+"\tpop ax\n\tmov "+s1->word+",ax\n";
    else
     err(10,s1->line);
    delete s1;
    delete s2;
    delete s3;
    delete s4;
    break;
   case 3://OK
    //S->{W}
    log<<"语法分析:S->{W}"<<endl;
    ss.pop();
    ss.pop();
    ss.pop();
    s3=sos.top();
    sos.pop();
    s2=sos.top();
    sos.pop();
    s1=sos.top();
    sos.pop();
    m=new Symbol;
    m->group='S';
    m->line=s1->line;
    sos.push(m);
    //动作
    m->code=s2->code;
    delete s1;
    delete s2;
    delete s3;
    break;
   case 4://OK
    //S->i(G)S
    ss.pop();
    ss.pop();
    ss.pop();
    ss.pop();
    ss.pop();
    s5=sos.top();
    sos.pop();
    s4=sos.top();
    sos.pop();
    s3=sos.top();
    sos.pop();
    s2=sos.top();
    sos.pop();
    s1=sos.top();
    sos.pop();
    m=new Symbol;
    m->group='S';
    m->line=s1->line;
    sos.push(m);
    //动作
    if(s1->word=="if"){
     l1=new Label;
     m->code=s3->code+"\tpop ax\n\tcmp ax,1\n\tjne "+l1->text+"\n"+s5->code+l1->text+":\n";
     delete l1;

⌨️ 快捷键说明

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