实验用:

几点注意:

1.代码又长又臭,时间关系,没有优化,冗余项多(我都看不下去了。囧)

2.加了一下简单的错误检测。(在mapping.h中定义了错误类型,可以查阅)

3.使用头文件宏定义来表示单词的各种属性,也可以用文件

4.对于标志符的入口地址,无非是为了唯一识别,只要名字相同,都作为一个,使用自增的Int来模拟入口地址,即唯一标识。不考虑变量类型。

5.最后输出有三个表:Token表,错误表,标志符表。

6.一个字符一个字符的读文件,其实可以每次读到一个固定长度的缓冲区,双缓冲区进行分析。也可以读每一行。

代码:

mapping.h:

[cpp] view plaincopy
  1. /*
  2. 头文件:mapping.h
  3. */
  4. //关键字
  5. #define AUTO 1
  6. #define BREAK 2
  7. #define CASE 3
  8. #define CHAR 4
  9. #define CONST 5
  10. #define CONTINUE 6
  11. #define DEFAULT 7
  12. #define DO 8
  13. #define DOUBLE 9
  14. #define ELSE 10
  15. #define ENUM 11
  16. #define EXTERN 12
  17. #define FLOAT 13
  18. #define FOR 14
  19. #define GOTO 15
  20. #define IF 16
  21. #define INT 17
  22. #define LONG 18
  23. #define REGISTER 19
  24. #define RETURN 20
  25. #define SHORT 21
  26. #define SIGNED 22
  27. #define SIZEOF 23
  28. #define STATIC 24
  29. #define STRUCT 25
  30. #define SWITCH 26
  31. #define TYPEDEF 27
  32. #define UNION 28
  33. #define UNSIGNED 29
  34. #define VOID 30
  35. #define VOLATILE 31
  36. #define WHILE 32
  37. #define KEY_DESC "关键字"
  38. //标志符
  39. #define IDENTIFER 40
  40. #define IDENTIFER_DESC "标志符"
  41. //常量
  42. #define INT_VAL 51 //整形常量
  43. #define CHAR_VAL 52 //字符常量
  44. #define FLOAT_VAL 53 //浮点数常量
  45. #define STRING_VAL 54 //双精度浮点数常量
  46. #define MACRO_VAL 55 //宏常量
  47. #define CONSTANT_DESC "常量"
  48. //运算符
  49. #define NOT 61   // !
  50. #define BYTE_AND 62 //&
  51. #define COMPLEMENT 63 // ~
  52. #define BYTE_XOR  64 // ^
  53. #define MUL 65 // *
  54. #define DIV 66// /
  55. #define MOD 67 // %
  56. #define ADD 68 // +
  57. #define SUB 69 // -
  58. #define LES_THAN 70 // <
  59. #define GRT_THAN 71 // >
  60. #define ASG 72 // =
  61. #define ARROW 73 // ->
  62. #define SELF_ADD 74 // ++
  63. #define SELF_SUB 75 // --
  64. #define LEFT_MOVE 76 // <<
  65. #define RIGHT_MOVE 77 // >>
  66. #define LES_EQUAL 78 // <=
  67. #define GRT_EQUAL 79 // >=
  68. #define EQUAL 80 // ==
  69. #define NOT_EQUAL 81 // !=
  70. #define AND 82 // &&
  71. #define OR 83 // ||
  72. #define COMPLETE_ADD 84 // +=
  73. #define COMPLETE_SUB 85 // -=
  74. #define COMPLETE_MUL 86 // *=
  75. #define COMPLETE_DIV 87 // /=
  76. #define COMPLETE_BYTE_XOR 88 // ^=
  77. #define COMPLETE_BYTE_AND 89 // &=
  78. #define COMPLETE_COMPLEMENT 90 // ~=
  79. #define COMPLETE_MOD 91 //%=
  80. #define BYTE_OR 92 // |
  81. #define OPE_DESC "运算符"
  82. //限界符
  83. #define LEFT_BRA 100 // (
  84. #define RIGHT_BRA 101 // )
  85. #define LEFT_INDEX 102 // [
  86. #define RIGHT_INDEX 103 // ]
  87. #define L_BOUNDER 104 //  {
  88. #define R_BOUNDER 105 // }
  89. #define POINTER 106 // .
  90. #define JING 107 // #
  91. #define UNDER_LINE 108 // _
  92. #define COMMA 109 // ,
  93. #define SEMI 110 // ;
  94. #define SIN_QUE 111 // '
  95. #define DOU_QUE 112 // "
  96. #define CLE_OPE_DESC "限界符"
  97. #define NOTE1 120 // "/**/"注释
  98. #define NOTE2 121 // "//"注释
  99. #define NOTE_DESC "注释"
  100. #define HEADER 130 //头文件
  101. #define HEADER_DESC "头文件"
  102. //错误类型
  103. #define FLOAT_ERROR "float表示错误"
  104. #define FLOAT_ERROR_NUM 1
  105. #define DOUBLE_ERROR "double表示错误"
  106. #define DOUBLE_ERROR_NUM 2
  107. #define NOTE_ERROR "注释没有结束符"
  108. #define NOTE_ERROR_NUM 3
  109. #define STRING_ERROR "字符串常量没有结束符"
  110. #define STRING_ERROR_NUM 4
  111. #define CHARCONST_ERROR "字符常量没有结束符"
  112. #define CHARCONST_ERROR_NUM 5
  113. #define CHAR_ERROR "非法字符"
  114. #define CHAR_ERROR_NUM 6
  115. #define LEFT_BRA_ERROR "'('没有对应项"
  116. #define LEFT_BRA_ERROR_NUM 7
  117. #define RIGHT_BRA_ERROR "')'没有对应项"
  118. #define RIGHT_BRA_ERROR_NUM 8
  119. #define LEFT_INDEX_ERROR "'['没有对应项"
  120. #define LEFT_INDEX_ERROR_NUM 9
  121. #define RIGHT_INDEX_ERROR "']'没有对应项"
  122. #define RIGHT_INDEX_ERROR_NUM 10
  123. #define L_BOUNDER_ERROR "'{'没有对应项"
  124. #define L_BOUNDER_ERROR_NUM 11
  125. #define R_BOUNDER_ERROR "'}'没有对应项"
  126. #define R_BOUNDER_ERROR_NUM 12
  127. #define PRE_PROCESS_ERROR "预处理错误" //头文件或者宏定义错误
  128. #define PRE_PROCESS_ERROR_NUM  13
  129. #define _NULL "无"

main.cpp:

[cpp] view plaincopy
  1. //main.cpp
  2. #include <iostream>
  3. #include <fstream>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <iomanip>
  8. #include "mapping.h"
  9. using namespace std;
  10. const char * key[] = {"auto","break","case","char","const","continue","default","do","double",
  11. "else","enum","extern","float","for","goto","if","int","long","register",
  12. "return","short","signed","sizeof","static","struct","switch","typedef",
  13. "union","unsigned","void","volatile","while"
  14. };//C语言的关键字
  15. int leftSmall = 0;//左小括号
  16. int rightSmall = 0;//右小括号
  17. int leftMiddle = 0;//左中括号
  18. int rightMiddle = 0;//右中括号
  19. int leftBig = 0;//左大括号
  20. int rightBig = 0;//右大括号
  21. int lineBra[6][1000] = {0};//括号和行数的对应关系,第一维代表左右6种括号
  22. int static_iden_number = 0;//模拟标志符的地址,自增
  23. //Token节点
  24. struct NormalNode
  25. {
  26. char content[30];//内容
  27. char describe[30];//描述
  28. int type;//种别码
  29. int addr;//入口地址
  30. int line;//所在行数
  31. NormalNode * next;//下一个节点
  32. };
  33. NormalNode * normalHead;//首结点
  34. //错误节点
  35. struct ErrorNode
  36. {
  37. char content[30];//错误内容
  38. char describe[30];//错误描述
  39. int type;
  40. int line;//所在行数
  41. ErrorNode * next;//下一个节点
  42. };
  43. ErrorNode * errorHead;//首节点
  44. //标志符节点
  45. struct IdentiferNode
  46. {
  47. char content[30];//内容
  48. char describe[30];//描述
  49. int type;//种别码
  50. int addr;//入口地址
  51. int line;//所在行数
  52. IdentiferNode * next;//下一个节点
  53. };
  54. IdentiferNode * idenHead;//首节点
  55. void initNode()
  56. {
  57. normalHead = new NormalNode();
  58. strcpy(normalHead->content,"");
  59. strcpy(normalHead->describe,"");
  60. normalHead->type = -1;
  61. normalHead->addr = -1;
  62. normalHead->line = -1;
  63. normalHead->next = NULL;
  64. errorHead = new ErrorNode();
  65. strcpy(errorHead->content,"");
  66. strcpy(errorHead->describe,"");
  67. errorHead->line = -1;
  68. errorHead->next = NULL;
  69. idenHead = new IdentiferNode();
  70. strcpy(idenHead->content,"");
  71. strcpy(idenHead->describe,"");
  72. idenHead->type = -1;
  73. idenHead->addr = -1;
  74. idenHead->line = -1;
  75. idenHead->next = NULL;
  76. }
  77. void createNewNode(char * content,char *descirbe,int type,int addr,int line)
  78. {
  79. NormalNode * p = normalHead;
  80. NormalNode * temp = new NormalNode();
  81. while(p->next!=NULL)
  82. {
  83. p = p->next;
  84. }
  85. strcpy(temp->content,content);
  86. strcpy(temp->describe,descirbe);
  87. temp->type = type;
  88. temp->addr = addr;
  89. temp->line = line;
  90. temp->next = NULL;
  91. p->next = temp;
  92. }
  93. void createNewError(char * content,char *descirbe,int type,int line)
  94. {
  95. ErrorNode * p = errorHead;
  96. ErrorNode * temp = new ErrorNode();
  97. strcpy(temp->content,content);
  98. strcpy(temp->describe,descirbe);
  99. temp->type = type;
  100. temp->line = line;
  101. temp->next = NULL;
  102. while(p->next!=NULL)
  103. {
  104. p = p->next;
  105. }
  106. p->next = temp;
  107. }
  108. //返回值是新的标志符的入口地址
  109. int createNewIden(char * content,char *descirbe,int type,int addr,int line)
  110. {
  111. IdentiferNode * p = idenHead;
  112. IdentiferNode * temp = new IdentiferNode();
  113. int flag = 0;
  114. int addr_temp = -2;
  115. while(p->next!=NULL)
  116. {
  117. if(strcmp(content,p->next->content) == 0)
  118. {
  119. flag = 1;
  120. addr_temp = p->next->addr;
  121. }
  122. p = p->next;
  123. }
  124. if(flag == 0)
  125. {
  126. addr_temp = ++static_iden_number;//用自增来模拟入口地址
  127. }
  128. strcpy(temp->content,content);
  129. strcpy(temp->describe,descirbe);
  130. temp->type = type;
  131. temp->addr = addr_temp;
  132. temp->line = line;
  133. temp->next = NULL;
  134. p->next = temp;
  135. return addr_temp;
  136. }
  137. void printNodeLink()
  138. {
  139. NormalNode * p = normalHead;
  140. p = p->next;
  141. cout<<"************************************分析表******************************"<<endl<<endl;
  142. cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl;
  143. while(p!=NULL)
  144. {
  145. if(p->type == IDENTIFER)
  146. {
  147. cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl;
  148. }
  149. else
  150. {
  151. cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<"\t"<<p->line<<endl;
  152. }
  153. p = p->next;
  154. }
  155. cout<<endl<<endl;
  156. }
  157. /*
  158. 错误种类:
  159. 1.float表示错误
  160. 2.double表示错误
  161. 3.注释没有结束符
  162. 4.字符串常量没有结束符
  163. 5.字符常量没有结束符
  164. 6.非法字符
  165. 7.'('没有对应项
  166. 8.预处理错误
  167. */
  168. void printErrorLink()
  169. {
  170. ErrorNode * p = errorHead;
  171. p = p->next;
  172. cout<<"************************************错误表******************************"<<endl<<endl;
  173. cout<<setw(10)<<"内容"<<setw(30)<<"描述"<<"\t"<<"类型"<<"\t"<<"行号"<<endl;
  174. while(p!=NULL)
  175. {
  176. cout<<setw(10)<<p->content<<setw(30)<<p->describe<<"\t"<<p->type<<"\t"<<p->line<<endl;
  177. p = p->next;
  178. }
  179. cout<<endl<<endl;
  180. }
  181. //标志符表,有重复部分,暂不考虑
  182. void printIdentLink()
  183. {
  184. IdentiferNode * p = idenHead;
  185. p = p->next;
  186. cout<<"************************************标志符表******************************"<<endl<<endl;
  187. cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl;
  188. while(p!=NULL)
  189. {
  190. cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl;
  191. p = p->next;
  192. }
  193. cout<<endl<<endl;
  194. }
  195. int mystrlen(char * word)
  196. {
  197. if(*word == '\0')
  198. {
  199. return 0;
  200. }
  201. else
  202. {
  203. return 1+mystrlen(word+1);
  204. }
  205. }
  206. //预处理,处理头文件和宏定义
  207. void preProcess(char * word,int line)
  208. {
  209. const char * include_temp = "include";
  210. const char * define_temp = "define";
  211. char * p_include,*p_define;
  212. int flag = 0;
  213. p_include = strstr(word,include_temp);
  214. if(p_include!=NULL)
  215. {
  216. flag = 1;
  217. int i;
  218. for(i=7;;)
  219. {
  220. if(*(p_include+i) == ' ' || *(p_include+i) == '\t')
  221. {
  222. i++;
  223. }
  224. else
  225. {
  226. break;
  227. }
  228. }
  229. createNewNode(p_include+i,HEADER_DESC,HEADER,-1,line);
  230. }
  231. else
  232. {
  233. p_define = strstr(word,define_temp);
  234. if(p_define!=NULL)
  235. {
  236. flag = 1;
  237. int i;
  238. for(i=7;;)
  239. {
  240. if(*(p_define+i) == ' ' || *(p_define+i) == '\t')
  241. {
  242. i++;
  243. }
  244. else
  245. {
  246. break;
  247. }
  248. }
  249. createNewNode(p_define+i,CONSTANT_DESC,MACRO_VAL,-1,line);
  250. }
  251. }
  252. if(flag == 0)
  253. {
  254. createNewError(word,PRE_PROCESS_ERROR,PRE_PROCESS_ERROR_NUM,line);
  255. }
  256. }
  257. void close()
  258. {
  259. delete idenHead;
  260. delete errorHead;
  261. delete normalHead;
  262. }
  263. int seekKey(char * word)
  264. {
  265. for(int i=0; i<32; i++)
  266. {
  267. if(strcmp(word,key[i]) == 0)
  268. {
  269. return i+1;
  270. }
  271. }
  272. return IDENTIFER;
  273. }
  274. void scanner()
  275. {
  276. char filename[30];
  277. char ch;
  278. char array[30];//单词长度上限是30
  279. char * word;
  280. int i;
  281. int line = 1;//行数
  282. FILE * infile;
  283. printf("请输入要进行语法分析的C语言程序:\n");
  284. scanf("%s",filename);
  285. infile = fopen(filename,"r");
  286. while(!infile)
  287. {
  288. printf("打开文件失败!\n");
  289. return;
  290. }
  291. ch = fgetc(infile);
  292. while(ch!=EOF)
  293. {
  294. i = 0;
  295. //以字母或者下划线开头,处理关键字或者标识符
  296. if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || ch == '_')
  297. {
  298. while((ch>='A' && ch<='Z')||(ch>='a' && ch<='z')||(ch>='0' && ch<='9') || ch == '_')
  299. {
  300. array[i++] = ch;
  301. ch = fgetc(infile);
  302. }
  303. word = new char[i+1];
  304. memcpy(word,array,i);
  305. word[i] = '\0';
  306. int seekTemp = seekKey(word);
  307. if(seekTemp!=IDENTIFER)
  308. {
  309. createNewNode(word,KEY_DESC,seekTemp,-1,line);
  310. }
  311. else
  312. {
  313. int addr_tmp = createNewIden(word,IDENTIFER_DESC,seekTemp,-1,line);
  314. createNewNode(word,IDENTIFER_DESC,seekTemp,addr_tmp,line);
  315. }
  316. fseek(infile,-1L,SEEK_CUR);//向后回退一位
  317. }
  318. //以数字开头,处理数字
  319. else if(ch >='0' && ch<='9')
  320. {
  321. int flag = 0;
  322. int flag2 = 0;
  323. //处理整数
  324. while(ch >='0' && ch<='9')
  325. {
  326. array[i++] = ch;
  327. ch = fgetc(infile);
  328. }
  329. //处理float
  330. if(ch == '.')
  331. {
  332. flag2 = 1;
  333. array[i++] = ch;
  334. ch = fgetc(infile);
  335. if(ch>='0' && ch<='9')
  336. {
  337. while(ch>='0' && ch<='9')
  338. {
  339. array[i++] = ch;
  340. ch = fgetc(infile);
  341. }
  342. }
  343. else
  344. {
  345. flag = 1;
  346. }
  347. //处理Double
  348. if(ch == 'E' || ch == 'e')
  349. {
  350. array[i++] = ch;
  351. ch = fgetc(infile);
  352. if(ch == '+' || ch == '-')
  353. {
  354. array[i++] = ch;
  355. ch = fgetc(infile);
  356. }
  357. if(ch >='0' && ch<='9')
  358. {
  359. array[i++] = ch;
  360. ch = fgetc(infile);
  361. }
  362. else
  363. {
  364. flag = 2;
  365. }
  366. }
  367. }
  368. word = new char[i+1];
  369. memcpy(word,array,i);
  370. word[i] = '\0';
  371. if(flag == 1)
  372. {
  373. createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line);
  374. }
  375. else if(flag == 2)
  376. {
  377. createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line);
  378. }
  379. else
  380. {
  381. if(flag2 == 0)
  382. {
  383. createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line);
  384. }
  385. else
  386. {
  387. createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line);
  388. }
  389. }
  390. fseek(infile,-1L,SEEK_CUR);//向后回退一位
  391. }
  392. //以"/"开头
  393. else if(ch == '/')
  394. {
  395. ch = fgetc(infile);
  396. //处理运算符"/="
  397. if(ch == '=')
  398. {
  399. createNewNode("/=",OPE_DESC,COMPLETE_DIV,-1,line);
  400. }
  401. //处理"/**/"型注释
  402. else if(ch == '*')
  403. {
  404. ch =  fgetc(infile);
  405. while(1)
  406. {
  407. while(ch != '*')
  408. {
  409. if(ch == '\n')
  410. {
  411. line++;
  412. }
  413. ch = fgetc(infile);
  414. if(ch == EOF)
  415. {
  416. createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line);
  417. return;
  418. }
  419. }
  420. ch = fgetc(infile);
  421. if(ch == '/')
  422. {
  423. break;
  424. }
  425. if(ch == EOF)
  426. {
  427. createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line);
  428. return;
  429. }
  430. }
  431. createNewNode(_NULL,NOTE_DESC,NOTE1,-1,line);
  432. }
  433. //处理"//"型注释
  434. else if(ch == '/')
  435. {
  436. while(ch!='\n')
  437. {
  438. ch = fgetc(infile);
  439. if(ch == EOF)
  440. {
  441. createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line);
  442. return;
  443. }
  444. }
  445. line++;
  446. createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line);
  447. if(ch == EOF)
  448. {
  449. return;
  450. }
  451. }
  452. //处理除号
  453. else
  454. {
  455. createNewNode("/",OPE_DESC,DIV,-1,line);
  456. }
  457. }
  458. //处理常量字符串
  459. else if(ch == '"')
  460. {
  461. createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line);
  462. ch = fgetc(infile);
  463. i = 0;
  464. while(ch!='"')
  465. {
  466. array[i++] = ch;
  467. if(ch == '\n')
  468. {
  469. line++;
  470. }
  471. ch = fgetc(infile);
  472. if(ch == EOF)
  473. {
  474. createNewError(_NULL,STRING_ERROR,STRING_ERROR_NUM,line);
  475. return;
  476. }
  477. }
  478. word = new char[i+1];
  479. memcpy(word,array,i);
  480. word[i] = '\0';
  481. createNewNode(word,CONSTANT_DESC,STRING_VAL,-1,line);
  482. createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line);
  483. }
  484. //处理常量字符
  485. else if(ch == '\'')
  486. {
  487. createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line);
  488. ch = fgetc(infile);
  489. i = 0;
  490. while(ch!='\'')
  491. {
  492. array[i++] = ch;
  493. if(ch == '\n')
  494. {
  495. line++;
  496. }
  497. ch = fgetc(infile);
  498. if(ch == EOF)
  499. {
  500. createNewError(_NULL,CHARCONST_ERROR,CHARCONST_ERROR_NUM,line);
  501. return;
  502. }
  503. }
  504. word = new char[i+1];
  505. memcpy(word,array,i);
  506. word[i] = '\0';
  507. createNewNode(word,CONSTANT_DESC,CHAR_VAL,-1,line);
  508. createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line);
  509. }
  510. else if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
  511. {
  512. if(ch == '\n')
  513. {
  514. line++;
  515. }
  516. }
  517. else
  518. {
  519. if(ch == EOF)
  520. {
  521. return;
  522. }
  523. //处理头文件和宏常量(预处理)
  524. else if(ch == '#')
  525. {
  526. while(ch!='\n' && ch!=EOF)
  527. {
  528. array[i++] = ch;
  529. ch = fgetc(infile);
  530. }
  531. word = new char[i+1];
  532. memcpy(word,array,i);
  533. word[i] = '\0';
  534. preProcess(word,line);
  535. fseek(infile,-1L,SEEK_CUR);//向后回退一位
  536. }
  537. //处理-开头的运算符
  538. else if(ch == '-')
  539. {
  540. array[i++] = ch;
  541. ch = fgetc(infile);
  542. if(ch >='0' && ch<='9')
  543. {
  544. int flag = 0;
  545. int flag2 = 0;
  546. //处理整数
  547. while(ch>='0' && ch<='9')
  548. {
  549. array[i++] = ch;
  550. ch = fgetc(infile);
  551. }
  552. //处理float
  553. if(ch == '.')
  554. {
  555. flag2 = 1;
  556. array[i++] = ch;
  557. ch = fgetc(infile);
  558. if(ch>='0' && ch<='9')
  559. {
  560. while(ch>='0' && ch<='9')
  561. {
  562. array[i++] = ch;
  563. ch = fgetc(infile);
  564. }
  565. }
  566. else
  567. {
  568. flag = 1;
  569. }
  570. //处理Double
  571. if(ch == 'E' || ch == 'e')
  572. {
  573. array[i++] = ch;
  574. ch = fgetc(infile);
  575. if(ch == '+' || ch == '-')
  576. {
  577. array[i++] = ch;
  578. ch = fgetc(infile);
  579. }
  580. if(ch >='0' && ch<='9')
  581. {
  582. array[i++] = ch;
  583. ch = fgetc(infile);
  584. }
  585. else
  586. {
  587. flag = 2;
  588. }
  589. }
  590. }
  591. word = new char[i+1];
  592. memcpy(word,array,i);
  593. word[i] = '\0';
  594. if(flag == 1)
  595. {
  596. createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line);
  597. }
  598. else if(flag == 2)
  599. {
  600. createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line);
  601. }
  602. else
  603. {
  604. if(flag2 == 0)
  605. {
  606. createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line);
  607. }
  608. else
  609. {
  610. createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line);
  611. }
  612. }
  613. fseek(infile,-1L,SEEK_CUR);//向后回退一位
  614. }
  615. else if(ch == '>')
  616. {
  617. createNewNode("->",OPE_DESC,ARROW,-1,line);
  618. }
  619. else if(ch == '-')
  620. {
  621. createNewNode("--",OPE_DESC,SELF_SUB,-1,line);
  622. }
  623. else if(ch == '=')
  624. {
  625. createNewNode("--",OPE_DESC,SELF_SUB,-1,line);
  626. }
  627. else
  628. {
  629. createNewNode("-",OPE_DESC,SUB,-1,line);
  630. fseek(infile,-1L,SEEK_CUR);
  631. }
  632. }
  633. //处理+开头的运算符
  634. else if(ch == '+')
  635. {
  636. ch = fgetc(infile);
  637. if(ch == '+')
  638. {
  639. createNewNode("++",OPE_DESC,SELF_ADD,-1,line);
  640. }
  641. else if(ch == '=')
  642. {
  643. createNewNode("+=",OPE_DESC,COMPLETE_ADD,-1,line);
  644. }
  645. else
  646. {
  647. createNewNode("+",OPE_DESC,ADD,-1,line);
  648. fseek(infile,-1L,SEEK_CUR);
  649. }
  650. }
  651. //处理*开头的运算符
  652. else if(ch == '*')
  653. {
  654. ch = fgetc(infile);
  655. if(ch == '=')
  656. {
  657. createNewNode("*=",OPE_DESC,COMPLETE_MUL,-1,line);
  658. }
  659. else
  660. {
  661. createNewNode("*",OPE_DESC,MUL,-1,line);
  662. fseek(infile,-1L,SEEK_CUR);
  663. }
  664. }
  665. //处理按^开头的运算符
  666. else if(ch == '^')
  667. {
  668. ch = fgetc(infile);
  669. if(ch == '=')
  670. {
  671. createNewNode("^=",OPE_DESC,COMPLETE_BYTE_XOR,-1,line);
  672. }
  673. else
  674. {
  675. createNewNode("^",OPE_DESC,BYTE_XOR,-1,line);
  676. fseek(infile,-1L,SEEK_CUR);
  677. }
  678. }
  679. //处理%开头的运算符
  680. else if(ch == '%')
  681. {
  682. ch = fgetc(infile);
  683. if(ch == '=')
  684. {
  685. createNewNode("%=",OPE_DESC,COMPLETE_MOD,-1,line);
  686. }
  687. else
  688. {
  689. createNewNode("%",OPE_DESC,MOD,-1,line);
  690. fseek(infile,-1L,SEEK_CUR);
  691. }
  692. }
  693. //处理&开头的运算符
  694. else if(ch == '&')
  695. {
  696. ch = fgetc(infile);
  697. if(ch == '=')
  698. {
  699. createNewNode("&=",OPE_DESC,COMPLETE_BYTE_AND,-1,line);
  700. }
  701. else if(ch == '&')
  702. {
  703. createNewNode("&&",OPE_DESC,AND,-1,line);
  704. }
  705. else
  706. {
  707. createNewNode("&",OPE_DESC,BYTE_AND,-1,line);
  708. fseek(infile,-1L,SEEK_CUR);
  709. }
  710. }
  711. //处理~开头的运算符
  712. else if(ch == '~')
  713. {
  714. ch = fgetc(infile);
  715. if(ch == '=')
  716. {
  717. createNewNode("~=",OPE_DESC,COMPLETE_COMPLEMENT,-1,line);
  718. }
  719. else
  720. {
  721. createNewNode("~",OPE_DESC,COMPLEMENT,-1,line);
  722. fseek(infile,-1L,SEEK_CUR);
  723. }
  724. }
  725. //处理!开头的运算符
  726. else if(ch == '!')
  727. {
  728. ch = fgetc(infile);
  729. if(ch == '=')
  730. {
  731. createNewNode("!=",OPE_DESC,NOT_EQUAL,-1,line);
  732. }
  733. else
  734. {
  735. createNewNode("!",OPE_DESC,NOT,-1,line);
  736. fseek(infile,-1L,SEEK_CUR);
  737. }
  738. }
  739. //处理<开头的运算符
  740. else if(ch == '<')
  741. {
  742. ch = fgetc(infile);
  743. if(ch == '<')
  744. {
  745. createNewNode("<<",OPE_DESC,LEFT_MOVE,-1,line);
  746. }
  747. else if(ch == '=')
  748. {
  749. createNewNode("<=",OPE_DESC,LES_EQUAL,-1,line);
  750. }
  751. else
  752. {
  753. createNewNode("<",OPE_DESC,LES_THAN,-1,line);
  754. fseek(infile,-1L,SEEK_CUR);
  755. }
  756. }
  757. //处理>开头的运算符
  758. else if(ch == '>')
  759. {
  760. ch = fgetc(infile);
  761. if(ch == '>')
  762. {
  763. createNewNode(">>",OPE_DESC,RIGHT_MOVE,-1,line);
  764. }
  765. else if(ch == '=')
  766. {
  767. createNewNode(">=",OPE_DESC,GRT_EQUAL,-1,line);
  768. }
  769. else
  770. {
  771. createNewNode(">",OPE_DESC,GRT_THAN,-1,line);
  772. fseek(infile,-1L,SEEK_CUR);
  773. }
  774. }
  775. //处理|开头的运算符
  776. else if(ch == '|')
  777. {
  778. ch = fgetc(infile);
  779. if(ch == '|')
  780. {
  781. createNewNode("||",OPE_DESC,OR,-1,line);
  782. }
  783. else
  784. {
  785. createNewNode("|",OPE_DESC,BYTE_OR,-1,line);
  786. fseek(infile,-1L,SEEK_CUR);
  787. }
  788. }
  789. else if(ch == '=')
  790. {
  791. ch = fgetc(infile);
  792. if(ch == '=')
  793. {
  794. createNewNode("==",OPE_DESC,EQUAL,-1,line);
  795. }
  796. else
  797. {
  798. createNewNode("=",OPE_DESC,ASG,-1,line);
  799. fseek(infile,-1L,SEEK_CUR);
  800. }
  801. }
  802. else if(ch == '(')
  803. {
  804. leftSmall++;
  805. lineBra[0][leftSmall] = line;
  806. createNewNode("(",CLE_OPE_DESC,LEFT_BRA,-1,line);
  807. }
  808. else if(ch == ')')
  809. {
  810. rightSmall++;
  811. lineBra[1][rightSmall] = line;
  812. createNewNode(")",CLE_OPE_DESC,RIGHT_BRA,-1,line);
  813. }
  814. else if(ch == '[')
  815. {
  816. leftMiddle++;
  817. lineBra[2][leftMiddle] = line;
  818. createNewNode("[",CLE_OPE_DESC,LEFT_INDEX,-1,line);
  819. }
  820. else if(ch == ']')
  821. {
  822. rightMiddle++;
  823. lineBra[3][rightMiddle] = line;
  824. createNewNode("]",CLE_OPE_DESC,RIGHT_INDEX,-1,line);
  825. }
  826. else if(ch == '{')
  827. {
  828. leftBig++;
  829. lineBra[4][leftBig] = line;
  830. createNewNode("{",CLE_OPE_DESC,L_BOUNDER,-1,line);
  831. }
  832. else if(ch == '}')
  833. {
  834. rightBig++;
  835. lineBra[5][rightBig] = line;
  836. createNewNode("}",CLE_OPE_DESC,R_BOUNDER,-1,line);
  837. }
  838. else if(ch == '.')
  839. {
  840. createNewNode(".",CLE_OPE_DESC,POINTER,-1,line);
  841. }
  842. else if(ch == ',')
  843. {
  844. createNewNode(",",CLE_OPE_DESC,COMMA,-1,line);
  845. }
  846. else if(ch == ';')
  847. {
  848. createNewNode(";",CLE_OPE_DESC,SEMI,-1,line);
  849. }
  850. else
  851. {
  852. char temp[2];
  853. temp[0] = ch;
  854. temp[1] = '\0';
  855. createNewError(temp,CHAR_ERROR,CHAR_ERROR_NUM,line);
  856. }
  857. }
  858. ch = fgetc(infile);
  859. }
  860. }
  861. void BraMappingError()
  862. {
  863. if(leftSmall != rightSmall)
  864. {
  865. int i = (leftSmall>rightSmall) ? (leftSmall-rightSmall) : (rightSmall - leftSmall);
  866. bool  flag = (leftSmall>rightSmall) ? true : false;
  867. if(flag)
  868. {
  869. while(i--)
  870. {
  871. createNewError(_NULL,LEFT_BRA_ERROR,LEFT_BRA_ERROR_NUM,lineBra[0][i+1]);
  872. }
  873. }
  874. else
  875. {
  876. while(i--)
  877. {
  878. createNewError(_NULL,RIGHT_BRA_ERROR,RIGHT_BRA_ERROR_NUM,lineBra[1][i+1]);
  879. }
  880. }
  881. }
  882. if(leftMiddle != rightMiddle)
  883. {
  884. int i = (leftMiddle>rightMiddle) ? (leftMiddle-rightMiddle) : (rightMiddle - leftMiddle);
  885. bool flag = (leftMiddle>rightMiddle) ? true : false;
  886. if(flag)
  887. {
  888. while(i--)
  889. {
  890. createNewError(_NULL,LEFT_INDEX_ERROR,LEFT_INDEX_ERROR_NUM,lineBra[2][i+1]);
  891. }
  892. }
  893. else
  894. {
  895. while(i--)
  896. {
  897. createNewError(_NULL,RIGHT_INDEX_ERROR,RIGHT_INDEX_ERROR_NUM,lineBra[3][i+1]);
  898. }
  899. }
  900. }
  901. if(leftBig != rightBig)
  902. {
  903. int i = (leftBig>rightBig) ? (leftBig-rightBig) : (rightBig - leftSmall);
  904. bool flag = (leftBig>rightBig) ? true : false;
  905. if(flag)
  906. {
  907. while(i--)
  908. {
  909. createNewError(_NULL,L_BOUNDER_ERROR,L_BOUNDER_ERROR_NUM,lineBra[4][i+1]);
  910. }
  911. }
  912. else
  913. {
  914. while(i--)
  915. {
  916. createNewError(_NULL,R_BOUNDER_ERROR,R_BOUNDER_ERROR_NUM,lineBra[5][i+1]);
  917. }
  918. }
  919. }
  920. }
  921. int main()
  922. {
  923. initNode();
  924. scanner();
  925. BraMappingError();
  926. printNodeLink();
  927. printErrorLink();
  928. printIdentLink();
  929. close();
  930. return 0;
  931. }

测试的C文件:test.c(一个错误很多的C程序)

[cpp] view plaincopy
  1. #include          <stdio.h>
  2. #include "my.h"
  3. #define max 90
  4. #de some
  5. int char main()
  6. {
  7. 8888char yn;
  8. do
  9. {
  10. int 9801;
  11. float 9.;
  12. double 9.ef;
  13. float -9.876;
  14. double hello.8.9;
  15. float 7.9e-5;
  16. int e-5;
  17. a /= 6;
  18. init(); /*初始化*/
  19. scanner();//扫描源程序//
  20. printf("Are You continue(y/n)\n");
  21. yn=getch();
  22. if(a == 7)
  23. {
  24. }
  25. else
  26. {
  27. }
  28. @
  29. }
  30. while(yn=='y'||yn=='Y');
  31. return 0;
  32. [hello
  33. //
  34. //
  35. //
  36. printf("hello");
  37. /*我是头猪

程序运行结果:

[plain] view plaincopy
  1. 请输入要进行语法分析的C语言程序:
  2. test.c
  3. ************************************分析表******************************
  4. 内容      描述        种别码  地址    行号
  5. <stdio.h>    头文件        130             1
  6. "my.h"    头文件        130             2
  7. max 90      常量        55              3
  8. int    关键字        17              6
  9. char    关键字        4               6
  10. main    标志符        40      1       6
  11. (    限界符        100             6
  12. )    限界符        101             6
  13. {    限界符        104             7
  14. 8888      常量        51              8
  15. char    关键字        4               8
  16. yn    标志符        40      2       8
  17. ;    限界符        110             8
  18. do    关键字        8               9
  19. {    限界符        104             10
  20. int    关键字        17              11
  21. 9801      常量        51              11
  22. ;    限界符        110             11
  23. float    关键字        13              12
  24. ;    限界符        110             12
  25. double    关键字        9               13
  26. f    标志符        40      3       13
  27. ;    限界符        110             13
  28. float    关键字        13              14
  29. -9.876      常量        53              14
  30. ;    限界符        110             14
  31. double    关键字        9               15
  32. hello    标志符        40      4       15
  33. .    限界符        106             15
  34. 8.9      常量        53              15
  35. ;    限界符        110             15
  36. float    关键字        13              16
  37. 7.9e-5      常量        53              16
  38. ;    限界符        110             16
  39. int    关键字        17              17
  40. e    标志符        40      5       17
  41. -5      常量        51              17
  42. ;    限界符        110             17
  43. a    标志符        40      6       18
  44. /=    运算符        87              18
  45. 6      常量        51              18
  46. ;    限界符        110             18
  47. init    标志符        40      7       19
  48. (    限界符        100             19
  49. )    限界符        101             19
  50. ;    限界符        110             19
  51. 无      注释        120             19
  52. scanner    标志符        40      8       20
  53. (    限界符        100             20
  54. )    限界符        101             20
  55. ;    限界符        110             20
  56. 无      注释        121             21
  57. printf    标志符        40      9       21
  58. (    限界符        100             21
  59. "    限界符        112             21
  60. Are You continue(y/n)\n      常量        54              21
  61. "    限界符        112             21
  62. )    限界符        101             21
  63. ;    限界符        110             21
  64. yn    标志符        40      2       22
  65. =    运算符        72              22
  66. getch    标志符        40      10      22
  67. (    限界符        100             22
  68. )    限界符        101             22
  69. ;    限界符        110             22
  70. if    关键字        16              23
  71. (    限界符        100             23
  72. a    标志符        40      6       23
  73. ==    运算符        80              23
  74. 7      常量        51              23
  75. )    限界符        101             23
  76. {    限界符        104             24
  77. }    限界符        105             26
  78. else    关键字        10              27
  79. {    限界符        104             28
  80. }    限界符        105             30
  81. }    限界符        105             33
  82. while    关键字        32              34
  83. (    限界符        100             34
  84. yn    标志符        40      2       34
  85. ==    运算符        80              34
  86. '    限界符        111             34
  87. y      常量        52              34
  88. '    限界符        111             34
  89. ||    运算符        83              34
  90. yn    标志符        40      2       34
  91. ==    运算符        80              34
  92. '    限界符        111             34
  93. Y      常量        52              34
  94. '    限界符        111             34
  95. )    限界符        101             34
  96. ;    限界符        110             34
  97. return    关键字        20              36
  98. 0      常量        51              36
  99. ;    限界符        110             36
  100. [    限界符        102             37
  101. hello    标志符        40      4       37
  102. 无      注释        121             43
  103. 无      注释        121             45
  104. 无      注释        121             46
  105. printf    标志符        40      9       47
  106. (    限界符        100             47
  107. "    限界符        112             47
  108. hello      常量        54              47
  109. "    限界符        112             47
  110. )    限界符        101             47
  111. ;    限界符        110             47
  112. ************************************错误表******************************
  113. 内容                          描述        类型    行号
  114. #de some                    预处理错误        13      4
  115. 9.                 float表示错误        1       12
  116. 9.e                double表示错误        2       13
  117. @                      非法字符        6       31
  118. 无                注释没有结束符        3       49
  119. 无                 '['没有对应项        9       37
  120. 无                 '{'没有对应项        11      7
  121. ************************************标志符表******************************
  122. 内容      描述        种别码  地址    行号
  123. main    标志符        40      1       6
  124. yn    标志符        40      2       8
  125. f    标志符        40      3       13
  126. hello    标志符        40      4       15
  127. e    标志符        40      5       17
  128. a    标志符        40      6       18
  129. init    标志符        40      7       19
  130. scanner    标志符        40      8       20
  131. printf    标志符        40      9       21
  132. yn    标志符        40      2       22
  133. getch    标志符        40      10      22
  134. a    标志符        40      6       23
  135. yn    标志符        40      2       34
  136. yn    标志符        40      2       34
  137. hello    标志符        40      4       37
  138. printf    标志符        40      9       47
  139. Process returned 0 (0x0)   execution time : 5.629 s
  140. Press any key to continue.

C++写的一个简单的词法分析器(分析C语言)相关推荐

  1. 最近写了一个简单的面向对象的脚本语言 Q 语言

    最近写了一个简单的面向对象的脚本语言 Q 语言,语法类似于 Javascript, 加入了一些 python 的语法功能. 同时实现了部分的 Javascript prototype 的功能 (个人觉 ...

  2. easy-mock写的一个简单的模拟二页的反馈

    用easy-mock写的一个简单的模拟二页的反馈,因为后端团队比较传统,所以设计的结构不太规范. 功能:每页10条,共2页,共12条记录,超出参数范围会返错误码: easy模板: {code: fun ...

  3. AndroidSDK开发6我用kotlin协程写了一个简单sdk

    目录 AndroidSDK开发6我用kotlin协程写了一个简单sdk 1.kotlin的依赖和导包如下:(//如果不使用协程可以去掉协程的导包减少sdk包大小) 2.Application代码如下: ...

  4. 用shell脚本写的一个简单的俄罗斯方块

    用shell脚本写的一个简单的俄罗斯方块 代码 代码 测试 下载链接 代码 代码 #!/bin/bash #version 1.2,若非正常退出,请使用附带的killel.sh脚本杀死进程 #定义用于 ...

  5. [基因课学习笔记]一个简单的基因家族分析

    工作背景 探究在芝麻.大豆以及拟南芥中FAD4-like基因家族进化关系,并使其可视化(进化树) 操作环境及软件的准备 虚拟机应用:VMware Workstation pro 17 虚拟机操作系统: ...

  6. 自己写的一个简单的android记事本app

    自己写的一个简单的记事本app,效果如下: 一.首先是第一个界面的编写,最上面是一个TextView,中间是一个Linearlayout中嵌套一个listview布局,最下面是一个button.下面附 ...

  7. 用li写的一个简单的横向导航菜单demo

    用ul li写的一个简单的横向导航菜单,很实用: /* 所有class为menu的div中的ul样式 */ div.menu ul { list-style:none; /* 去掉ul前面的符号 */ ...

  8. python解析器是什么_如何用python写一个简单的词法分析器

    编译原理老师要求写一个java的词法分析器,想了想决定用python写一个. 目标 能识别出变量,数字,运算符,界符和关键字,用excel表打印出来. 有了目标,想想要怎么实现词法分析器. 1.先进行 ...

  9. python写词法分析器_如何用python写一个简单的词法分析器

    编译原理老师要求写一个java的词法分析器,想了想决定用python写一个. 目标 能识别出变量,数字,运算符,界符和关键字,用excel表打印出来. 有了目标,想想要怎么实现词法分析器. 1.先进行 ...

最新文章

  1. 工业相机丢帧现象怎么解决?
  2. 测试眉形的有哪个软件_心理测试:你的眉形是下面的哪种?测你生来命运如何!超准...
  3. SSL 数字证书助力电子商务,让您网络购物更安心
  4. Eclipse导入Spring Boot项目后pom.xml出现红叉的解决办法
  5. 程序员的写作课:三、 海量信息输入指南
  6. OncePerRequestFilter-源码解析
  7. html 自定义字段,HTML 标签自定义属性的问题
  8. 屏幕时代,开发者如何撬动亿级受众,获得用户增长
  9. java mvc jquery weui_WEUI 事件绑定
  10. greenplum客户端工具_GreenPlum数据加载工具gpload | 信春哥,系统稳,闭眼上线不回滚!...
  11. html怎么用excel打开乱码,excel打开是乱码,详细教您excel打开是乱码怎么解决
  12. 算法4(一、递归学习)
  13. python主函数的作用_Python中的main函数解析
  14. 剑客之剑系列续篇:六脉神剑——PyCharm使用宝典
  15. 技术狂潮下的生理性健忘:科技产品如何影响我们的大脑?
  16. 机器学习从入门到创业手记-1.3 必备的工具与框架
  17. CentOS8 编译安装tsar nagios + nagios-plugins + nsca
  18. verilog中always和initial的区别
  19. 蛮力法/01背包问题
  20. 麻省理工科技评论:AI预言的七宗罪(上)

热门文章

  1. 【错误记录】VMware 虚拟机报错 ( VMWare 中的 Ubuntu 虚拟机网络设置 | 第一次网络设置 )
  2. 【Android 插件化】“ 插桩式 “ 插件化框架 ( 注入上下文的使用 )
  3. Shell脚本基本命令4
  4. Js计算时间差(天、小时、分钟、秒)
  5. Cmder命令行工具在Windows系统中的配置
  6. 题解 P4753 【River Jumping】
  7. HDU 4850 Wow! Such String! 【欧拉回路】【一顿乱构造】
  8. Linux服务器通过rz/sz轻松上传下载文件
  9. HTTPS_SSL配置的步骤以及原理说明
  10. 转:socket select模型示例