• 一个IF的词法分析器


    最近在学习编译原理,用图转移算法写了一个IF的词法分析器,本来觉得原理挺简单的,没想到还鼓弄了一天才弄出来,这里把写的代码放这里记录下

    通过myfile.txt输入。输入与输出如下

    输入:

    ifx if iif       if  234

    iff     if 

    输出    第一代表行数,第二个代表开始地址

    代码如下,

      1 #include<stdio.h>
      2 #include<memory.h>
      3 #include<stdlib.h>
      4 
      5 enum kind {IF, ID, NUM};
      6 
      7 typedef struct{
      8     enum kind k;
      9     char lexeme[10];
     10     int line[2];
     11 }token;
     12 
     13 typedef struct ListNode{
     14     token val;
     15     struct ListNode *next;
     16 }node;
     17 
     18 void Printnode(node *head);
     19 void Freenode(node *head);
     20 
     21 // Buildtoken using link to store tokens
     22 node * Buildtoken(node *cur, char *buf, int linenum)
     23 {    
     24     int buf_index = 0;
     25     int lexeme_index = 0;
     26     int status = -1;
     27     //node *head = cur;
     28 
     29     cur->val.line[0] = linenum;
     30     while(buf[buf_index] == ' ')
     31         buf_index++;
     32     cur->val.line[1] = buf_index+1;
     33     
     34 status3:
     35     if(('0' <= buf[buf_index]) && (buf[buf_index] <= '9'))
     36         status = 0;
     37 
     38     if((('A' <= buf[buf_index]) && (buf[buf_index] <= 'Z'))
     39         || ('a' <= buf[buf_index] &&  buf[buf_index] <= 'h') 
     40         || ('j' <= buf[buf_index] && buf[buf_index] <= 'z') )
     41         status = 1;
     42 
     43     if(buf[buf_index] == 'i')
     44         status = 2;
     45 
     46     switch (status)    
     47     {
     48         case 0:
     49             cur->val.k = NUM;
     50             cur->val.lexeme[lexeme_index++] = buf[buf_index++];
     51             while('0' <= buf[buf_index] && buf[buf_index] <= '9')
     52             {
     53                  cur->val.lexeme[lexeme_index++] = buf[buf_index];
     54                 buf_index++;
     55             }
     56             
     57             if((('A' <= buf[buf_index]) && (buf[buf_index] <= 'Z'))
     58                     || ('a' <= buf[buf_index] &&  buf[buf_index] <= 'z'))
     59             {
     60                  cur->val.lexeme[lexeme_index++] = buf[buf_index];
     61                 buf_index++;
     62                 goto status1;
     63             }
     64 
     65             break;
     66         case 1:    
     67     status1: 
     68             cur->val.k = ID;
     69             
     70             while((('A' <= buf[buf_index]) && (buf[buf_index] <= 'Z'))
     71                     || ('a' <= buf[buf_index] &&  buf[buf_index] <= 'z'))
     72             {
     73                  cur->val.lexeme[lexeme_index++] = buf[buf_index];
     74                 buf_index++;
     75             }
     76             goto status2;
     77             break;    
     78         case 2:
     79             cur->val.k = IF;
     80             cur->val.lexeme[lexeme_index++] = buf[buf_index++];
     81             if(buf[buf_index] == 'f')
     82             {
     83                 cur->val.lexeme[lexeme_index++] = buf[buf_index++];
     84             }
     85             if((('A' <= buf[buf_index]) && (buf[buf_index] <= 'Z'))
     86                     || ('a' <= buf[buf_index] &&  buf[buf_index] <= 'z'))
     87                 goto status1; 
     88             goto status2;
     89             break;
     90         default:
     91     status2:
     92             while(buf[buf_index] == ' ')
     93             {
     94                 buf_index++;    
     95             }
     96             if(buf[buf_index] == '
    ' || buf[buf_index] == EOF)
     97             {
     98                 return cur;
     99             }
    100             cur->next = malloc(sizeof(node));
    101             cur = cur->next;
    102             cur->next = NULL;
    103             cur->val.line[0] = linenum;
    104             cur->val.line[1] = buf_index + 1;
    105             lexeme_index = 0;
    106             status = -1;
    107         goto status3;
    108     }
    109     return cur;
    110 }
    111 
    112 //Print nodes 
    113 void Printnode(node *head)
    114 {
    115     node *cur = head;
    116     while(cur != NULL) 
    117     {
    118         switch (cur->val.k)
    119         {
    120             case IF:
    121                 printf("IF (%d, %d)
    ", cur->val.line[0], cur->val.line[1]);
    122                 break;
    123             case ID:
    124                 printf("ID(%s)  (%d, %d)
    ", cur->val.lexeme,cur->val.line[0], cur->val.line[1]);
    125                 break;
    126             case NUM:
    127                 printf("NUM(%s)  (%d, %d)
    ", cur->val.lexeme,cur->val.line[0], cur->val.line[1]);
    128                 break;
    129             default:
    130                 break;
    131         }
    132         cur = cur->next;
    133     }
    134 }
    135 
    136 // because link is used by malloc, this function free these nodes
    137 void Freenode(node *head)
    138 {
    139     node *cur = head;
    140     node *prenode = cur;
    141     while(cur != NULL)
    142     {
    143         prenode = cur;
    144         cur = cur->next;
    145         free(prenode);    
    146     }
    147 }
    148 
    149 int main(void)
    150 {
    151     FILE *pFile;
    152     char buf[100];
    153     int linenum = 1;
    154     node *cur;
    155     node* head = malloc(sizeof(node));    
    156     node *prenode = NULL;
    157 
    158     if(head == NULL)
    159     {
    160         printf("out of memory
    ");
    161         exit(1);
    162     }
    163     cur = head;
    164     cur->next = NULL;
    165     pFile = fopen("myfile.txt", "r");
    166     if(pFile == NULL)
    167         perror("Error opening file");
    168 
    169     // read one line each time
    170     while(fgets(buf, 100, pFile) != NULL)
    171     {
    172         cur = Buildtoken(cur, buf, linenum);
    173         linenum++;
    174         memset(buf, '', 100);
    175         cur->next = malloc(sizeof(node));
    176         prenode = cur;
    177         cur = cur->next;
    178     }
    179 
    180     prenode->next = NULL;
    181     free(prenode);
    182     Printnode(head);
    183     Freenode(head);
    184 
    185     fclose(pFile);
    186 
    187     return 0;
    188 }
  • 相关阅读:
    《剑指offer》— JavaScript(29)最小的K个数
    《剑指offer》— JavaScript(28)数组中出现次数超过一半的数字
    《剑指offer》— JavaScript(27)字符串的排列
    《剑指offer》— JavaScript(26)二叉搜索树与双向链表
    《剑指offer》— JavaScript(25)复杂链表的复制
    【备忘】接口
    【备忘】WPF基础
    UWP-动态磁贴
    UWP-磁贴初识
    【备忘】C#语言基础-2
  • 原文地址:https://www.cnblogs.com/qtalker/p/4529996.html
Copyright © 2020-2023  润新知