词法分析程序

1.词法分析程序的功能:

词法分析程序的主要功能是从字符流的程序中识别单词,他主要从左至右逐个字符地扫描源程序,因此他还可以完成其他任务。比如,滤掉源程序中的注释和空白(由空格/控制符或回车换行字符引起的空白);又如,为了使编译程序能将发现的错误信息与源程序的出错位置联系起来,词法分析程序负责记录新读入的字符行的行号,以便行号与出错信息相关联;再如,在支持宏处理功能的源程序中,可以由词法分析程序完成其预处理等。

2.符号与种别码对照表:

单词符号

种别码

单词符号

种别码

单词符号

种别码

auto

1

short

21

<=

41

break

2

signed

22

>=

42

case

3

sizeof

23

==

43

char

4

static

24

:=

44

const

5

struct

25

<> 

45

continue

6

switch

26

46

default

7

typedef

27

=>

47

do

8

union

28

=

48

double

9

unsigned

29

:

49

else

10

void

33

+

50

enum

11

include

34

-

51

extern

12

stdio

35

*

52

float

13

string

36

/

53

for

14

main

37

(

54

goto

15

stdlib

38

)

55

if

16

d(number)

40

{

56

int 17

17

l(qita)

100

}

57

long

18

 

 

58

register

19

 

 

.

59

return

20

 

 

 

 

 

3.用文法描述词法规则:

  • <字母> →l
  • <数字> →d
  • <整数常数> →d|d<整数常数>
  • <标识符> →l|l〈字母数字〉
  • <关键字>→l|l〈字母数字〉
  • <运算符> →+|-|*|/|=|〈〈等号〉|〉〈等号〉……
  • <界符> →,|;|(|)|……

其中l表示a~z中的任一英文字母,d表示0~9中的任一数字。

4.已完成的代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char TOken[10];//分开进行比较
char ch;/*char rwtab[6]={"begin","if","then","while","do","end"};*/
char r1[]={"auto"};
char r2[]={"break"};
char r3[]={"case"};
char r4[]={"char"};
char r5[]={"const"};
char r6[]={"continue"};
char r7[]={"default"};
char r8[]={"do"};
char r9[]={"double"};
char r10[]={"else"};
char r11[]={"enum"};
char r12[]={"extern"};
char r13[]={"float"};
char r14[]={"for"};
char r15[]={"goto"};
char r16[]={"if"};
char r17[]={"int"};
char r18[]={"long"};
char r19[]={"register"};
char r20[]={"return"};
char r21[]={"short"};
char r22[]={"signed"};
char r23[]={"sizeof"};
char r24[]={"static"};
char r25[]={"struct"};
char r26[]={"switch"};
char r27[]={"typedef"};
char r28[]={"union"};
char r29[]={"unsigned"};
char r30[]={"void"};
char r31[]={"volatile"};
char r32[]={"while"};
char r33[]={"end"};
char r34[]={"include"};
char r35[]={"stdio"};
char r36[]={"string"};
char r37[]={"main"};
char A[10000];//输入的所有值
int syn,row;
int n,m,p,sum,j;
static int i = 0;
void scaner();
int main()
{
row = 0 ;
p = 0 ;
printf("符号与种别码对照表如下:\n");
printf(" 单词符号 种别码 单词符号 种别码\n");
printf(" auto 1 return 20\n");
printf(" break 2 short 21\n");
printf(" case 3 signed 22\n");
printf(" char 4 sizeof 23\n");
printf(" const 5 static 24\n");
printf(" continue 6 struct 25\n");
printf(" default 7 switch 26\n");
printf(" do 8 typedef 27\n");
printf(" double 9 union 28\n");
printf(" else 10 unsigned 29\n");
printf(" enum 11 void 30\n");
printf(" extern 12 volatile 31\n");
printf(" float 13 while 32\n");
printf(" for 14 end 33\n");
printf(" goto 15 include 34\n");
printf(" if 16 stdio 35\n");
printf(" int 17 string 36\n");
printf(" long 18 main 37\n");
printf(" register 19 @ 0\n\n");
printf("\n 其他均为100。\n\n");
printf(" 请输入您想转换的语句:(输入@结束)\n");
do{
scanf("%c",&ch);
A[p]=ch;
p++;
}while(ch!='@');/*将输入的语句分别存入数组A[]中,@出现时结束语句*/
do
{
scaner();//进入函数进行判定
switch(syn)
{
case 40: printf("(%d,%d)\n",syn,sum); break;//如果是40,那么就是数字
case 0: printf("(%d,%c)\n",syn,TOken[0]);break;//如果是0,那么就是@ 结束
case -2: row=row++;break;
default: printf("(%d,%s)\n",syn,TOken);break;//否则,就是变量名、关键词
}
}
while (syn!=0);

}
void scaner()/*分别对标示符、数字、符号进行分析*/
{
for(n=0;n<7;n++)
TOken[n]=0;/*每次循环完就清零*/
ch=A[i];
while(ch==' '||ch=='\n')/*如果字符是空格或者回车,跳过*/
{
i++;
ch=A[i];
}
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;m++;
i++;ch=A[i];
}
TOken[m]='\0';/*将识别出来的字符和已定义的标示符作比较,输出其种别码*/
if(strcmp(TOken,r1)==0){syn=1;}
else if(strcmp(TOken,r2)==0){syn=2;}
else if(strcmp(TOken,r3)==0){syn=3;}
else if(strcmp(TOken,r4)==0){syn=4;}
else if(strcmp(TOken,r5)==0){syn=5;}
else if(strcmp(TOken,r6)==0){syn=6;}
else if(strcmp(TOken,r7)==0){syn=7;}
else if(strcmp(TOken,r8)==0){syn=8;}
else if(strcmp(TOken,r9)==0){syn=9;}
else if(strcmp(TOken,r10)==0){syn=10;}
else if(strcmp(TOken,r11)==0){syn=11;}
else if(strcmp(TOken,r12)==0){syn=12;}
else if(strcmp(TOken,r13)==0){syn=13;}
else if(strcmp(TOken,r14)==0){syn=14;}
else if(strcmp(TOken,r15)==0){syn=15;}
else if(strcmp(TOken,r16)==0){syn=16;}
else if(strcmp(TOken,r17)==0){syn=17;}
else if(strcmp(TOken,r18)==0){syn=18;}
else if(strcmp(TOken,r19)==0){syn=19;}
else if(strcmp(TOken,r20)==0){syn=20;}
else if(strcmp(TOken,r21)==0){syn=21;}
else if(strcmp(TOken,r22)==0){syn=22;}
else if(strcmp(TOken,r23)==0){syn=23;}
else if(strcmp(TOken,r24)==0){syn=24;}
else if(strcmp(TOken,r25)==0){syn=25;}
else if(strcmp(TOken,r26)==0){syn=26;}
else if(strcmp(TOken,r27)==0){syn=27;}
else if(strcmp(TOken,r28)==0){syn=28;}
else if(strcmp(TOken,r29)==0){syn=29;}
else if(strcmp(TOken,r30)==0){syn=30;}
else if(strcmp(TOken,r31)==0){syn=31;}
else if(strcmp(TOken,r32)==0){syn=32;}
else if(strcmp(TOken,r33)==0){syn=33;}
else if(strcmp(TOken,r34)==0){syn=34;}
else if(strcmp(TOken,r35)==0){syn=35;}
else if(strcmp(TOken,r36)==0){syn=36;}
else if(strcmp(TOken,r37)==0){syn=37;}
else{syn=100;} //变量名
}
else if((ch>='0'&&ch<='9')) //数字
{
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';//显示其数字sum
i++;
ch=A[i];
}
syn=40;
}
else switch(ch) //其他字符
{
case'<':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='=')//<>为22
{
syn=41;
TOken[m]=ch;m++;i++;
}
else{syn=46;}break;
case'>':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='='){
syn=42;
TOken[m]=ch;m++;i++;
}
else{syn=47;}break;
case':':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='=')
{
syn=44;
TOken[m]=ch;m++;i++;
}
else
{
syn=49;
}break;
case'@':syn=0;TOken[0]=ch;i++;break;
case'=':syn=48;TOken[0]=ch;i++;break;
case'#':syn=59;TOken[0]=ch;i++;break;
case'+':syn=50;TOken[0]=ch;i++;break;
case'-':syn=51;TOken[0]=ch;i++;break;
case'*':syn=52;TOken[0]=ch;i++;break;
case'/':syn=53;TOken[0]=ch;i++;break;
case'(':syn=54;TOken[0]=ch;i++;break;
case')':syn=55;TOken[0]=ch;i++;break;
case'{':syn=56;TOken[0]=ch;i++;break;
case'}':syn=57;TOken[0]=ch;i++;break;
case';':syn=58;TOken[0]=ch;i++;break;
case'.':syn=59;TOken[0]=ch;i++;break;
case'\'':syn=60;TOken[0]=ch;i++;break;
default: syn=-1;break;
}
}

posted @ 2016-10-08 03:13  245陈蔓嘉  阅读(274)  评论(0编辑  收藏  举报