词法分析

来源:互联网 发布:手机淘宝二手怎么进去 编辑:程序博客网 时间:2024/05/17 05:58

  词法分析

要求:

编制一个读单词过程,源程序为一个文件,读取该文件,识别出各个具有独立意义的单词,并依次输出各个单词的内部编码及单词符号自身值。

单词的内部编码如下:

1、保留字:mainifintforwhiledoreturnbreakcontinue单词种别码分别为1~9,输出的二元组形式为(单词种别码,0

2、标识符:除保留字外的以字母开头,后跟字母、数字的字符序列单词种别码为20,输出的二元组形式为(单词种别码,标识符的名字);

3、常数为无符号整型数;单词种别码为30,输出的二元组形式为(单词种别码,常数值);

4、运算符包括:+-*/=><>=<===!=;单词种别码为41~51,输出的二元组形式为(单词种别码,0;

5、分隔符包括:,;{}(); 单词种别码为61~66,输出的二元组形式为(单词种别码,0

单词符号

种别码

单词符号

种别码

main

1

/

44

int

2

=

45

if

3

>

46

for

4

<

47

while

5

>=

48

do

6

<=

49

return

7

==

50

break

8

!=

51

continue

9

,

61

ID

20

;

62

NUM

30

{

63

+

41

}

64

-

42

(

65

*

43

)

66

 

 

举例

源程序文件内容如下:

main()

{

int  a, b;

a = 10;

     b = a + 20;

}

要求输出如下:

(10)

(650

(660)

(630)

(20)

 

source code:

#include <stdio.h>
#include<stdlib.h>
#include <ctype.h>
char a[10];//用于存储待识别的标识符或关键字
char *p=a;
void token_scan();
int qiseq(char *p,char *q);

typedef struct token
{
 char *kind;
 int value;
 char *word;
}TOKEN;
TOKEN token[28]=
{
 
 {"1",0,"main"},// main
 {"2",0,"int"},// int
 {"3",0,"if"},// if
 {"4",0,"for"},// for
 {"5",0,"while"},// while 
 {"6",0,"do"},// do
 {"7",0,"return"},// return
 {"8",0,"break"},// break
 {"9",0,"continue"},// continue

 {"20",0},//10 ID
 {"30",0},//11 NUM

 {"41",0,},//12 +
 {"42",0,},//13 -
 {"43",0,},//14 *
 {"44",0,},//15 /
 {"45",0,},//16 = 
 {"46",0,},//17 >
 {"47",0,},//18 <
 {"48",0,},//19 >=
 {"49",0,},//20 <=
 {"50",0,},//21 ==
 {"51",0,},//22 !=
 
 {"61",0,},//23 ,
 {"62",0,},//24 ;
 {"63",0,},//25 {
 {"64",0,},//26 }
 {"65",0,},//27 (
 {"66",0,},//28 )
};


void main()
{
 token_scan();
 getchar();
 
 
}

int qiseq(char *p,char *q)
{
 //u判断两字符串的内容是否相等,若相等返回1,不等返回0
 while(*(p++)!='/0'&&*(q++)!='/0')
 {
      if(*p==*q) continue;
   else
    return 0;
 }
 if(*p!='/0'||*q!='/0') 
  return 0;
 else
  return 1;
}
void token_scan()
{
 //模拟词法分析程序,每次读入一个单词,返回(单词种别,属性值)
  FILE *fp;
 char ch;
 
 int i=0;
 int j=0;
 fp=fopen("file.txt","r");
 if (fp==NULL)
 { printf("cannot open file/n");exit(0);}
ch=fgetc(fp);
while(ch!=EOF)
{
if(isalpha(ch))
{   i=0;
 a[i++]=ch;
 ch=fgetc(fp);
 while(isalnum(ch)||isalpha(ch))
 { a[i++]=ch;ch=fgetc(fp);}
 p=a;
    for(i=0;i<8;i++)
 {
 if(qiseq(p,token[i].word))
 {
   printf("(%s,0)/n",token[i].kind);
  goto loop;
 }
 }
   printf("(20,/"%s/")/n",a);
loop:
   j=0;
 while(a[j]!='/0')
    a[j++]='/0';
}
else if(isdigit(ch))
{  i=0;
 while(isdigit(ch))
{
 if(isdigit(ch))
 {
  a[i++]=ch;ch=fgetc(fp);}
 else break;
}
   printf("(30,%s)/n",a);
   j=0;
   while(a[j]!='/0')
    a[j++]='/0';
}
else
switch(ch)
{
 
case '=':
 ch=fgetc(fp);
 if(ch=='=')
 {
  printf("(%s,%d)/n",token[20].kind,token[20].value);
 ch=fgetc(fp);
 }
 else
 printf("(%s,%d)/n",token[15].kind,token[15].value);
    //ch=fgetc(fp);
 break;
case '+':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[11].kind,token[11].value);
    //ch=fgetc(fp);
 break;
case '-':
 ch=fgetc(fp);
 
 printf("(%s,%d)/n",token[12].kind,token[12].value);
    //ch=fgetc(fp);
 break;
case '(':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[26].kind,token[26].value);
    //ch=fgetc(fp);
 break;
case ')':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[27].kind,token[27].value);
    //ch=fgetc(fp);
 break;
case ',':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[22].kind,token[22].value);
    //ch=fgetc(fp);
 break;
case ';':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[23].kind,token[23].value);
    //ch=fgetc(fp);
 break;
case '{':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[24].kind,token[24].value);
    //ch=fgetc(fp);
 break;
case '}':
 ch=fgetc(fp);
 printf("(%s,%d)/n",token[25].kind,token[25].value);
    //ch=fgetc(fp);
 break;
default:
 
 ch=fgetc(fp);
 
}
}
}

 

原创粉丝点击