|
1 | 1 | %{ |
2 | 2 | #include <stdio.h> |
| 3 | +#include <stdlib.h> |
| 4 | +#include <string.h> |
| 5 | +#define MAX_SIZE 100 |
| 6 | +int wordcount = 0; |
3 | 7 | %} |
| 8 | + |
4 | 9 | letter [A-Za-z] |
5 | 10 | digit [0-9] |
6 | | - |
7 | 11 | // <标识符> → <字母>│<标识符> <数字>│<标识符> <字母> |
8 | 12 | identifier {letter}({letter}|{digit})* |
| 13 | + //整数 |
| 14 | +integer {digit}* |
| 15 | + //字符常数和错误的字符常数 |
| 16 | + //char_num '{letter}*' |
| 17 | +char_const ['][^']*['] |
| 18 | +false_char_const ['][^']* |
| 19 | + //注释和错误的注释 |
| 20 | +comment [/][*].*[*][/] |
| 21 | +false_comment [/][*].* |
9 | 22 | %% |
| 23 | + |
10 | 24 | [ \t\r\a]+ ; // 空白字符 |
11 | 25 | [\n] ; // 换行符 |
| 26 | +and return 1; |
| 27 | +array return 2; |
| 28 | +begin return 3; |
| 29 | +bool return 4; |
| 30 | +call return 5; |
| 31 | +case return 6; |
| 32 | +char return 7; |
| 33 | +constant return 8; |
| 34 | +dim return 9; |
| 35 | +do return 10; |
| 36 | +else return 11; |
| 37 | +end return 12; |
| 38 | +false return 13; |
| 39 | +for return 14; |
| 40 | +if return 15; |
| 41 | +input return 16; |
| 42 | +integer return 17; |
| 43 | +not return 18; |
| 44 | +of return 19; |
| 45 | +or return 20; |
| 46 | +output return 21; |
| 47 | +procedure return 22; |
12 | 48 | program return 23; |
| 49 | +read return 24; |
| 50 | +real return 25; |
| 51 | +repeat return 26; |
| 52 | +set return 27; |
| 53 | +stop return 28; |
| 54 | +then return 29; |
| 55 | +to return 30; |
| 56 | +true return 31; |
| 57 | +until return 32; |
13 | 58 | var return 33; |
14 | | -{identifier} return 36; // 标识符 |
| 59 | +while return 34; |
| 60 | +write return 35; |
| 61 | +"(" return 39; |
| 62 | +")" return 40; |
| 63 | +"*" return 41; |
| 64 | +"*/" return 42; |
| 65 | +"+" return 43; |
15 | 66 | "," return 44; |
| 67 | +"-" return 45; |
| 68 | +"." return 46; |
| 69 | +".." return 47; |
| 70 | +"/" return 48; |
| 71 | +"/*" return 49; |
16 | 72 | ":" return 50; |
| 73 | +":=" return 51; |
17 | 74 | ";" return 52; |
18 | | - /* write you code here */ |
| 75 | +"<" return 53; |
| 76 | +"<=" return 54; |
| 77 | +"<>" return 55; |
| 78 | +"=" return 56; |
| 79 | +">" return 57; |
| 80 | +">=" return 58; |
| 81 | +"[" return 59; |
| 82 | +"]" return 60; |
| 83 | + |
| 84 | +{identifier} { // 标识符 |
| 85 | + //++wordcount; |
| 86 | + return 36; |
| 87 | +} |
| 88 | +{integer} { // 整数 |
| 89 | + //++wordcount; |
| 90 | + return 37; |
| 91 | +} |
| 92 | +{char_const} { //字符常数 |
| 93 | + //++wordcount; |
| 94 | + return 38; |
| 95 | +} |
| 96 | +{false_char_const} { //错误字符常数 |
| 97 | + printf("Wrong Character Constant Format: %s\n", yytext); |
| 98 | + return 300; |
| 99 | +} |
| 100 | +{comment} { // 注释 |
| 101 | + //printf("This is a comment, do not show this: %s\n", yytext); |
| 102 | + return 301; |
| 103 | +} |
| 104 | +{false_comment} { // 错误注释 |
| 105 | + printf("Wrong Comment Format: %s\n", yytext); |
| 106 | + return 302; |
| 107 | +} |
| 108 | +. { //其他非法字符 |
| 109 | + printf("Illegal character: %s\n",yytext); |
| 110 | + return 303; |
| 111 | +} |
19 | 112 |
|
20 | 113 | %% |
| 114 | + |
| 115 | +// 定义键值对的结构体 |
| 116 | +struct KeyValue { |
| 117 | + char key[32]; |
| 118 | + int value; |
| 119 | +}; |
| 120 | + |
| 121 | +// 定义map结构体 |
| 122 | +struct Map { |
| 123 | + struct KeyValue data[MAX_SIZE]; |
| 124 | + int size; |
| 125 | +}; |
| 126 | + |
| 127 | +// 初始化map |
| 128 | +void initMap(struct Map *map) { |
| 129 | + map->size = 0; |
| 130 | +} |
| 131 | + |
| 132 | +// 插入键值对 |
| 133 | +int insert(struct Map *map, const char *key) { |
| 134 | + if (map->size < MAX_SIZE) { |
| 135 | + strcpy(map->data[map->size].key, key); |
| 136 | + map->data[map->size].value = map->size + 1; // 设置值为键值对在map中的位置+1 |
| 137 | + map->size++; |
| 138 | + return map->size - 1; // 返回刚插入的键值对的位置 |
| 139 | + } else { |
| 140 | + printf("Map is full, cannot insert more elements.\n"); |
| 141 | + return -1; |
| 142 | + } |
| 143 | +} |
| 144 | + |
| 145 | +// 查找键对应的值 |
| 146 | +int get(struct Map *map, const char *key) { |
| 147 | + for (int i = 0; i < map->size; i++) { |
| 148 | + if (strcmp(map->data[i].key, key) == 0) { |
| 149 | + return i; // 返回键值对在map中的位置 |
| 150 | + } |
| 151 | + } |
| 152 | + return -1; // 返回-1表示未找到 |
| 153 | +} |
| 154 | + |
| 155 | +// 增加与给定字符串关联的键值对的值 |
| 156 | +void incrementValue(struct Map *map, const char *key) { |
| 157 | + for (int i = 0; i < map->size; i++) { |
| 158 | + if (strcmp(map->data[i].key, key) == 0) { |
| 159 | + map->data[i].value++; |
| 160 | + } |
| 161 | + } |
| 162 | +} |
| 163 | + |
| 164 | + |
| 165 | +// if (map->size < MAX_SIZE) { |
| 166 | +// strcpy(map->data[map->size].key, key); |
| 167 | +// map->data[map->size].value = map->size + 1; // 设置值为键值对在map中的位置+1 |
| 168 | +// map->size++; |
| 169 | +// return map->size - 1; // 返回刚插入的键值对的位置 |
| 170 | +// } else { |
| 171 | +// printf("Map is full, cannot insert more elements.\n"); |
| 172 | +// return -1; |
| 173 | +// } |
| 174 | +// } |
| 175 | +// // 删除键值对 |
| 176 | +// void erase(struct Map *map, const char *key) { |
| 177 | +// for (int i = 0; i < map->size; i++) { |
| 178 | +// if (strcmp(map->data[i].key, key) == 0) { |
| 179 | +// for (int j = i; j < map->size - 1; j++) { |
| 180 | +// map->data[j] = map->data[j + 1]; |
| 181 | +// } |
| 182 | +// map->size--; |
| 183 | +// return; |
| 184 | +// } |
| 185 | +// } |
| 186 | +// } |
| 187 | + |
| 188 | + |
21 | 189 | int main(int argc, char const *argv[]) { |
22 | 190 | int type; |
| 191 | + char filename[64]; |
| 192 | + struct Map map; |
| 193 | + int flag = 0; |
| 194 | + initMap(&map); |
| 195 | + printf("Modified by ■■■, ■■■, ■■■■■■■■■■■■\n"); |
| 196 | + |
| 197 | + printf("Enter the name of the program file: "); //读取文件 |
| 198 | + scanf("%s", filename); |
| 199 | + FILE *file = fopen(filename, "r"); |
| 200 | + if (file == NULL) { |
| 201 | + printf("Error: Cannot open the file %s.\n", filename); |
| 202 | + return 1; |
| 203 | + } |
23 | 204 |
|
| 205 | + yyin = file; |
24 | 206 | while (type = yylex()) { |
25 | | - printf("(%d, '%s')\n", type, yytext); |
| 207 | + if(type <= 9) //为了美观设置的格式化输出 |
| 208 | + { |
| 209 | + printf("( %d, - ) ", type); |
| 210 | + flag++; |
| 211 | + if(flag%5 == 0) |
| 212 | + printf("\n"); |
| 213 | + } |
| 214 | + else if(type == 36 | type == 37 | type == 38) //标识符/整数/字符常数 |
| 215 | + { |
| 216 | + //printf("starting...\n"); |
| 217 | + if(get(&map, yytext) == -1 ) { //判断是新的标识符,加入哈希表 |
| 218 | + wordcount++; |
| 219 | + insert(&map, yytext); |
| 220 | + } |
| 221 | + else { //判断为旧的标识符,将对应的value++ |
| 222 | + incrementValue(&map, yytext); |
| 223 | + } |
| 224 | + printf("(%d, %d ) ", type, get(&map, yytext)+1); |
| 225 | + flag++; |
| 226 | + if(flag%5 == 0) |
| 227 | + printf("\n"); |
| 228 | + } |
| 229 | + else if(type == 300 | type == 301 | type == 302 | type == 303) //抛出错误 |
| 230 | + ; // do nothing |
| 231 | + else |
| 232 | + { |
| 233 | + printf("(%d, - ) ", type); |
| 234 | + flag++; |
| 235 | + if(flag%5 == 0) |
| 236 | + printf("\n"); |
| 237 | + } |
26 | 238 | } |
27 | 239 |
|
| 240 | + fclose(file); //关闭文件 |
28 | 241 | return 0; |
29 | 242 | } |
30 | 243 |
|
|
0 commit comments