5.词法分析程序的设计与实现
词法分析程序(Lexical Analyzer)要求:
- 从左至右扫描构成源程序的字符流
- 识别出有词法意义的单词(Lexemes)
- 返回单词记录(单词类别,单词本身)
- 滤掉空格
- 跳过注释
- 发现词法错误
程序结构:
输入:字符流(什么输入方式,什么数据结构保存)
处理:
–遍历(什么遍历方式)
–词法规则
输出:单词流(什么输出形式)
–二元组
单词类别:
1.标识符(13)
2.无符号数(10)
3.保留字(一词一码)
4.运算符(11)
5.界符(5)
单词符号 | 种别码 | 单词符号 | 种别码 |
begin | 0 | * | 15 |
call | 1 | / | 16 |
const | 2 | = | 17 |
do | 3 | # | 18 |
end | 4 | < | 19 |
if | 5 | <= | 20 |
odd | 6 | > | 21 |
procedure | 7 | >= | 22 |
read | 8 | := | 23 |
then | 9 | ( | 24 |
var | 10 | ) | 25 |
while | 11 | , | 26 |
write | 12 | ; | 27 |
+ | 13 | , | 28 |
- | 14 | l(l|d)* | 29 |
dd* | 30 |
测试代码:
1 int a=1;
2 int b=2;
3 if(a<b){
4 printf("1");
5 }
6 else{
7 printf("2");
8 }
运行代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #define reserve 13 4 #define operator 11 5 6 FILE* fiar; 7 char ch; //getch读取的字符 8 char id[operator+1]; 9 int num; 10 int sum, length; 11 char line[81]; 12 char a[operator+1]; //读取的符号存在这里 13 char word[reserve][operator]; //保留字13个 14 FILE* fin; 15 FILE* fout; 16 char fname[operator]; //输入的文件名 17 int err; 18 19 #define getchdo if(-1==getch()) return -1; 20 21 void init() { 22 strcpy(&(word[0][0]), "begin"); 23 strcpy(&(word[1][0]), "call"); 24 strcpy(&(word[2][0]), "const"); 25 strcpy(&(word[3][0]), "do"); 26 strcpy(&(word[4][0]), "end"); 27 strcpy(&(word[5][0]), "if"); 28 strcpy(&(word[6][0]), "odd"); 29 strcpy(&(word[7][0]), "procedure"); 30 strcpy(&(word[8][0]), "read"); 31 strcpy(&(word[9][0]), "then"); 32 strcpy(&(word[10][0]), "var"); 33 strcpy(&(word[11][0]), "while"); 34 strcpy(&(word[12][0]), "write"); 35 } 36 37 int getch() { 38 if(sum == length) { 39 if(feof(fin)) { 40 return -1; 41 } 42 length = 0; 43 sum = 0; 44 ch = ' '; 45 while(ch != 10) { 46 if(fscanf(fin, "%c", &ch) == EOF) { 47 line[length] = 0; 48 break; 49 } 50 line[length] = ch; 51 length++; 52 } 53 } 54 ch = line[sum]; 55 sum++; 56 return 0; 57 } 58 59 int getsym() { 60 int i, j, k; 61 while(ch == ' ' || ch == 10 || ch == 9||ch== 13) { 62 getchdo; 63 } 64 if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { 65 k = 0; 66 do { 67 if(k < operator) { 68 a[k] = ch; 69 k++; 70 } 71 getchdo; 72 } while(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9'); 73 a[k] = '\0'; 74 strcpy(id, a); 75 i = 0; 76 j = reserve-1; 77 do { 78 k = (i+j)/2; 79 if(strcmp(id, word[k]) <= 0) 80 j = k-1; 81 if(strcmp(id, word[k]) >= 0) 82 i = k+1; 83 } while(i <= j); 84 85 if(i-1 > j) { 86 printf("3.保 留 字 -- %s\n", id); 87 } else { 88 printf("1.标 识 符 -- %s\n", id); 89 } 90 } else { 91 if(ch >= '0' && ch <= '9') { 92 k = 0; 93 num = 0; 94 do { 95 num = num * 10 + ch - '0'; 96 k++; 97 getchdo; 98 } while(ch >= '0' && ch <= '9'); 99 k--; 100 printf("2.无符号数 -- %d\n",num); 101 } else { 102 if(ch == '=') { 103 printf("4.运 算 符 -- =\n"); 104 getchdo; 105 } else if(ch == ':') { 106 getchdo; 107 if(ch == '=') { 108 printf("4.运 算 符 -- :=\n"); 109 getchdo; 110 } else { 111 } 112 113 } else { 114 if(ch == '<') { 115 getchdo; 116 if(ch == '=') { 117 printf("4.运 算 符 -- <=\n"); 118 getchdo; 119 } else { 120 printf("4.运 算 符 -- <\n"); 121 } 122 } else { 123 if(ch == '>') { 124 getchdo; 125 if(ch == '=') { 126 printf("4.运 算 符 -- >=\n"); 127 getchdo; 128 } else { 129 printf("4.运 算 符 -- >\n"); 130 } 131 } else { 132 if(ch=='+') { 133 printf("4.运 算 符 -- +\n"); 134 getchdo; 135 } else if(ch=='-') { 136 printf("4.运 算 符 -- -\n"); 137 getchdo; 138 } else if(ch=='*') { 139 printf("4.运 算 符 -- *\n"); 140 getchdo; 141 } else if(ch=='/') { 142 printf("4.运 算 符 -- /\n"); 143 getchdo; 144 } else if(ch=='#') { 145 printf("4.运 算 符 -- #\n"); 146 getchdo; 147 } else if(ch=='(') { 148 printf("5.界 符 -- (\n"); 149 getchdo; 150 } else if(ch==')') { 151 printf("5.界 符 -- )\n"); 152 getchdo; 153 } else if(ch==',') { 154 printf("5.界 符 -- ,\n"); 155 getchdo; 156 } else if(ch==';') { 157 printf("5.界 符 -- ;\n"); 158 getchdo; 159 } else if(ch=='.') { 160 printf("5.界 符 -- .\n"); 161 getchdo; 162 } else { 163 getchdo; 164 165 } 166 } 167 } 168 } 169 } 170 } 171 return 0; 172 } 173 174 int main() { 175 printf("文件名: "); 176 scanf("%s", fname); 177 fin = fopen(fname, "r"); 178 if(fin) { 179 init(); 180 printf("\n结果如下:\n\n"); 181 err = 0; 182 sum = length = 0; 183 ch = ' '; 184 while(getsym() != -1) { 185 } 186 } else { 187 printf("文件不存在\n"); 188 } 189 printf("\n"); 190 return 0; 191 }
运行结果:
还未完全实现作业的全部要求。
参考代码来自:https://blog.csdn.net/sinat_37341950/article/details/79565485