词法分析程序(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>
#include <stdlib.h>
void match();  //匹配的方法
char t1[500],t2[500];
char ch;
const char *keyword[6]= {"begin","if","then","while","do","end"};   //存储保留字
int i=0,num,n;
int main() {

    printf("\t\n请输入需要分析的程序:\n");
    ch=getchar();
    while(ch!='#') {
        t1[i]=ch;
        ch=getchar();
        i++;
    }
    
    t1[i]='#';
    i++;
    t1[i]='\0';
    i=0;
    match();
    
    while(num!=0){
        match();
    }
    printf("\n词法分析成功!");
}
void match() {
    ch=t1[i++];
    while(ch==' ') {
        ch=t1[i++];
    }

    if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) {        //判断保留字和字符串 
        n=0;
        num=10;
        char a=ch;
        
        do {
            t2[n++]=ch;
            ch=t1[i++];
        }while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'));     //字符串数组复制
        
        for(n=0; n<6; n++) {
            if(strcmp(t2,keyword[n])==0) {    //判断两个字符串是否一致
                num=n+1;   
                printf("[%s,%d]\n",t2,num);
            }
        }
        
        i--;
        
        if(num==10) {
            ch=a;
            printf("[%c,%d]\n",ch,num);
        }
    }

    if(ch>='0'&&ch<='9') {    //数字判断 
        num=11;
        printf("[%c,%d]\n",ch,num);
    } 
    else { 
        switch(ch) {    //运判断算符界符 
            case '#':num=0;printf("[%c,%d]\n",ch,num);break;
            case '+':num=13;printf("[%c,%d]\n",ch,num);break;
            case '-':num=14;printf("[%c,%d]\n",ch,num);break;
            case '*':num=15;printf("[%c,%d]\n",ch,num);break;
            case '/':num=16;printf("[%c,%d]\n",ch,num);break;
            case ':':
                ch=t1[i++];
                if(ch=='=') {
                    num=18;
                    printf("[:%c,%d]\n",ch,num);
                } 
                else {
                    i--;
                    ch=t1[i];
                    num=17;
                    printf("[%c,%d]\n",ch,num);
                }break;
                
            case '<':
                ch=t1[i++];
                if(ch=='=') {
                    num=21;
                    printf("[<%c,%d]\n",ch,num);
                } else if(ch='>') {
                    num=22;
                    printf("[<%c,%d]\n",ch,num);
                } else {
                    i--;
                    ch=t1[i];
                    num=20;
                    printf("[%c,%d]\n",ch,num);
                }break;
                
            case '>':
                ch=t1[i++];
                if(ch=='=') {
                    num=24;
                    printf("[>%c,%d]\n",ch,num);
                } else {
                    i--;
                    ch=t1[i];
                    num=23;
                    printf("[%c,%d]\n",ch,num);
                }
                break;
            case '=':num=26;printf("[%c,%d]\n",ch,num);break;
            case ';':num=27;printf("[%c,%d]\n",ch,num);break;
            case '(':num=27;printf("[%c,%d]\n",ch,num);break;
            case ')':num=28;printf("[%c,%d]\n",ch,num);break;
        }
    }
}