一个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] == '\n' || 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)\n", cur->val.line[0], cur->val.line[1]);
122                 break;
123             case ID:
124                 printf("ID(%s)  (%d, %d)\n", cur->val.lexeme,cur->val.line[0], cur->val.line[1]);
125                 break;
126             case NUM:
127                 printf("NUM(%s)  (%d, %d)\n", 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\n");
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, '\0', 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 }

 

posted @ 2015-05-26 10:42  qtalker  阅读(265)  评论(0编辑  收藏  举报