用 C/C++ 编写一个 C 语言的词法分析器程序

#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
#define maxn 100
#include<map>
//词法分析器,对于输入的串,先处理空格,过滤掉,进入主程序,判断是字母,循环判断字母或数字
//循环出去后,判断所读字符串是否是保留字,若是输出保留字及其编码,若不是,输出标识符和编码
//判断首字符是数字,则可能是常数,识别首字符后,循环判断是否是数字,出循环后指针回退一个字符
//输出数字
//需要的函数,getbe()过滤空格,connect用string实现,back()回退一个指针
string Reversed[34]={
    
    " ","auto","break","case","char" ,"const","continue",
"default","do","double","else","enum" ,"extern" ,
"float","for","goto ","if","int", "long",
"register","return","short", "signed","sizeof","static" ,
"struct", "switch" ,"typedef","union", "unsigned","void" ,
"volatile" ,"while"};
int p;
string prog;
string str;
int i;
void read_prog(string& prog)
{
    
    
	char c;
	while(scanf("%c",&c)!=EOF){
    
    
		prog += c;
	}
}
void getbe()
{
    
    
    while(prog[p]==' '){
    
    
        p++;
    }
}
bool digit(char c)
{
    
    
    if('0'<=c&&c<='9'){
    
    
        return true;
    }
    else{
    
    
        return false;
    }
}
bool letter(char c)
{
    
    
    if(('a'<=c&&c<='z')||('A'<=c&&c<='Z')){
    
    
        return true;
    }
    else{
    
    
        return false;
    }
}
int digitorletter(char c)
{
    
    
    if(letter(c)){
    
    
        return 1;//字母
    }
    if(digit(c)){
    
    
        return 2;//数字
    }
    return 3;//其他
}
bool isReversed(string str)
{
    
    
    for(int j=1;j<=33;j++){
    
    
        if(str==Reversed[j]){
    
    
            cout<<i++<<':'<<' '<<'<'<<Reversed[j]<<','<<j<<'>';
            return true;
        }
    }
    return false;
}
int flag;

void analysis()
{
    
    
    getbe();
    str.clear();
    str+=prog[p];
    flag=1;
    switch(digitorletter(prog[p]))
    {
    
    
        case 1:p++;
            while(digit(prog[p])||letter(prog[p])){
    
    
                str+=prog[p];
                p++;
            }
        p--;//back
        if(isReversed(str)==false){
    
    
            cout<<i++<<':'<<' '<<'<'<<str<<','<<81<<'>';
        }
        break;
        case 2:p++;
            while(digit(prog[p])){
    
    
                str+=prog[p];
                p++;
            }
            p--;
            cout<<i++<<':'<<' '<<'<'<<str<<','<<80<<'>';
            break;
        case 3:switch(prog[p])
        {
    
    
            case'-':p++;
            if(prog[p]=='-'){
    
    
                printf("%d: <--,34>",i++);
            }
            else if(prog[p]=='='){
    
    
                printf("%d: <-=,35>",i++);
            }
            else if(prog[p]=='>'){
    
    
                printf("%d: <->,36>",i++);
            }
            else{
    
    
                p--;//回退
                printf("%d: <-,33>",i++);
            }
            break;
            case'!':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <!=,38>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <!,37>",i++);
            }
            break;
            case'%':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <%=,40>",i++);
            }
            else if(letter(prog[p])){
    
    
                str+=prog[p];
                cout<<i++<<':'<<' '<<'<'<<str<<','<<81<<'>';
            }
            else{
    
    
                p--;
                printf("%d: <%,39>",i++);
            }
            break;
            case'&':p++;
            if(prog[p]=='&'){
    
    
                printf("%d: <&&,42>",i++);
            }
            else if(prog[p]=='='){
    
    
                printf("%d: <&=,43>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <&,41>",i++);
            }
            break;
            case'(':printf("%d: <(,44>",i++);break;
            case'/':p++;
            if(prog[p]=='*'){
    
    
                while(prog[p]!='/'){
    
    
                    str+=prog[p];
                    p++;
                }
                str+=prog[p];
                cout<<i++<<':'<<' '<<'<'<<str<<','<<79<<'>';
            }
            else if(prog[p]=='='){
    
    
                printf("%d: </=,51>",i++);
            }
            else if(prog[p]=='/'){
    
    
                while(prog[p]!='\n'){
    
    
                    str+=prog[p];
                    p++;
                }
                cout<<i++<<':'<<' '<<'<'<<str<<','<<79<<'>';
            }
            else{
    
    
                printf("%d: </,50>",i++);
                p--;
            }
            break;
            case')':printf("%d: <),45>",i++);break;
            case'*':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <*=,47>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <*,46>",i++);
            }
            break;
            case',':printf("%d: <,,48>",i++);break;
            case'.':printf("%d: <.,49>",i++);break;
            case':':printf("%d: <:,52>",i++);break;
            case';':printf("%d: <;,53>",i++);break;
            case'?':printf("%d: <?,54>",i++);break;
            case'[':printf("%d: <[,55>",i++);break;
            case']':printf("%d: <],56>",i++);break;
            case'^':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <^=,58>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <^,57>",i++);
            }
            break;
            case'{':printf("%d: <{,59>",i++);break;
            case'|':p++;
            if(prog[p]=='|'){
    
    
                printf("%d: <||,61>",i++);
            }
            else if(prog[p]=='='){
    
    
                printf("%d: <|=,62>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <|,60>",i++);
            }
            break;
            case'}':printf("%d: <},63>",i++);break;
            case'~':printf("%d: <~,64>",i++);break;
            case'+':p++;
            if(prog[p]=='+'){
    
    
                printf("%d: <++,66>",i++);
            }
            else if(prog[p]=='='){
    
    
                printf("%d: <+=,67>",i++);
            }
            else{
    
    
                printf("%d: <+,65>",i++);
                p--;
            }
            break;
            case'<':p++;
            if(prog[p]=='<'){
    
    
                p++;
                if(prog[p]=='='){
    
    
                    printf("%d: <<<=,70>",i++);
                }
                else{
    
    
                    p--;
                    printf("%d: <<<,69",i++);
                }
            }
            else if(prog[p]=='='){
    
    
                printf("%d: <<=,71",i++);
            }
            else{
    
    
                p--;
                printf("%d: <<,68>",i++);
            }
            break;
            case'=':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <==,73>",i++);
            }
            else{
    
    
                p--;
                printf("%d: <=,72>",i++);
            }
            break;
            case'>':p++;
            if(prog[p]=='='){
    
    
                printf("%d: <>=,75>",i++);
            }
            else if(prog[p]=='>'){
    
    
                p++;
                if(prog[p]=='='){
    
    
                    printf("%d: <>>=,77>",i++);
                }
                else{
    
    
                    p--;
                    printf("%d: <>>,76>",i++);
                }
            }
            else{
    
    
                p--;
                printf("%d: <>,74>",i++);
            }
            break;
            case'\"':printf("%d: <\",78>",i++);break;
            default:flag=0;
        }
    }
}

void Analysis()
{
    
    
	read_prog(prog);
	/* 骚年们 请开始你们的表演 */
    /********* Begin *********/
    p=0;
    i=1;
    while(prog[p]){
    
    
        if(flag==1){
    
    
            printf("\n");
        }
        analysis();

        p++;
    }
    /********* End *********/

}
int main()
{
    
    
    Analysis();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45890608/article/details/111595244