📄 complier_c0.cpp.bak
字号:
//**********************************************************************//
// 项目名称:编译课程设计 //
// 作者:杨宏轩 //
// 学号:33061006 //
// 版本:1.0 //
// 日期:2006-2-11 //
// 描述:扩充C0文法编译器主程序 //
// //
//**********************************************************************//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "VarDef.h"
#include "ProcDef.h"
extern void Interpreter(char *fileName);
// 初始化
void Initial(){
lineNo=1;
err=0;
tTop=0;
level=0;
tbIndex[0]=0;
label=0;
}
// 读取源文件中的字符
void GetChar(){
static int ln=1; // 当前字符所在的行号
lineNo=ln; // 处理的单词实际所在行号(由于预读造成lineNo总滞后于ln)
if (feof(fpIn))
ch=-1;
else{
ch=fgetc(fpIn);
while ((ch=='\n') || (ch=='\t')){
if (ch=='\n')
ln++;
ch=fgetc(fpIn);
}
}
}
//***************************错误处理****************************//
void Error(int i,char *s){
if (err==0)
fpErr=fopen("Err.txt","w");
err++;
fprintf(fpErr,"Error at %d:%s\n",lineNo,s);
}
//****************************************************************//
//***************************词法分析****************************//
// 判断标识符是否为保留字
int IsReserved(char s[]){
int i;
for (i=0;i<NUMRSV;i++)
if (strcmp(s,reserved[i])==0)
return OFFSET+i;
return -1;
}
// 按照词法规则,分析出各语法成分(读符号)
Symbol GetSym(){
int i;
Symbol s;
int k=0; // 当前字符在单词值中的位置
s.name[0]='\0';
while (ch==' ')
GetChar();
if (isalpha(ch) || ch=='_'){ // 处理标识符和保留字
s.name[k++]=ch;
GetChar();
while (isalpha(ch) || ch=='_' || isdigit(ch)){
if (k<VARMAX) // 若标识符过长,则进行截取
s.name[k]=ch;
k++;
GetChar();
}
if (k>VARMAX){ // 判断标识符是否超过指定长度
Error(lineNo,"Identifer is too long!");
s.name[VARMAX]='\0';
}
else
s.name[k]='\0';
if ((i=IsReserved(s.name))!=-1) // 判断是否为保留字
s.type=i;
else
s.type=IDENT;
}
else if (isdigit(ch)){ // 处理数字
while (isdigit(ch)){
if (k<SMAX)
s.name[k++]=ch;
else
k++;
GetChar();
}
s.type=INTEGER;
if (ch=='.'){ // 判断是浮点数还是整数
s.name[k++]=ch;
GetChar();
while (isdigit(ch)){
if (k<SMAX)
s.name[k++]=ch;
else
k++;
GetChar();
}
s.type=REAL;
}
if (k<=SMAX)
s.name[k]='\0';
else
s.name[SMAX]='\0';
if (s.type==INTEGER && abs(atoi(s.name))>INTMAX) // 判断整数是否超出范围
Error(lineNo,"Number is out of range!");
if (s.type==REAL && abs(atof(s.name))>REALMAX) // 判断浮点数是否超出范围
Error(lineNo,"Number is out of range!");
}
else if (ch=='\''){ // 处理字符常量
GetChar();
s.name[k++]=ch;
s.type=CHARC;
GetChar();
if (ch!='\'')
Error(lineNo,"Char is lack of \' ");
else
GetChar();
s.name[k]='\0';
}
else if (ch=='"'){ // 处理字符串
GetChar();
while (ch!='"'){
if (k<SMAX)
s.name[k++]=ch;
else
k++;
GetChar();
}
if (ch=='"')
GetChar();
if (k<=SMAX) // 判断字符串是否过长
s.name[k]='\0';
else
Error(lineNo,"String is too long!");
s.type=STRING;
}
else if (ch=='='){ // 处理 == 和 =
GetChar();
if (ch=='='){
s.type=EQL;
GetChar();
}
else
s.type=BECOME;
}
else if (ch=='<'){ // 处理 <= 和 <
GetChar();
if (ch=='='){
s.type=LESSEQL;
GetChar();
}
else
s.type=LESS;
}
else if (ch=='>'){ // 处理 >= 和 >
GetChar();
if (ch=='='){
s.type=GREATEREQL;
GetChar();
}
else
s.type=GREATER;
}
else if (ch=='!'){ // 处理 !=
GetChar();
if (ch=='='){
s.type=NOTEQL;
GetChar();
}
else
Error(lineNo,"There is illegal words in this line");
}
else{ // 处理其它符号: { } ( ) , ; :
switch (ch)
{
case '+': s.type=PLUS; break;
case '-': s.type=MINUS; break;
case '*': s.type=TIMES; break;
case '/': s.type=RDIV; break;
case '{': s.type=LBRACKET; break;
case '}': s.type=RBRACKET; break;
case '(': s.type=LPARENT; break;
case ')': s.type=RPARENT; break;
case ',': s.type=COMMA; break;
case ';': s.type=SEMICOLON; break;
case ':': s.type=COLON; break;
case -1:s.type=-1;break;
default: Error(lineNo,"Word Error!\0");
}
GetChar();
}
return s;
}
//***********************************************************//
//************************* 语法分析*************************//
void ReadSym(){ // 读符号
sym=buf[0];
buf[0]=buf[1];
buf[1]=GetSym();
curLine=lineN[0];
lineN[0]=lineN[1];
lineN[1]=lineNo;
}
bool IsType(int t){ // 判断获取的单词是否为类型标识符
if (t==INTSYM || t==FLOATSYM || t==CHARSYM)
return true;
return false;
}
bool IsIn(int t,int i){ // 判断获取单词类型是否在i的First集中
int k;
for (k=0;k<8;k++)
if (t==first[i][k])
return true;
return false;
}
void Ignore(int i){
do{
ReadSym();
}while(sym.type!=i);
ReadSym();
}
void ReturnSent(){ // 返回语句
int t;
ReadSym();
if (sym.type==LPARENT){
ReadSym();
if (IsIn(sym.type,EXPRESSION)){
Expression(t);
}
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else
ReadSym();
}
_Emit("RETURN");
}
void WriteSent(){ // 写语句
char n[SMAX+1];
int t;
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else
ReadSym();
if (sym.type==STRING){
strcpy(n,sym.name);
_Emit("WRITES",n);
ReadSym();
if (sym.type!=COMMA)
Error(curLine,"缺少,");
else
ReadSym();
}
if (IsIn(sym.type,EXPRESSION)){
Expression(t);
_Write(t);
}
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else
ReadSym();
}
void ReadSent(){ // 读语句
char n[SMAX+1];
int l,j,t;
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
ReadSym();
if (sym.type!=IDENT)
Error(curLine,"缺少标识符");
else{
strcpy(n,sym.name);
_Lookup(n,l,j);
_Type(l,j,t);
ReadSym();
}
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emit("READ");
_Emit("STO",l,j);
ReadSym();
}
}
void SentList(){ // 语句列
while (IsIn(sym.type,SENTENCE) || sym.type==SEMICOLON){
if (sym.type!=SEMICOLON)
Sentence();
else
ReadSym();
}
}
void ParaList(int i,int z){ // 值参数列表
int t,m=0;
if (IsIn(sym.type,EXPRESSION)){
while(1){
Expression(t);
_Chktype(t,i,m,z);
if (sym.type!=COMMA)
break;
ReadSym();
}
}
_ChkLength(z);
}
void ProcCall(){ // 无返回值函数调用语句
char n[SMAX+1],y[SMAX+1];
int i,z;
if (sym.type!=IDENT)
Error(curLine,"缺少函数名");
strcpy(n,sym.name);
if (err==0 && !_LookupProc(n,i,z))
Error(curLine,"该函数未定义");
else
_GenLab(y);
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else{
ReadSym();
ParaList(i,z);
}
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emit("LOADI",atoi(y));
_Emit("JSR",n);
_Labprod(y);
ReadSym();
}
}
void FuncCall(){ // 有返回值函数调用语句
char n[SMAX+1],y[SMAX+1];
int i,z;
if (sym.type!=IDENT)
Error(curLine,"缺少函数名");
strcpy(n,sym.name);
if (err==0 && !_LookupProc(n,i,z))
Error(curLine,"该函数未定义");
else
_GenLab(y);
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else{
ReadSym();
ParaList(i,z);
}
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emit("LOADI",atoi(y));
_Emit("JSR",n);
_Labprod(y);
ReadSym();
}
}
void Default(){ // 缺省
if (sym.type==DEFAULTSYM){
ReadSym();
if (sym.type!=COLON){
Error(curLine,"缺少:");
Ignore(SEMICOLON);
}
else
ReadSym();
Sentence();
}
}
void SubCase(char x[]){ // 情况子语句
int s;unionc c; char y[SMAX+1];
if (sym.type!=CASESYM)
Error(curLine,"缺少分情况语句case");
_Emit("LOAD $Top");
ReadSym();
if (sym.type==PLUS || sym.type==MINUS || sym.type==INTEGER)
Integer(s,c);
else if (sym.type==PLUS || sym.type==MINUS || sym.type==REAL)
Float(s,c);
else if (sym.type==CHARC){
Char(s,c);
}
_GenLab(y);
_Pushi(s,c);
_Brcomp(y);
if (sym.type!=COLON){
Error(curLine,"缺少:");
Ignore(SEMICOLON);
}
else
ReadSym();
Sentence();
_Emit("BR",x);
_Labprod(y);
}
void CaseTable(char x[]){ // 情况表
SubCase(x);
while(sym.type==CASESYM){
SubCase(x);
}
}
void CaseSent(){ // 情况语句
char x[SMAX+1];
int t;
if (sym.type!=SWITCHSYM)
Error(curLine,"缺少switch标识符");
else
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else
ReadSym();
Expression(t);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_GenLab(x);
ReadSym();
}
if (sym.type!=LBRACKET)
Error(curLine,"缺少{");
else
ReadSym();
CaseTable(x);
Default();
if (sym.type!=RBRACKET){
Error(curLine,"缺少}");
Ignore(RBRACKET);
return;
}
_Labprod(x);
_Emit("POP");
ReadSym();
}
void WhileSent(){ // 循环语句
char r[SMAX+1],f[SMAX+1];
_GenLab(r);
_Labprod(r);
ReadSym();
if (sym.type!=LPARENT){
Error(curLine,"缺少(");
Ignore(SEMICOLON);
goto LSentence;
}
ReadSym();
Condition();
_GenLab(f);
_Emit("BRF",f);
if (sym.type!=RPARENT){
Error(curLine,"缺少)");
Ignore(SEMICOLON);
goto LSentence;
}
ReadSym();
LSentence:
Sentence();
_Emit("BR",r);
_Labprod(f);
}
void Condition(){ // 条件
int t,t1,t2;
Expression(t1);
t=sym.type;
if (t==NOTEQL || t==LESS || t==GREATER || t==LESSEQL
|| t==GREATEREQL || t==EQL){
ReadSym();
Expression(t2);
_Lggen(t1,t2,t);
return;\
}
}
void IfSent(){ // 条件语句
char y[SMAX+1],z[SMAX+1];
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else
ReadSym();
Condition();
_GenLab(y);
_Emit("BRF",y);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else
ReadSym();
Sentence();
if (sym.type!=ELSESYM)
_Labprod(y);
else{
_GenLab(z);
_Emit("BR",z);
_Labprod(y);
ReadSym();
Sentence();
_Labprod(z);
}
}
void LetSent(){ // 赋值语句
int l,j,t,s;
bool Lt;
Lt=true;
_Lookup(sym.name,l,j);
_Type(l,j,t);
if (err==0 && symTable[tbIndex[l]+j-1].kind==CONST)
Error(curLine,"常量不能为左值"); // 常量不能为左值
ReadSym();
if (sym.type!=BECOME){
Error(curLine,"赋值语句中缺少=");
Ignore(SEMICOLON);
return;
}
ReadSym();
Lt=false;
Expression(s);
_Storin(t,s,l,j);
}
void Sentence(){ // 处理语句
int l,j;
if (sym.type==IFSYM)
IfSent();
else if (sym.type==WHILESYM)
WhileSent();
else if (sym.type==SWITCHSYM)
CaseSent();
else if (sym.type==PRINTFSYM){
WriteSent();
if (sym.type!=SEMICOLON)
Error(curLine,"缺少;");
ReadSym();
}
else if (sym.type==SCANFSYM){
ReadSent();
if (sym.type!=SEMICOLON)
Error(curLine,"缺少;");
ReadSym();
}
else if (sym.type==IDENT && buf[0].type==LPARENT){
_Lookup(sym.name,l,j);
FuncCall();
if (sym.type!=SEMICOLON)
Error(curLine,"缺少;");
else
ReadSym();
}
else if (sym.type==RETURNSYM){
ReturnSent();
if (sym.type!=SEMICOLON)
Error(curLine,"缺少;");
ReadSym();
}
else if (sym.type==IDENT && buf[0].type==BECOME){
LetSent();
if (sym.type!=SEMICOLON)
Error(curLine,"缺少;");
ReadSym();
}
else if (sym.type==LBRACKET){
ReadSym();
SentList();
if (sym.type!=RBRACKET)
Error(curLine,"缺少}");
ReadSym();
}
}
void Factor(int &t){ // 因子
int j,t1,l;
unionc c;
char n[SMAX+1];
if (sym.type==IDENT && buf[0].type!=LPARENT){ // 处理标识符
strcpy(n,sym.name);
if (_Lookup(n,l,j)==-1) // 符号表中无定义
Error(curLine,"标识符未定义");
else{
_Type(l,j,t1);
_Emit("LOAD",l,j); // 将数据压栈
}
ReadSym();
}
else if (sym.type==PLUS || sym.type==MINUS || sym.type==INTEGER){
Integer(t1,c);
_Emit("LOADI",c.ival);
}
else if (sym.type==PLUS || sym.type==MINUS || sym.type==REAL){
Float(t1,c);
_Emit("LOADI",c.fval);
}
else if (sym.type==CHARC){
Char(t1,c);
_Emit("LOADI",c.cval);
}
else if (sym.type==IDENT && buf[0].type==LPARENT){
FuncCall();
}
else if (sym.type==LPARENT){
ReadSym();
Expression(t1);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else
ReadSym();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -