📄 aha.cpp
字号:
/*
类高级程序设计语言的词法分析程序
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
void Sort(char* inputword,FILE* Originalfile);
void RecogID(char* input,FILE* Originalfile); //处理标识符
void RecogDig(char*input,FILE* Originalfile); //处理数字
void RecogDel(char* input,FILE* Originalfile); //处理界符
void HandleCom(char* input,FILE* Originalfile); //处理注释
int Iskeyword(char word);
int IsNumber(char next);
void Initiate(struct keywordchain* keywordtable);
void Lookup(struct keywordchain* keywordtable,char value[],struct tokenform* token, int singal);
void Writetoken(struct tokenform token);
void Scanner();
//定义符号表结构
struct keywordchain
{
int id;
char* value;
struct keywordchain* next;
};
struct keywordchain keywordtable;//定义符号表
int lines =0;//用来统计行数
struct tokenform //定义token结构
{
int id;
struct keywordchain* reference;
};
int main()
{
Scanner();
return 0;
}
//从源程序文件中读取原程序
void Scanner()
{
Initiate(&keywordtable);
FILE* origin;
char input;
if((origin=fopen("origin.txt","r"))==NULL)
printf("文件打开失败!\n");
else
{
fscanf(origin,"%c",&input);
while(input!=EOF)
Sort(&input,origin);
}
fclose(origin);
}
//分类函数用来识别各类单词
void Sort(char* input,FILE* Originalfile)
{
if(isalpha(*input))
RecogID(input,Originalfile);
else if(isdigit(*input))
RecogDig(input,Originalfile);
else if(*input == '/')
HandleCom(input,Originalfile);
else if(*input == ' '||*input == '\n'||*input == '\t')
{
if(*input == '\n')
lines++;
*input = fgetc(Originalfile);
}
else
RecogDel(input,Originalfile);
}
//处理关键字和标识符
void RecogID(char* input,FILE* Originalfile)
{
char word[100];
char next='a'; //为使while循环开始
int i=0;
struct tokenform token;
word[i] = *input;
while(isdigit(next)||isalpha(next)) //读关键字或标识符
{
fscanf(Originalfile,"%c",&next);
if(isdigit(next)||isalpha(next))
word[++i] = next;
}
*input = next;
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
Writetoken(token);
}
//处理注释部分
void HandleCom(char* input,FILE* Originalfile)
{
char word[100];
bool flag =false;
char next, next1='a'; //给next赋初值
int i=0; //计数
word[i] = *input;
fscanf(Originalfile,"%c",&next);
if(next = '*') //以/*开头的注释方式
{
while(flag == false)
{
if(fscanf(Originalfile,"%c",&next1)==EOF) //读到文件结尾
break;
if(next == '*' && next1 =='/' && i!=0) //防止/*/情况误认为结束
flag = true;
i++;
next = next1;
}
if(flag == false)
printf("第%d行注解未完\n",lines);
if(fscanf(Originalfile,"%c",&next) == EOF) //处理下一字符
*input = EOF;
else
*input = next;
}
else if(next == '/') //以//为开头的注释方式
{
while(next != '\n') //读取全部注释
fscanf(Originalfile,"%c",&next);
fscanf(Originalfile,"%c",&next); //读下一个字符
*input = next;
}
}
//处理界符和算符
void RecogDel(char* input,FILE* Originalfile)
{
char word[100];
struct tokenform token;
int i=0;
char next;
word[i] = *input;
if(*input == '>')
{
fscanf(Originalfile,"%c",&next);
if(next == '=')
{
word[++i] = next;
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
else
{
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
}
else if(*input == '<')
{
fscanf(Originalfile,"%c",&next);
if(next == '=')
{
word[++i] = next;
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
else if(next == '>')
{
word[++i] = next;
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
else
{
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
}
else if((*input == '(')||(*input == ')')||(*input == '=')||(*input == '+')||(*input == '*')) //算符
{
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
else if((*input == '&')||(*input == ';')||(*input == ',')||(*input == '|')||(*input == '!')||(*input == '{')||(*input == '}')) //界符
{
word[++i] = '\0';
Lookup(&keywordtable,word,&token,1);
fscanf(Originalfile,"%c",&next);
}
*input = next;
Writetoken(token);
}
//处理常数部分
void RecogDig(char* input,FILE* Originalfile)
{
char number[100];
char next;
int state = 1;
int i = 0;
struct tokenform token;
number[i] = *input;
while(state != 5)
{
fscanf(Originalfile,"%c",&next);
if(state == 1) //接受数据的自动机
{
if(isdigit(next))
state = 1;
else if(next == '.')
state = 2;
else if (next == 'e')
state = 4;
else
state = 5;
}
else if(state == 2)
{
if(isdigit(next))
state = 3;
else
{
printf("数字格式输入错误!\n");
state = 5;
}
}
else if (state == 3)
{
if(isdigit(next))
state = 3;
else if (next == 'e')
state = 4;
else
state = 5;
}
else if (state == 4)
{
if(isdigit(next))
state = 4;
else
state = 5;
}
number[++i] = next;
}
*input = next;
number[i] = '\0';
Lookup(&keywordtable,number,&token,0);
Writetoken(token);
}
//将识别出来的token写入指定文件
void Writetoken(struct tokenform token)
{
FILE* tokenfile;
if((tokenfile=fopen("token.txt","a"))==NULL)
printf("文件写入失败!\n");
else
{
fprintf(tokenfile,"%s %d\n",token.reference->value,token.id);
fclose(tokenfile);
}
}
//判断给定字符是否符合关键字或标识符的要求
// 创建符号表
void Initiate(struct keywordchain* keyword)
{
struct keywordchain* midpoint;
int id;
char name[30];
FILE* keywordfile;
if((keywordfile=fopen("keyword.txt","r"))==NULL)
printf("文件打开失败!\n");
keyword->id = 0;
keyword->value = "none";
while(fscanf(keywordfile,"%s%d",name,&id)!=EOF)
{
midpoint = (struct keywordchain*)malloc(sizeof(struct keywordchain));
midpoint->id = id;
midpoint->value = (char*)malloc(sizeof(name));
strcpy(midpoint->value ,name);
midpoint->next = NULL;
keyword->next = midpoint;
keyword = midpoint;
}
//keywordtable = (struct keywordtable*)malloc(sizeof(struct keywordchain));
}
//查询符号表操作
void Lookup(struct keywordchain* keyword,char value[],struct tokenform* token, int singal)
{
struct keywordchain *reserve, *add;
bool flag = false;
while(keyword!=NULL)
{
if(!strcmp(keyword->value,value)) //如果是关键字,算符,界符
{
token->id = keyword->id; //形成Token字
token->reference = keyword;
flag = true;
break;
}
reserve = keyword;
keyword = keyword->next;
}
if(flag == true)
return ;
else //
{
add = (struct keywordchain*)malloc(sizeof(struct keywordchain));
add->value= (char*)malloc(sizeof(value));
strcpy(add->value,value);
if(singal == 1)
add->id = 13;
else
add->id = 12;
add->next = NULL;
reserve->next = add;
token->id = add->id;
token->reference = add;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -