词法分析程序

时间:2022-06-16 16:56:49

词法分析程序的功能:

输入:源程序字符串。

输出:二元组(单词种别码,单词符号本身)。

单词符号对应的种别码:

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

20

while

4

<=

21

do

5

<> 

22

end

6

23

Letter(letter|digit)

10

>=

24

digit   digit

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

用文法描述词法规则:

 

<字母>G[S]:S->SA

       A->a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|S|Y|Z

<数字> G[S]:S->S

S->0|1|2|3|4|5|6|7|8|9     

  • <整数常数> G[S]:S->S|SA

              S->1|2|3|4|5|6|7|8|9

              A->0|1|2|3|4|5|6|7|8|9

  • <标识符>G[S]:S->D/SN/SD

            D->a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z            N->0|1|2|3|4|5|6|7|8|9

  • <关键字>G[S]:S->S

            S->Const| Dim|As|Mod|And|Or|Not|If|Else|Stop|End|Select|Case|Is|For|To|Step|Byref|Byval|Sub|Function|Exit|Do|Loop|Until|While|Wend|Let|Call|Rem|Integer|Long|Single|Double|Boolean|String|Me| Private|Public

  • <运算符> G[S]:S->S

            S->+|-|*|/|=|#|<|<=|>|>=|:=

  • <界符> G[S]:S->S

                 S->(|),|;|.

 

#include<stdio.h>
#include<string.h>
#include<math.h>
char character[80];//存放所有输入的字符
char token[8];//单词自身字符串
char ch;//单个字符
int sym;//sym:单词种别码
int p,m=0,i,row,sum=0;//sum:整型常数
char*rwtab[6]={"begin","if","then","while","do","end"};
void scanner();
void main()
{
    p=0;
    row=1;
    printf("请输入一串字符串\n");
    do
    {
        ch=getchar();
        character[i++]=ch;
    }while(ch!='#');//输入以#号键结束
p=0;
do
{
  scanner();//识别单词
  switch(sym)
  {
    case 11:printf("(%d,%d)\n",sym,sum);break;
    case -1:printf("error in row %d!\n",row);break;
    case -2:row=row++;break;
    default:printf("(%d,%s)\n",sym,token);break;
  }
}while(sym!=0);
}
void scanner()
{
    for(i=0;i<8;i++)

        token[i]=NULL;
       ch=character[p++];
    while(ch==' ')
    {
        ch=character[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=character[p++];
        }
            token[m++]='\0';
            p--;
            sym=10;
            for(i=0;i<6;i++)  //将识别出来的字符和已定义的标示符作比较,
            if(strcmp(token,rwtab[i])==0)
            {
                sym=i+1;
                break;
            }
    }
    else if((ch>='0'&&ch<='9'))//数字
    {
        sum=0;
        while((ch>='0'&&ch<='9'))
            {
                sum=sum*10+ch-'0';
                ch=character[p++];

            }
            p--;
            sym=11;
            if(sum>32767)
                sym=-1;
    }
    else switch(ch)//其他字符
    {
    case'<':m=0;token[m++]=ch;
        ch=character[p++];
        if(ch=='=')
        {
            sym=21;
            token[m++]=ch;
        }
        else if(ch=='>')
        {
            sym=22;
            token[m++]=ch;
        }
        else
        {
            sym=23;
            p--;
        }
        break;
    case'>':m=0;token[m++]=ch;
       ch=character[p++];
       if(ch=='=')
       {
           sym=24;
           token[m++]=ch;
       }
       else
       {
           sym=20;
           p--;
       }
       break;
    case':':m=0;token[m++]=ch;
       ch=character[p++];
       if(ch=='=')
       {
           sym=18;
           token[m++]=ch;
       }
       else
       {
           sym=17;
           p--;
       }
       break;
        case'*':sym=13;token[0]=ch;break;
        case'/':sym=14;token[0]=ch;break;
        case'+':sym=15;token[0]=ch;break;
        case'-':sym=16;token[0]=ch;break;
        case'=':sym=25;token[0]=ch;break;
        case';':sym=26;token[0]=ch;break;
        case'(':sym=27;token[0]=ch;break;
        case')':sym=28;token[0]=ch;break;
        case'#':sym=0;token[0]=ch;break;
        case'\n':sym=-2;break;
        default:sym=-1;break;

    }

}

词法分析程序