一个简单的C语言编译器
---------------------------------
源代码:
//
//
#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 + "_").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;
c语言编译器ide代码编辑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;
ca
se '/':
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){
p();
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();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
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();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
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();
p();
sos.pop();
p();
sos.pop();
p();
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();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
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;
log<<"语法分析:S->i(G)S"<<endl;
}
if(s1->word=="while"){
l1=new Label;
l2=new Label;
m->code=l1->text+":\n"+s3->code+"\tpop ax\n\tcmp ax,1\n\tjne "+l2->text+"\n"+s5->code+"\tjmp "+l1->text+"\n"+l2->text+":\n";
delete l1;
delete l2;
log<<"语法分析:S->w(G)S"<<endl;
}
delete s1;
delete s2;
delete s3;
delete s4;
delete s5;
break;
case 5://OK
//S->i(G)SeS
ss.pop();
ss.pop();
ss.pop();
ss.pop();
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='S';
m->line=s1->line;
sos.push(m);
//动作
l1=new Label;
l2=new Label;
if(s1->word=="if"){
m->code=s
3->code+"\tpop ax\n\tcmp ax,1\n\tjnz "+l1->text+"\n"+s5->code+"\tjmp "+l2->text+"\n"+l1->text+":\n"+s7->code+l2->text+":\n";
log<<"语法分析:S->i(G)SeS"<<endl;
}
else
err(8,s6->line);
delete l1;
delete l2;
delete s1;
delete s2;
delete s3;
delete s4;
delete s5;
delete s6;
delete s7;
break;
case 6://ok
//S->w(G)S
log<<"语法分析:S->w(G)S"<<endl;
ss.pop();
ss.pop();
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='S';
m->line=s1->line;
sos.push(m);
//动作
delete s1;
delete s2;
delete s3;
delete s4;
delete s5;
break;
case 7://OK
//S->zL;
log<<"语法分析:S->zL;"<<endl;
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='S';
m->line=s1->line;
sos.push(m);
//动作
delete s1;
delete s2;
delete s3;
break;
case 8://OK
//S->@(E);
log<<"语法分析:S->@(E);"<<endl;
ss.pop();
ss.pop();
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='S';
m->line=s1->line;
sos.push(m);
//动作
if(s1->word=="out"&&needOutSuppose)
m->code=s3->code+"\tpop ax\n\tcall outint\n";
else
err(6,s1->line);
delete s1;
delete s2;
delete s3;
delete s4;
delete s5;
break;
case 9://OK
//W->WS
log<<"语法分析:W->WS"<<endl;
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='W';
m->line=s1->line;
sos.push(m);
//动作
m->code=s1->code+s2->code;
delete s1;
delete s2;
break;
case 10://OK
/
/W->S
log<<"语法分析:W->S"<<endl;
ss.pop();
p();
sos.pop();
m=new Symbol;
m->group='W';
m->line=s1->line;
sos.push(m);
//动作
m->code=s1->code;
delete s1;
break;
case 11://OK
//L->@
log<<"语法分析:L->@"<<endl;
ss.pop();
p();
sos.pop();
m=new Symbol;
m->group='L';
m->line=s1->line;
sos.push(m);
//动作
if(!lookup(s1->word))
symbolList.d(),s1->word);
else
err(11,s1->line);
delete s1;
break;
case 12://OK
//L->L,@
log<<"语法分析:L->L,@"<<endl;
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
s
os.pop();
p();
sos.pop();
m=new Symbol;
m->group='L';
m->line=s1->line;
sos.push(m);
if(!lookup(s3->word))
symbolList.d(),s3->word);
else
err(11,s3->line);
delete s1;
delete s2;
delete s3;
break;
case 13://OK
//G->G&M
log<<"语法分析:G->G&M"<<endl;
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='G';
m->line=s1->line;
sos.push(m);
//动作
if(s2->word=="&&")
m->code=s3->code+s1->code+"\tpop ax\n\tpop bx\n\tand ax,bx\n\tpush ax\n";
if(s2->word=="||")
m->code=s3->code+s1->code+"\tpop ax\n\tpop bx\n\tor ax,bx\n\tpush ax\n";
delete s1;
delete s2;
delete s3;
break;
case 14://OK
//G->M
log<<"语法分析:G->M"<<endl;
ss.pop();
p();
sos.pop();
m=new Symbol;
m->group='G';
m->line=s1->line;
sos.push(m);
//动作
m->code=s1->code;
delete s1;
break;
case 15:
//M->E>E
log<<"语法分析:M->E>E"<<endl;
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='M';
m->line=s1->line;
sos.push(m);
/
/动作
l1=new Label;
l2=new Label;
m->code=s3->code+s1->code+"\tpop ax\n\tpop bx\n\tcmp ax,bx\n";
if(s2->word==">")
m->code+="\tjg "+l1->text+"\n";
if(s2->word=="<")
m->code+="\tjl "+l1->text+"\n";
if(s2->word=="==")
m->code+="\tje "+l1->text+"\n";
if(s2->word=="!=")
m->code+="\tjne "+l1->text+"\n";
if(s2->word==">=")
m->code+="\tjge "+l1->text+"\n";
if(s2->word=="<=")
m->code+="\tjle "+l1->text+"\n";
m->code+="\tmov ax,0\n\tjmp "+l2->text+"\n"+l1->text+":\tmov ax,1\n"+l2->text+":\tpush ax\n";
delete l1;
delete l2;
delete s1;
delete s2;
delete s3;
break;
case 16://OK
//M->!M
log<<"语法分析:M->!M"<<endl;
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='M';
m->line=s1->line;
sos.push(m);
//动作
m->code="\tpop ax\n\txor ax,ax\n\tpush ax\n";
delete s1;
delete s2;
break;
case 17://OK
//M->(G)
log<<"语法分析:M->(G)"<<endl;
ss.pop();
ss.pop();
ss.pop();
p();
sos.pop();
p();
sos.pop();
p();
sos.pop();
m=new Symbol;
m->group='M';
m->line=s1->line;
sos.push(m);
//动作
m->code=s2->code;
delete s1;
delete s2;
delete s3;
break;
case 18://OK
//E->E+T
log<<"语法分析:E->E+T"<<endl;
ss.pop();
ss.pop();
ss.pop();
p()