• PL/0 词法分析器


    PL/0 词法分析器

      1 #include<stdio.h>
      2 #include <ctype.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 typedef enum SymEnum
      7 {
      8     Identifier=0, //标识符
      9     Const=1,  //常数
     10     Key=2,    //关键字
     11     Operator=3,   //运算符
     12     Delimiter=4   //界符
     13 } SymEnum;
     14 
     15 char KeyWord[13][15];    //关键字
     16 
     17 void Init()
     18 {
     19     strcpy(&KeyWord[0][0],"begin");
     20     strcpy(&KeyWord[1][0],"call");
     21     strcpy(&KeyWord[2][0],"const");
     22     strcpy(&KeyWord[3][0],"do");
     23     strcpy(&KeyWord[4][0],"end");
     24     strcpy(&KeyWord[5][0],"if");
     25     strcpy(&KeyWord[6][0],"odd");
     26     strcpy(&KeyWord[7][0],"procedure");
     27     strcpy(&KeyWord[8][0],"read");
     28     strcpy(&KeyWord[9][0],"then");
     29     strcpy(&KeyWord[10][0],"var");
     30     strcpy(&KeyWord[11][0],"while");
     31     strcpy(&KeyWord[12][0],"write");
     32 }
     33 
     34 //判断一个单词是否为关键字
     35 int IsKeyWord(char *word)
     36 {
     37     int i=0,j=12;
     38     while(i<=j)
     39     {
     40         int k=(i+j)/2;
     41         if(strcmp(word,KeyWord[k])<=0)
     42             j=k-1;
     43         if(strcmp(word,KeyWord[k])>=0)
     44             i=k+1;
     45     }
     46     return i-1>j ? 1 : 0;
     47 }
     48 
     49 //判断一个单词是否为界符
     50 int IsDelimiter(char word)
     51 {
     52     if(word==','||word==';'||word=='.'||word=='('||word==')')
     53         return 1;
     54     return 0;
     55 }
     56 
     57 //判断一个单词是否为操作符
     58 int IsOperator(char *word)
     59 {
     60     if(word[0]=='+'||word[0]=='-'||word[0]=='*'||word[0]=='/'||word[0]=='<'||word[0]=='>'||strcmp(word,":=")==0||strcmp(word,">=")==0||strcmp(word,"<=")==0||word[0]=='#'||word[0]=='=')
     61         return 1;
     62     return 0;
     63 }
     64 
     65 //判断一个单词是否是常数
     66 int IsConst(char *word)
     67 {
     68     if(word[0]>='0'&&word[0]<='9')
     69         return 1;
     70     return 0;
     71 }
     72 
     73 //判断连个字符是否属于相同类型
     74 int IsSame(char f,char s)
     75 {
     76     int bf = (f>='0'&&f<='9'||f>='a'&&f<='z'||f>='A'&&f<='Z')?  1 : 0 ;
     77     int bs = (s>='0'&&s<='9'||s>='a'&&s<='z'||s>='A'&&s<='Z')?  1 : 0 ;
     78     return bf == bs;
     79 }
     80 
     81 //判断 word 的类型
     82 SymEnum TypeOfWord(char *word)
     83 {
     84     if(IsKeyWord(word))
     85         return Key;
     86     if(IsConst(word))
     87         return Const;
     88     if(IsOperator(word))
     89         return Operator;
     90     return Identifier;
     91 }
     92 
     93 int GetSym()
     94 {
     95     FILE *fp,*fout;
     96     if((fp=fopen("PL0.txt","r"))==NULL || (fout=fopen("source.txt","w+"))==NULL)
     97     {
     98         printf("Open Error!
    ");
     99         exit(0);
    100     }
    101     SymEnum SYM;    //存放每个单词的类别,用内部编码形式表示;
    102     char word[50];  //存储单词
    103     word[0]='';
    104     int len=0;      //单词长度
    105     char ch;
    106     while(fscanf(fp,"%c",&ch)!=EOF)
    107     {
    108         // ch 为空格,回车符,制表符
    109         if(ch==' '||ch=='
    '||ch=='	')
    110         {
    111             // word 不为空
    112             if(len)
    113             {
    114                 //判断单词类型
    115                 SYM=TypeOfWord(word);
    116                 fprintf(fout,"%d %s
    ",SYM,word);
    117                 //清空缓存区
    118                 len=0;
    119                 word[len]='';
    120             }
    121             // word 为空,忽略 ch
    122         }
    123         else if(IsDelimiter(ch))
    124         {
    125             //word 不为空
    126             if(len)
    127             {
    128                 //判断单词的类型
    129                 SYM=TypeOfWord(word);
    130                 fprintf(fout,"%d %s
    ",SYM,word);
    131                 // ch == delimiter
    132                 SYM=Delimiter;
    133                 fprintf(fout,"%d %c
    ",SYM,ch);
    134                 //清空缓存区
    135                 len=0;
    136                 word[len]='';
    137             }
    138             else
    139             {
    140                 //word 为空, ch 为界符
    141                 SYM=Delimiter;
    142                 fprintf(fout,"%d %c
    ",SYM,ch);
    143                 //清空缓存区
    144                 len=0;
    145                 word[len]='';
    146             }
    147         }
    148         else
    149         {
    150             if(len>0)
    151             {
    152                 if(IsSame(word[len-1],ch))
    153                 {
    154                     //判断 word 与 ch 是否同类型
    155                     word[len++]=ch;
    156                     word[len]=''; //字符串终结符
    157                 }
    158                 else
    159                 {
    160                     //判断单词类型
    161                     SYM=TypeOfWord(word);
    162                     fprintf(fout,"%d %s
    ",SYM,word);
    163                     //清空缓存区,并把 ch 放入缓存区
    164                     len=0;
    165                     word[len++]=ch;
    166                     word[len]=''; //字符串终结符
    167                 }
    168             }
    169             else
    170             {
    171                 word[len++]=ch;
    172                 word[len]='';
    173             }
    174         }
    175     }
    176     fclose(fp);
    177     fclose(fout);
    178     return 0;
    179 }
    180 
    181 void PrintToScream()
    182 {
    183     FILE *fp;
    184     if((fp=fopen("source.txt","r+"))==NULL)
    185     {
    186         printf("Open File Error!
    ");
    187         exit(0);
    188     }
    189     int id;
    190     char word[50];
    191     printf("0-标识符 1-常数 2-关键字 3-操作符 4-界符
    ");
    192     while(fscanf(fp,"%d %s",&id,word)!=EOF)
    193     {
    194         printf("(%d,%s)
    ",id,word);
    195     }
    196     fclose(fp);
    197 }
    198 
    199 int main()
    200 {
    201     Init();
    202     GetSym();
    203     PrintToScream();
    204     return 0;
    205 }
  • 相关阅读:
    CF1168B Good Triple 性质分析
    bzoj 4994: [Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组_排序
    BZOJ 3940: [Usaco2015 Feb]Censoring AC自动机+栈
    BZOJ 1691 [Usaco2007 Dec]挑剔的美食家 multiset+排序+贪心
    BZOJ 1725: [Usaco2006 Nov]Corn Fields牧场的安排 状压动归
    BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路 Dijkstra
    BZOJ 1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏 幼儿园测试题
    BZOJ 5508: [Tjoi2019]甲苯先生的字符串 矩阵乘法_思维
    BZOJ 1602: [Usaco2008 Oct]牧场行走 倍增裸题
    描述符get/set/delete,init/new/call,元类
  • 原文地址:https://www.cnblogs.com/SilentCode/p/5414364.html
Copyright © 2020-2023  润新知