词法分析器

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e3+10;

int n;///输入文本的行数
char buffer[MAXN][MAXN];///缓冲区
int len[MAXN];///输入文本每行的列数

struct out///输出格式
{
    string id;
    int val;
    out(){}
    out(string a,int b){id=a;val=b;}
}res[MAXN*MAXN];///输出表
int rescnt;///输出计数器

set<string> cal;///运算符
set<string> key;///关键字+标识符

struct indent///标识符格式
{
    string name;
    int val;
    indent(){}
    indent(string a,int b){name=a;val=b;}
}iden[MAXN*MAXN];///标识符表
int idencnt;///标识符计数器

int num[MAXN*MAXN];///常数表
int numcnt;///常数计数器

void init()
{
    string s[]={"begin", "end" ,"if" ,"then", "while", "do", "const", "var","call","procedure","+", "-", "*","/","odd","=","<>","<",">","<=",">=",":=", "(" , ")" ,"," , "." , ";"};
    string t[]={"+", "-", "*","/","<",">",":","=", "(" , ")" ,"," , "." , ";"};
    for(int i=0;i<27;i++) key.insert(s[i]);
    for(int i=0;i<13;i++) cal.insert(t[i]);
    for(int i=0;i<n;i++) len[i]=strlen(buffer[i]);
}

int dp(char x)
{
    if((x>='A'&&x<='Z')||(x>='a'&&x<='z')) return 1;
    if(x>='0'&&x<='9') return 2;
    char c[]={x,'\0'};string s=c;
    if(cal.count(s)) return 3;
    return 0;
}

int to_int(string s)
{
    int ans=0;
    for(int i=0;i<s.size();i++)
        ans=ans*10+s[i]-'0';
    return ans;
}

void solve()
{
    for(int i=0;i<n;i++)
    {
        int index=0;
        while(index<len[i])
        {
            while(index<len[i]&&(buffer[i][index]==' '||buffer[i][index]=='\t')) index++;
            if(index>=len[i]) break;

            char t[]={buffer[i][index],'\0'}; string sss=t;
            int indexdp=dp(buffer[i][index]);
            index++;

            if(indexdp==1||indexdp==2)
            {
                while(index<len[i]&&dp(buffer[i][index])==indexdp)
                {
                    char tt[]={buffer[i][index],'\0'};
                    sss+=tt;
                    index++;
                }
                if(indexdp==1)
                {
                    if(key.count(sss)) res[rescnt++]=out(sss,-1);
                    else
                    {
                        int j=0;
                        for(;j<idencnt;j++) if(sss==iden[j].name) break;
                        if(j==idencnt) iden[idencnt++]=indent(sss,0);
                        res[rescnt++]=out("id",j);
                    }
                }
                else if(indexdp==2)
                {
                    int j=0,x=to_int(sss);
                    for(;j<numcnt;j++) if(x==num[j]) break;
                    if(j==numcnt) num[numcnt++]=x;
                    res[rescnt++]=out("int",j);
                }
            }
            else if(indexdp==3)
            {
                if(index<len[i]&&dp(buffer[i][index])==indexdp)
                {
                    char tt[]={buffer[i][index],'\0'};
                    string str=tt;
                    index++;
                    if(key.count(sss+str))
                        res[rescnt++]=out(sss+str,-1);
                    else
                    {
                        index--;
                        if(key.count(sss)) res[rescnt++]=out(sss,-1);
                        else ;///异常处理
                    }
                }
                else
                {
                    if(key.count(sss)) res[rescnt++]=out(sss,-1);
                    else ;///异常处理
                }
            }
            else {}///异常处理
        }
    }
}

void cifa()
{
    init();
    solve();
    for(int i=0;i<rescnt;i++)
    {
        cout<<"("<<res[i].id<<",";
        if(res[i].val==-1) cout<<" ";
        else cout<<res[i].val;
        cout<<")"<<endl;
    }
}

int main()
{
    cout<<"请输入源程序,连按两个回车结束"<<endl;
    while(cin.peek()!='\n')
    {
        cin.getline(buffer[n],MAXN);getchar();
        n++;
    }

    cifa();

    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值