词法分析器CMM

来源:互联网 发布:面板数据主成分分析法 编辑:程序博客网 时间:2024/05/16 13:57

#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;
    }
}

原创粉丝点击