词法分析器

来源:互联网 发布:保密电话软件 编辑:程序博客网 时间:2024/05/03 06:22

1 问题描述

对于如下文法所定义的PASCAL语言子集,试编写并上机调试一个词法分析程序:

<程序>→PROGRAM<标识符>;<分程序>.

<分程序>→<变量说明>BEGIN<语句表>END

<变量说明>→VAR<变量表>:<类型>;|<空>

<变量表>→<变量表>,<变量>| <变量>

<类型>→INTEGER

<语句表>→<语句表>;<语句>| <语句>

<语句>→<赋值语句>| <条件语句> |<WHILE语句> |<复合语句> |<过程定义>

<赋值语句>→<变量>:=<算术表达式>

<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>

<WHILE语句>→WHILE<关系表达式>DO<语句>

<复合语句>→BEGIN<语句表>END

<过程定义>→PROCEDURE<标识符><参数表>;

BEGIN<语句表>END

<参数表>→(<标识符表>)|<空>

<标识符表>→<标识符表>,<标识符>| <标识符>

<算术表达式>→<算术表达式>+<项>| <项>

<项>→<项>*<初等量>| <初等量>

<初等量>→(<算术表达式>)|<变量> |<无符号数>

<关系表达式>→<算术表达式><关系符><算术表达式>

<变量>→<标识符>

<标识符>→<标识符><字母>|<标识符><数学>| <字母>

<无符号数>→<无符号数><数字>| <数字>

<关系符>→= | < |<= | > | >= |<>

<字母>→A | B | C | ··· | X | Y |Z

<数字>→0 | 1 | 2 | ··· | 8 | 9

<空>→

要求和提示:

(1)   单词的分类。

可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则采取一词一类。

(2)   符号表的建立。

可事先建立一保留字表,以备在识别保留字时进行查询。变量名表及常数表则在词法分析过程中建立。

(3)   单词串的输出形式。

所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。对于变量标识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串,其最大长度为四个字符;常数表登记项中则存放该整数的二进制形式。)。对于保留字和分隔号,由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。不过,为便于查看由词法分析程序所输出的单词串,也可以在CLASS字段上直接放置单词符号串本身。

2 C源代码

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define num 32
char *keysign[num]={
                     "auto","break","case","char",
      "const","continue","default","do",
      "double","else","enum","extern",
      "float","for","goto","if",
      "int","long","regist","return",
      "short","signed","sizeof","static",
      "struct","switch","typedef","union",
      "unsigned","void","volatile","while"};
FILE *fpin,*fpout,*outa,*outb,*outc;
char token[40];
int j=0;
int lookup()
{
    inti,k=0;
   for(i=0;i<=31;i++)
    {
       if(strcmp(token,keysign[i])==0)
       {
     k=1;
           return(1);
       }
    }
   if(k!=1)
       return(0);
}
void cltoken() 
{
    j=0;
   strcpy(token," ");
}
int scanner(void)
{
  char ch,in[40],out[40];
  char aa[40],bb[40],cc[40];
  int id=0;
  printf("please input the Source documentname:");
  scanf("%s",in);
  printf("please input the document name whichwill be saved:");
  scanf("%s",out);
  printf("please input the aa document name whichwill be saved:");
  scanf("%s",aa);
  printf("please input the bb document name whichwill be saved:");
  scanf("%s",bb);
  printf("please input the cc document name whichwill be saved:");
  scanf("%s",cc);
  if((fpin=fopen(in,"rt"))==NULL)
  {
   printf("\nSource document filecan't be found");
   return(1);
  }
  fpout=fopen(out,"wt");
  outa=fopen(aa,"wt");
  outb=fopen(bb,"wt");
  outc=fopen(cc,"wt");
  ch=fgetc(fpin);
  while(ch!=EOF)
  {
   if(isspace(ch))
   ch=fgetc(fpin);
   else if(isalpha(ch))
   {
   token[j]=ch;
   for(ch=fgetc(fpin);isalnum(ch)||ch=='_';ch=fgetc(fpin))
   token[++j]=ch;
   token[++j]='\0';
   id=lookup();
   printf("%d--->%s\n",id,token);
   fprintf(outa,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
    cltoken(); 
   }
   else if(isdigit(ch))
   {
   token[j]=ch;
   for(ch=fgetc(fpin);isdigit(ch);ch=fgetc(fpin))
   token[++j]=ch;
   token[++j]='\0';
    id=2;
   printf("%d--->%s\n",id,token);
   fprintf(outb,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
   }
   else if(ch=='!' || ch=='{' ||ch=='*' || ch=='/' || ch=='%'|| ch=='}' || ch=='[' ||ch==']'||ch=='(' ||ch==')'|| ch=='?')
    {
    id=3;
    printf("%d--->%c\n",id,ch);
    fprintf(outc,"%d--->%s\n",id,ch);
   fprintf(fpout,"%d--->%c\n",id,ch);
   ch=fgetc(fpin);
    }
    elseif(ch=='=')
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='='){token[++j]=ch;id=4;ch=fgetc(fpin);}
    else id=5;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    elseif(ch=='&')
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='&'){token[++j]=ch;id=6;ch=fgetc(fpin);}
    else id=7;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    elseif(ch=='>') 
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='='){token[++j]=ch;id=8;ch=fgetc(fpin);}
    else id=9;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    elseif(ch=='<') 
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='=') {token[++j]=ch;id=10;}
    else id=11;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    elseif(ch=='+') 
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='+'){token[++j]=ch;id=12;ch=fgetc(fpin);}
    else id=13;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    elseif(ch=='-') 
    {
    token[j]=ch;
    ch=fgetc(fpin);
    if(ch=='-'){token[++j]=ch;id=14;ch=fgetc(fpin);}
    else id=15;
    token[++j]='\0';
    printf("%d--->%s\n",id,token);
    fprintf(outc,"%d--->%s\n",id,token);
   fprintf(fpout,"%d--->%s\n",id,token);
   cltoken();
    }
    else
    {
      token[0]=ch;
      token[1]='\0';
      printf("%d--->%s\n",id,token);
      fprintf(fpout,"%d--->%s\n",id,token);
      ch=fgetc(fpin);
    }
  }
fclose(fpin);
fclose(fpout);
fclose(outa);
fclose(outb);
fclose(outc);
return(1);
}
void main(void)
{
 scanner();
 printf("The lexical analysis has been completedsuccessfully!");
}


 

 

原创粉丝点击