#define MAX_LEN 50
#define LINE_MAX 256
#define KEYWORD_NUM 8
#define OP_NUM 12
#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
//关键字
static const char *keyword[]={"int","real","while","if","else","for","write","read"};
//运算符
static const char *op[]={"+","-","*","/","=","<","==","<>",
"+=","-=","*=","/="};
//分隔符
static const char *seperator[]={"(",")",";",",","[","]","{","}"};
//行号
int line=1;
//判断关键字
bool keyword_search(char const *token){
for(int i=0;i<KEYWORD_NUM;i++){
if(strcmp(token,keyword[i])==0)
return true;
}
return false;
}
//判断标识符
bool id_search(char const *token){
if(!isalpha(*token))
return false;
while(*token!='/0'){
if(!isalnum(*token))
return false;
token++;
}
return true;
}
//判断整形值
bool int_search(char const *token){
while(*token!='/0'){
if('0'>*token||'9'<*token)
return false;
token++;
}
return true;
}
//判断浮点数
bool real_search(char const *token){
int dot=0;
while(*token!='/0'){
if(*token=='.')
dot++;
else if(!isdigit(*token))
return false;
if(dot>1)
return false;
token++;
}
return true;
}
//判断运算符
bool op_search(char const *token){
for(int i=0;i<OP_NUM;i++)
if(strcmp(token,op[i])==0)
return true;
return false;
}
//'+' ,'-' ,'*' ,'/'
bool isop(char ch){
if(ch!='+'
&&ch!='-'
&&ch!='*'
&&ch!='/'
&&ch!='<'
&&ch!='>'
&&ch!='=')
return false;
return true;
}
void scan(){
char str[LINE_MAX];
char ch;
char *temp;
char token[MAX_LEN];
char file_name[MAX_LEN];
FILE *input;
FILE *output;
cout<<"input an file>>";
cin>>file_name;
input=fopen(file_name,"r");
if(input==NULL)
{
cout<<"Error! Can't open file: "<<file_name<<endl;
return;
}
output=fopen("output.txt","w+");
while(fgets(str,LINE_MAX,input)!=NULL){
fprintf(output,"%d: %s",line,str);
temp=str;
//处理行
while(*temp!='/0'){
ch=*temp;
//处理空白,直接跳过
if(ch=='/n'||ch=='/t'||ch==' '){
;
}
//字符常量处理
else if(ch=='/''){
if(ch=*++temp=='//') //转义符
ch=*++temp;
fprintf(output,"/t%d:char val=/'%c/'/n",line,ch);
temp++;
}
//字符串常量处理
else if(ch=='/"'){
fprintf(output,"/t%d:string val=/"",line);
while(*++temp!='/"')
fprintf(output,"%c",*temp);
fprintf(output,"/"/n");
}
//注释处理
else if(ch=='/'){
ch=*++temp;
//单行注释
if(ch=='/')
break;
//运算
else if(ch=='='){
fprintf(output,"/t%d:OPERATOR /=/n",line);
}
//多行注释
else if(ch=='*'){
while(true){
if(*temp=='/0'){
line++;
fgets(str,LINE_MAX,input);
fprintf(output,"%d: %s",line,str);
temp=str;
}
else if(*temp++=='*'&&*temp=='/')
break ;
}
}
//除法运算
else{
fprintf(output,"/t%d:OPERATOR //n",line);
temp--;
}
}
//标识符,关键字
else if(isalpha(ch)){
int i=0;
while(isalnum(ch=*temp++))
token[i++]=ch;
token[i]='/0';
temp--;
temp--;
if(keyword_search(token))
fprintf(output,"/t%d: Keyword %s/n",line,token);
else if(id_search(token))
fprintf(output,"/t%d: ID, name=%s/n",line,token);
else
fprintf(output,"/t%d: Unrecognized %s/n",line,token);
}
//数值
else if(isdigit(ch)){
int i=0;
while(*temp=='.'|isalnum(ch=*temp++))
token[i++]=ch;
token[i]='/0';
temp--;
temp--;
if(int_search(token))
fprintf(output,"/t%d: INT, value= %s/n",line,token);
else if(real_search(token))
fprintf(output,"/t%d: REAL, value=%s/n",line,token);
else
fprintf(output,"/t%d: Unrecognized %s/n",line,token);
}
//运算符处理
else if(isop(ch)){
int i=0;
while(isop(ch=*temp++))
token[i++]=ch;
token[i]='/0';
temp--;
temp--;
if(op_search(token))
fprintf(output,"/t%d: OPERATOR %s/n",line,token);
else
fprintf(output,"/t%d: Unrecognized %s/n",line,token);
}
//分格符
else if(ch=='['||ch==']'
||ch=='('
||ch=='{'
||ch=='}'
||ch==')'
||ch==';'){
fprintf(output,"/t%d: %c/n",line,ch);
}
//非法字符
else
fprintf(output,"/t%d: Unrecognized %c/n",line,ch);
temp++;
}
line++;
}
fclose(input);
fclose(output);
}
void display(){
FILE *output;
output=fopen("output.txt","r");
char str[LINE_MAX];
while(fgets(str,LINE_MAX,output)!=NULL)
printf("%s",str);
fclose(output);
}
int main(){
char ch='1';
while(true){
if(ch=='1')
scan();
line=1;
printf("analyse done!/nPress 1 to continue/nPress 2 to display result/nPress anyother key to exit/n");
cin>>ch;
if(ch=='1')
continue;
else if(ch=='2')
display();
else break;
}
}
词法分析器CMM
最新推荐文章于 2024-05-31 08:41:37 发布