📄 33.txt
字号:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
//定义缓冲区大小
#define BUFFERLEN 2048
//定义缓冲区索引
int front=0,rear=0;
//定义缓冲区并初始化
char buffer[BUFFERLEN]={0};
//用于指示装入哪半个缓冲区
int position=0;
//全局变量指示行号
int line;
//filename: 要解析的源文件名
FILE * fin;
//临时数组,用于存储标识符或关键字
char id[100];
//临时数组索引
int dex=0;
//每行单词计数器
int count=0;
//临时字符,用于存储字符
char achar;
//符号结构定义
struct token{
int lineno;//行号
int position;//在该行中的位置
int wordkey;//符号类型,用十六进制表示
char* value;
struct token* next_token;
}token;
//变量表
struct token* token_list_head=NULL;
//关键字表
char* keyword[]={
"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",
"protect",
"public",
"return",
"short",
"static",
"super",
"switch",
"synchronized",
"this",
"throw",
"throws",
"transient",
"true",
"try",
"void",
"volatile",
"while"
};
//将源文件装入缓冲区
void load(FILE * fin,int flag){
if(flag==0){
fread(buffer,sizeof(char),1023,fin);
rear=0;
}
else{
fread(buffer+1024,sizeof(char),1023,fin);
rear=1025;
}
}
//在关键字表中进行查找,若照到则返回1,否则返回0
int lookup_keyword(char* word){
int i;
for(i=0;i<49;i++){
if(strcmp(word,keyword[i])==0)
return 0;
}
if(i==49)
return 1;
}
//获取一个符号
struct token* get_token(){
int i;
struct token* token_pointer;
char ch=buffer[rear];
//如果是回车,只是将行号加1
if(ch=='\n'){
line++;
}
//如果遇到缓冲区结尾,装入另一半缓冲区
else if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
//如果是空格,只是将其跳过,并将所有空格用一个属性字表示
else if(isspace(ch)){
do{
ch=buffer[++rear];
if(ch=='\n'){
rear++;//?
line++;
}
else if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
}while(isspace(ch));
front=rear;
token_pointer=(struct token*)malloc(sizeof(token));
token_pointer->lineno=line;
token_pointer->wordkey=0x102;
token_pointer->value=(char*)malloc(2*sizeof(char));
strcpy(token_pointer->value," ");
token_pointer->next_token=token_list_head;
token_list_head=token_pointer;
}
//判断关键字和标识符及布尔值
if(isalnum(ch)||ch=='_'||ch=='$'){
do{
ch=buffer[++rear];
if(ch=='\n'){
//error
}
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
}while(isalnum(ch)||isdigit(ch)||ch=='_'||ch=='$');
i=front;
while(i!=rear){
if(buffer[i]==EOF){
i=(rear/1024)*1024;
}
id[dex]=buffer[i];
dex++;
i++;
}
//创建一块token结构
token_pointer=(struct token*)malloc(sizeof(token));
token_pointer->lineno=line;
token_pointer->value=(char *)malloc(dex*sizeof(char));
strcpy(token_pointer->value,id);
token_pointer->next_token=token_list_head;
token_list_head=token_pointer;
//在关键字表中查找
if(lookup_keyword(id)){
token_pointer->wordkey=0x104;
}
else{
if(strcmp(id,"true")==0 || strcmp(id,"false")==0){
token_pointer->wordkey=0x103;
}
else{
token_pointer->wordkey=0x103;
}
}
front=rear;
//将临时变量存储数组索引置零
dex=0;
//将临时变量存储数组清零
memset(id,0,100);
}
if(ch=='/'){
ch=buffer[++rear];
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
else if(ch=='/'){
do{
ch=buffer[++rear];
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
}while(ch!='\n');
}
else if(ch=='*'){
do{
ch=buffer[++rear];
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
}while(!(ch=='*'&& (ch=buffer[++rear])=='/'));
}
rear++;
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
front=rear;
token_pointer=(struct token*)malloc(sizeof(token));
token_pointer->lineno=line;
token_pointer->wordkey=0x101;
token_pointer->value=(char *)malloc(dex*sizeof(char));
strcpy(token_pointer->value,id);
token_pointer->next_token=token_list_head;
token_list_head=token_pointer;
}
//字符串解析
else if(ch=='"'){
while((ch=buffer[++rear])!='"'){
if(ch=='\\'){
ch=buffer[++rear];
switch(ch){
case ''':achar=''';
break;
case 'r':achar='\r'
break;
case 'f':achar='\f'
break;
case 't':achar='\t'
break;
case 'b':achar='\b';
break;
case 'n':achar='\n';
break;
case 't':achar='\t';
break;
case '\\':achar='\\';
break;
case '"':achar='"';
break;
case '\'':achar='\'';
break;
default:
//error
}
}
id[dex++]=ch;
if(dex==100){
//
}
}
rear++;
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
front=rear;
//将临时变量存储数组索引置零
token_pointer=(struct token*)malloc(sizeof(token));
token_pointer->lineno=line;
token_pointer->wordkey=0x106;
token_pointer->value=(char *)malloc(dex*sizeof(char));
strcpy(token_pointer->value,id);
token_pointer->next_token=token_list_head;
token_list_head=token_pointer;
dex=0;
//将临时变量存储数组清零
memset(id,0,100);
}
/********************************解析单个字符***************************/
else if(ch=='\''){
ch=buffer[++rear];
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
if(ch=='\\'){
ch=buffer[++rear];
if(ch==EOF){
position++;
fseek(fin,1023,1);
if(position/2==0){
load(fin,0);
}
else{
load(fin,1);
}
ch=buffer[rear];
}
switch(ch){
case ''':achar=''';
break;
case 'r':achar='\r'
break;
case 'f':achar='\f'
break;
case 't':achar='\t'
break;
case 'b':achar='\b';
break;
case 'n':achar='\n';
break;
case 't':achar='\t';
break;
case '\\':achar='\\';
break;
case '"':achar='"';
break;
case '\'':achar='\'';
break;
default:
//error
}
}
else
achar=ch;
if((ch=buffer[++rear])!='\'')
;//error
}
/**************************解析分界符及部分运算符*****************************/
else{
switch(ch){
case '(':
return L_BRACKET;
case ')':
return R_BRACKET;
case '[':
return L_MEDBRACKET;
case ']':
return R_MEDBRACKET;
case '{':
return L_BIGBRACKET;
case '}':
return R_BIGBRACKET;
case ',':
return COMMA;
case ';':
return SEMICOLON;
case '%':
return MOD;
case '*':
return MUL;
case '/':
return DIV;
case '+':
return ADD;
case '-':
return SUB;
case ':':
return COLON;
default:
return EOI;
}
int main(int argc,char * argv[]){
char filename[100];
int i=0;
//设立缓冲区标志位
buffer[1023]=EOF;
buffer[2047]=EOF;
printf("Please enter file name:\n");
scanf("%s",filename);
//打开文件,并将1023个字符读入前一半缓冲区
fin=fopen(filename,"r");
if(fin==NULL){
printf("FILE_CANNOT_OPEN\n");
}
else{
load(fin,0);
}
for(i=0;i<40;i++){
get_token();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -