📄 yufa.h
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define txmax 100 //名字表的最大容量
#define levmax 3 //最大允许过程嵌套声明层数[0,levmax]
#define cxmax 200 //最多的虚拟机代码数
// FILE *fa2;
int Lev=0;
int ptx=0 ;//名字表尾指针的指针,为了可以改变名字表尾指针的值
int pdx=3;
int varcount=0;
FILE *fin;
int flag=1;//用来标记表达式中的错误,当表达式至少出现一个错误时flag=0否则为1
int i=0,j=0;//定义变量i,j 用来保存表达式中左括号和,右括号的数目,当不相等是表达式错误
int num;
char id[20];
char error[20][80];
char errortotal=0;
void printblank(int m);
char lineno[6]="1";
//名字表中的类型
enum object
{
constant,variable,procedur
};
//虚拟机代码
enum fct
{
lit,opr,lod,sto,cal,inte,jmp,jpc
};
//虚拟机代码结构
typedef struct instruction
{
enum fct f;//虚拟机代码指令
int l; //引用层与申明层的层次差
int a; //根据f的不同而不同
}Instruction;
//符号表结构
typedef struct tablestruct
{
char name[10];//名字
object kind;//类型:const,var,array or procedure
int val;//数值,仅const 不使用
int level;//所处层,仅const不使用
int adr;//地址,仅const不使用
int size;//需要分配的数据区空间,仅procedure使用
}Tablestruct;
Tablestruct table[txmax];//定义一个字符表结构体数组
Instruction code[cxmax];//定义一个编码结构体数组用来保存 类pcode码
enum symbol
{
nul,ident,number,plus,minus,times,slash,oddsym,
eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,
semicolon,period,becomes,beginsym,endsym,ifsym,
thensym,whilesym,writesym,readsym,dosym,callsym,
constsym,varsym,proceduresym,dot
};
symbol sym;
char *errortype[27]={
"(0)常数说明中的\"=\"漏掉", "(1)常数说明中的\"=\"后应是数字",
"(2)常数说明中的标识符后应是\"=\"","(3)contst,var,procedure后应为标识符",
"(4)漏掉了','或';'","(5)过程说明后的符号不正确(应是语句开始符,或构成定义符)",
"(6)应是语句开始符","(7)程序体内语句部分的后跟符不正确","(8)程序结尾丢了句号'.'",
"(9)语句之间漏了';'","(10)标识符未说明",
"(11)赋值语句中,赋值号左部标识符属性应是变量",
"(12)赋值语句左部标识符后应是赋值号':='","(13)call后应为标识符",
"(14)call后标识符属性应为过程","(15)条件语句中丢了'then'",
"(16)丢了'end'或';'","(17)while型循环语句中丢了'do'","(18)语句后的符号不正确",
"(19)应为关系运算符","(20)表达式内标识符属性不能是过程","(21)表达式中漏掉右括号')'",
"(22)因子有的非法符号","(23)表达式的开始符号不能是此符号","(24)数越界",
"(25)read语句括号中的标识符不是变量","(26)变量重复定义了"
};
symbol getsym(FILE *file)
{
//此函数用来将从file指向的文件中读出的字符串转换成枚举类型,每次读一行一行中以逗号作为分割符号。
char ch[20]; //定义一个字符数组用来保存从文件里面读出的字符串
int i=0;//数组偏移量
while((lineno[i]=fgetc(file))!=','&&lineno[i]!='\n')
{
if(feof(file)) break;//判断是否读到了文件的末尾如没有读到则i加1;
else
i++;
}
lineno[i]='\0';
i=0;
while((ch[i]=fgetc(file))!=','&&ch[i]!='\n')
{
if(feof(file)) break;
else i++;
}
ch[i]='\0';
if(strlen(ch)>0)
if(strcmp(ch,"nul")==0) return nul;//返回相应的字符串匹配的枚举值
if(strcmp(ch,"ident")==0)
{
i=0;
while((ch[i]=fgetc(file))!='\n')
{
if(feof(file)) break;
else i++;
}
ch[i]='\0';
strcpy(id,ch);
return ident;
}
if(strcmp(ch,"number")==0)
{
i=0;
while((ch[i]=fgetc(file))!='\n')
{
if(feof(file)) break;
else i++;
}
ch[i]='\0';
num=atoi(ch);
return number;
}
if(strcmp(ch,"plus")==0) return plus;
if(strcmp(ch,"minus")==0) return minus;
if(strcmp(ch,"times")==0) return times;
if(strcmp(ch,"slash")==0) return slash;
if(strcmp(ch,"oddsym")==0) return oddsym;
if(strcmp(ch,"eql")==0) return eql;
if(strcmp(ch,"neq")==0)return neq;
if(strcmp(ch,"lss")==0) return lss;
if(strcmp(ch,"leq")==0) return leq;
if(strcmp(ch,"gtr")==0) return gtr;
if(strcmp(ch,"geq")==0) return geq;
if(strcmp(ch,"lparen")==0) return lparen;
if(strcmp(ch,"rparen")==0) return rparen;
if(strcmp(ch,"comma")==0) return comma;
if(strcmp(ch,"semicolon")==0) return semicolon;
if(strcmp(ch,"period")==0) return period;
if(strcmp(ch,"becomes")==0) return becomes;
if(strcmp(ch,"beginsym")==0) return beginsym;
if(strcmp(ch,"endsym")==0) return endsym;
if(strcmp(ch,"ifsym")==0) return ifsym;
if(strcmp(ch,"thensym")==0) return thensym;
if(strcmp(ch,"whilesym")==0) return whilesym;
if(strcmp(ch,"writesym")==0) return writesym;
if(strcmp(ch,"readsym")==0) return readsym;
if(strcmp(ch,"dosym")==0) return dosym;
if(strcmp(ch,"callsym")==0) return callsym;
if(strcmp(ch,"constsym")==0) return constsym;
if(strcmp(ch,"varsym")==0) return varsym;
if(strcmp(ch,"proceduresym")==0) return proceduresym;
return (symbol)0;//当匹配不了时返回0值由于0不是枚举类型故必须要使用强制类型转换
}
void progam(FILE *fin);//申明程序
void block(FILE *fin);//申明分程序
void constsymh(FILE *fin);//申明常量说明
void varsymh(FILE *fin);//申明变量说明
void proceduresymh(FILE *fin);//申明过程说明
void constdefin(FILE *fin);//常量定义
void sentence(FILE *fin);//申明句子
void statement(FILE *fin);//申明赋值语句
void tiaojian(FILE *fin);//申明条件
void expression(FILE *fin);//表达式申明
void term(FILE *fin);//申明项 函数
void factor(FILE *fin);//申明因子 函数
void condition(FILE *fin);//申明条件语句
void beginsymh(FILE *fin);//申明复合语句
void whilesymh(FILE *fin);//申明循环语句
void writesymh(FILE *fin);//申明写语句
void readsymh(FILE *fin);//申明读语句
void callsymh(FILE *fin);//申明过程调用语句
int k=0;//记录偏移的总长度
int m=1;//定义每次偏移的长度
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -