📄 main.c
字号:
#include "stdio.h"
#include "string.h"
struct stream { //属性字流
char attribute[6];
int site;
};
struct stream flow;
char buf[31];
char buf1[16]; //第一缓冲区,存放被覆盖的前半区的字符
char buf2[16]; //第二缓冲区,存放被覆盖的后半区的字符
int count1,count2; //count1指向缓冲区里的当前字符,count2表示不是关键字的标识符的个数
int count3,count4,count5,count6,count7; //指向变量表和错误的单词表,变量值表,注释表,字符串表
int index1; //指示第二缓冲区是否有内容
int row,line1,line2,linetotal,total;
char inkey[20],ininden[20],innum[14],instring[50];
char character; //存储第一次扫描的字符
char numstring[4]; //存储字符数,行号,列号转换的字符串
char keyword[50][13] = {
"abstract","boolean","break","byte","case","catch","char","class",
"const","continue","default","do","double","else","extends","false",
"final","finally","float","for","goto","if","implements","import",
"instanceof","int","interface","long","native","new","null","package",
"private","protected","public","return","short","static","super","switch",
"synchronized","this","throw","throws","transient","true","try","void",
"volatile","while"
};
char words[50][13]; //变量表
char value[50][13]; //变量或常量的值
char note[80][20] = {"//","/*","*/"}; //注释表
char op[50][5] = { //运算符表
"==","=","++","+=","+","--","-=","-","*=","*","/=",
"/","%=","%","^=","^","&=","&","|=","|","!=","!","&&","||",
">",">=",">>",">>=",">>>",">>>=","<","<=","<<","<<=",
"?",":","~","[","]","(",")",".",",","{","}",";"," "
};
char strings[50][50] = {"\""}; //存放字符串中单词的表
char inerror[50][50]; //错误单词表
FILE *fp,*fp1;
long int offset;
//读取字符到缓冲区前半区
void readin1() {
char ch,ch1;
char filename[10] ={"a.txt"};
int i = 15;
fp = fopen(filename,"r");
fseek(fp,offset,0); //定位指针的位置
while(1) {
ch = fgetc(fp);
buf[i++] = ch;
if(i == 30) break;
}
buf[i] = '\0';
offset = ftell(fp); //保存当前指针
fclose(fp);
}
//把后半区的内容送到前半区
void readin2() {
int i;
for(i = 0; i < 15; i++) { //把后半区的字符送给前半区
buf1[i] = buf[i];
buf[i] = buf[i+15];
}
}
//把第二缓冲区的内容送到后半区
void readin3() {
int i;
for(i = 0; i < 15; i++) { //把后半区的字符送给前半区
buf[i+15] = buf2[i];
}
index1 = 0;
}
//从缓冲区中读取一个字符
char readchar() {
char ch;
if(count1 == 15) { //读字符到缓冲区中间,则重新读入字符到缓冲区
if(index1 == 1) { //第二缓冲区里有字符
readin2();
readin3();
}
else {
readin2();
readin1();
}
count1 = 0;
}
ch = buf[count1];
count1++;
return ch;
}
//回退一个字符
void untread() {
char ch;
int i;
count1--;
if(count1 < 0) { //若正好在第一个字符,则把第一缓冲区的内容送到前半区
for(i = 0; i < 15; i++) {
buf2[i] = buf[i+15];
buf[i+15] = buf[i];
buf[i] = buf1[i];
}
index1 = 1; //表示第二缓冲区有内容
count1 = 14;
}
}
//清inkey和ininden,innum
void clean() {
int i;
for(i = 0; i < 14; i++) {
inkey[i] = '\0';
ininden[i] = '\0';
innum[i] = '\0';
}
}
//初始化
void initi() {
int i;
for(i = 0; i < 31; i++) {
buf[i] = '#';
}
count1 = 0;
count2 = 0;
count3 = 0;
count4 = 0;
count5 = 0;
count6 = 3;
count7 = 1;
index1 = 0;
offset = 0L;
row = 1;
line1 = 0;
line2 = 0;
total = 0;
linetotal = 0;
}
//把整数转换为字符串,即行号和列号
void change(int a) {
int i;
if(a < 10) {
numstring[2] = a + 48;
numstring[1] = ' ';
numstring[0] = ' ';
}
else if(a < 100) {
i = a % 10;
numstring[2] = i + 48;
a = a / 10;
numstring[1] = a + 48;
numstring[0] = ' ';
}
else if(a < 1000) {
i = a % 10;
numstring[2] = i + 48;
a = a / 10;
i = a % 10;
numstring[1] = i + 48;
a = a / 10;
numstring[0] = a + 48;
}
numstring[3] = '\0';
}
//把属性字流信息写进文件里
void writefile() {
char filename[20] ={"scanner_output.txt"},ch,string[3];
fp1 = fopen(filename,"a");
change(total); //总字数
fputs(numstring,fp1);
ch = ':';
fputc(ch,fp1);
change(linetotal); //每行的字数
fputs(numstring,fp1);
ch = ' ';
fputc(ch,fp1);
ch = '(';
fputc(ch,fp1);
change(row); //单词的位置
fputs(numstring,fp1);
ch = ',';
fputc(ch,fp1);
change(line2);
fputs(numstring,fp1);
ch = ')';
fputc(ch,fp1);
ch = ';';
fputc(ch,fp1);
ch = '(';
fputc(ch,fp);
strcpy(string,flow.attribute); //字符的属性
fputs(string,fp1);
ch = ',';
fputc(ch,fp1);
ch = flow.attribute[3];
if(ch == '0') {
ch = flow.attribute[4];
switch (ch) { //从各个表中读入字符流的值
case '0':
strcpy(string,inerror[flow.site]); //
fputs(string,fp1);
break;
case '1':
strcpy(string,note[flow.site]); //
fputs(string,fp1);
break;
case '2':
strcpy(string,op[flow.site]); //
fputs(string,fp1);
break;
case '3':
strcpy(string,keyword[flow.site]); //
fputs(string,fp1);
break;
case '4':
strcpy(string,words[flow.site]); //
fputs(string,fp1);
break;
case '5':
strcpy(string,keyword[flow.site]); //
fputs(string,fp1);
break;
case '6':
strcpy(string,instring); //
fputs(string,fp1);
break;
case '7':
strcpy(string,value[flow.site]); //
fputs(string,fp1);
break;
case '8':
strcpy(string,value[flow.site]); //
fputs(string,fp1);
break;
case '9':
strcpy(string,strings[flow.site]); //
fputs(string,fp1);
break;
}
}
else {
strcpy(string,op[flow.site]); //
fputs(string,fp1);
}
ch = ')';
fputc(ch,fp1);
ch = '\n';
fputc(ch,fp1);
fclose(fp1);
}
//扫描到错误的单词
void error(char *string) {
char ch,*sp;
int i = 0;
while(*string != '\0') { //把错误的字符之前的字符传递给错误的单词表
inerror[count3][i] = *string;
i++;
string++;
}
ch = readchar(); //继续读入错误的单词
while( ch != ' ' && ch != '\n' && ch != EOF) { //
if(ch == '/') {
character = ch;
ch = readchar();
if(ch != '/' && ch != '*') { //
inerror[count3][i++] = character;
inerror[count3][i] = ch;
ch = readchar();
i++;
line1++;
}
else break; //遇到注释停止
}
else {
inerror[count3][i] = ch;
ch = readchar();
i++;
line1++;
}
}
sp = "0x100";
strcpy(flow.attribute,sp);
flow.site = count3;
count3++;
linetotal++;
total++;
writefile();
}
//扫描标识符
void identifier() {
char ch,*sp;
int i = count2,j = 0;
ch = character; //第一个字符保存在character,则不用回退
line1++;
line2 = line1;
line2 -= count2;
while ( (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '$' || ch == '_') {
ininden[i++] = ch;
ch = readchar();
if(i == 19) break;
}
if(i == count2) { i = 0;}
else { ininden[i] = '\0';}
line1 = line1 + i - 1;
if(i < 19) { //扫描结束,
for(j = 0; j < count4; j++) {
if(strcmp(ininden,words[j]) == 0) { //判断标识符是否已存在
sp = "0x104";
strcpy(flow.attribute,sp);
flow.site = j;
total++;
linetotal++;
writefile();
break;
}
}
if(j == count4) { //不存在则写进变量表
strcpy(words[count4],ininden);
sp = "0x104";
strcpy(flow.attribute,sp);
flow.site = j;
total++;
linetotal++;
writefile();
count4++;
}
}
else { //大于12个字符为错误单词
sp = ininden;
untread();
error(sp);
}
clean();
count2 = 0;
}
//识别关键字
void key() {
char ch,*sp;
int i = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -