词法分析程序的设计与实现
此程序要逐个检查运行情况,并能当场补全代码。
词法分析程序(Lexical Analyzer)要求:
- 从左至右扫描构成源程序的字符流
- 识别出有词法意义的单词(Lexemes)
- 返回单词记录(单词类别,单词本身)
- 滤掉空格
- 跳过注释
- 发现词法错误
程序结构:
输入:字符流(什么输入方式,什么数据结构保存)
处理:
–遍历(什么遍历方式)
–词法规则
输出:单词流(什么输出形式)
–二元组
单词类别:
1.标识符(10)
2.无符号数(11)
3.保留字(一词一码)
4.运算符(一词一码)
5.界符(一词一码)
| 单词符号 | 种别码 | 单词符号 | 种别码 | 
| begin | 1 | : | 17 | 
| if | 2 | := | 18 | 
| then | 3 | < | 20 | 
| while | 4 | <= | 21 | 
| do | 5 | <> | 22 | 
| end | 6 | > | 23 | 
| l(l|d)* | 10 | >= | 24 | 
| dd* | 11 | = | 25 | 
| + | 13 | ; | 26 | 
| - | 14 | ( | 27 | 
| * | 15 | ) | 28 | 
| / | 16 | # | 0 | 
#include<stdio.h>
#include<string.h>
char prog[80],token[8];
char ch;
int syn,p,m=0,n,row,sum=0;
char *rwtab[6]={"begin","if","then","while","do","end"}; //标识符 
 
void scaner()
{
    /*
        共分为三大块,分别是标示符、数字、符号,对应下面的 if   else if  和 else 
        
    
    */ 
    for(n=0;n<8;n++) token[n]=NULL;
    ch=prog[p++];
    while(ch==' ')
    {
        ch=prog[p];
        p++;
    }
    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))  //可能是标示符或者变量名 
    {
        m=0;
        while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
        {
            token[m++]=ch;
            ch=prog[p++];
        }
        token[m++]='\0';
        p--;
        syn=10;
        for(n=0;n<6;n++)  //将识别出来的字符和已定义的标示符作比较, 
            if(strcmp(token,rwtab[n])==0)
            {
                syn=n+1;
                break;
            }
    }
    else if((ch>='0'&&ch<='9'))  //数字 
    {
        {
            sum=0;
            while((ch>='0'&&ch<='9'))
            {
                sum=sum*10+ch-'0';
                ch=prog[p++];
            }
        }
        p--;
        syn=11;
        if(sum>32767)
            syn=-1;
    }
    else switch(ch)   //其他字符 
    {
        case'<':m=0;token[m++]=ch;
            ch=prog[p++];
            if(ch=='>')
            {
                syn=22;
                token[m++]=ch;
            }
            else if(ch=='=')
            {
                syn=21;
                token[m++]=ch;
            }
            else
            {
                syn=20;
                p--;
            }
            break;
        case'>':m=0;token[m++]=ch;
            ch=prog[p++];
            if(ch=='=')
            {
                syn=24;
                token[m++]=ch;
            }
            else
            {
                syn=23;
                p--;
            }
            break;
        case':':m=0;token[m++]=ch;
            ch=prog[p++];
            if(ch=='=')
            {
                syn=18;
                token[m++]=ch;
            }
            else
            {
                syn=17;
                p--;
            }
            break;
        case'+':syn=13;token[0]=ch;break;
        case'-':syn=14;token[0]=ch;break;
        case'*':syn=15;token[0]=ch;break;
        case'/':syn=16;token[0]=ch;break;
        case'=':syn=25;token[0]=ch;break;
        case';':syn=26;token[0]=ch;break;
        case'(':syn=27;token[0]=ch;break;
        case')':syn=28;token[0]=ch;break;
        case'#':syn=0;token[0]=ch;break;
        case'\n':syn=-2;break;
        default: syn=-1;break;
    }
}
 
int main(void)
{
    p=0;
    row=1;
    printf("\n请输入源程序段:");
    do
    {
        ch=getchar();
        prog[p++]=ch;
    }
    while(ch!='#');
    printf("\n(%s)\n",prog);
    p=0;
    do
    {
        scaner();
        switch(syn)
        {
        case 11: printf("(%d,%d)\n",syn,sum); break;  
        case -1: printf("(%Error in row %d)\n",row); break;
        case -2: row=row++;break;
        default: printf("(%s,%d)\n",token,syn);break;
        }
    }
    while (syn!=0);
}


 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号