📄 1.cpp
字号:
#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 + -