词法分析器

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()
{
    int i,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 document name:");
  scanf("%s",in);
  printf("please input the document name which will be saved:");
  scanf("%s",out);
  printf("please input the aa document name which will be saved:");
  scanf("%s",aa);
  printf("please input the bb document name which will be saved:");
  scanf("%s",bb);
  printf("please input the cc document name which will be saved:");
  scanf("%s",cc);
  if((fpin=fopen(in,"rt"))==NULL)
  {
   printf("\nSource document file can'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);
    }
    else if(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();
    }
    else if(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();
    }
    else if(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();
    }
    else if(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();
    }
    else if(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();
    }
    else if(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 completed successfully!");
}


 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值