递归下降分析法的实现方案

递归下降分析法的原理是利用函数之间的递归调用模拟语法树自上而下的构造过程,具体实现方法概述如下:

1)每个非终结符对应一个解析函数;

2)产生式右侧为该产生式左侧非终结符所对应解析函数的“函数体”;

3)产生式右侧终结符对应从输入串中“消耗”该终结符的操作;

4)产生式中的‘|’对应函数体中的“if-else”语句;

5)对于扩展的BNF文法,产生式中的‘{}’对应函数体中的“while”语句。

说明:

此部分中的数据来源为前一篇(词法分析)的结果


[cpp] ​​ view plain​​ ​​ copy​​



  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.   
  5. #define MAX_ID_LENGTH   256
  6. #define MAX_TABLE_SIZE 2048
  7. #define SUCCESS         1
  8.   
  9. typedef enum
  10. {  
  11.   
  12.     T_0=0,          T_1=1,          T_2=2,          T_INT=3,            T_IF=4,         T_ELSE=5,  
  13.     T_WHILE=6,      T_FOR=7,        T_READ=8,       T_WRITE=9,          T_BEGIN=10,     T_FOUNCTION=11,  
  14.     T_END=12,       T_THEN=13,      T_ADD=14,       T_SUB=15,           T_MUL=16,       T_DIV=17,  
  15.     T_L=18,         T_LE=19,        T_G=20,         T_GE=21,            T_NE=22,        T_E=23,  
  16.     T_ASSIGN=24,    T_LPAR=25,      T_RPAR=26,      T_COM=27,           T_SEM=28,       T_RETURN=29,  
  17.     T_ERROR=30,     T_SYMBOL=31,    T_CONSTANT=32  
  18. } Token;  
  19.   
  20. typedef struct
  21. {  
  22.     Token read;  
  23. struct
  24. size_t
  25. } MYLEX;  
  26.   
  27.   
  28. MYLEX lex_head,error_temp;  
  29. MYLEX* current;  
  30. Token error_TOKEN=T_0;  
  31. /*初始化信息*/
  32.   
  33. /*函数申明*/
  34. int item(void);  
  35. int Block(void);  
  36. int Factor(void);  
  37. int Variable(void);  
  38. int Function(void);  
  39. int Constant(void);  
  40. int Parameter (void
  41. int Identifier (void);  
  42. int Main_Program(void);  
  43. int Function_call(void);  
  44. void emergency_exit(void);  
  45. int Read_statement(void);  
  46. int Write_statement(void);  
  47. int Execute_statement(void);  
  48. MYLEX* Advance(MYLEX* read);  
  49. MYLEX* Read_file(MYLEX* read);  
  50. int Relational_operators(void);  
  51. int Assignment_statement(void);  
  52. int Variable_declaration(void);  
  53. int Function_declaration(void);  
  54. int
  55. int Conditional_statement(void);  
  56. int Arithmetic_expression(void);  
  57. int Declarative_statement(void);  
  58. int Conditional_expression(void);  
  59. int Execute_statement_table(void);  
  60. int
  61. int Declarative_statement_table(void);  
  62.   
  63.   
  64. /*退出*/
  65. void emergency_exit(void)  
  66. {  
  67.     MYLEX* EXIT_TEEMP=lex_head.next;  
  68.     current=EXIT_TEEMP;  
  69. while(!current)  
  70.     {  
  71.         current=EXIT_TEEMP->next;  
  72.         free(EXIT_TEEMP);  
  73.     }  
  74.     exit(0);  
  75. }  
  76.   
  77. /*错误处理*/
  78. int
  79. {  
  80. FILE *error_file=fopen("error.txt","a");  
  81. if(!error_file)  
  82.     {  
  83. "can`t open file \n");  
  84.     }  
  85. if(error_temp.line<current->line)  
  86.     {  
  87.         error_temp=*current;  
  88.         error_TOKEN=aim;  
  89. "error in line:%d\tTOKEN:%d\texpeced Token is :%d\n",  
  90.                 error_temp.line,error_temp.read,error_TOKEN);  
  91.     }  
  92.     fclose(error_file);  
  93. return
  94. }  
  95. //************************************
  96. // Method:    Read_file
  97. // FullName:  Read_file
  98. // Access:    public
  99. // Returns:   int
  100. // Qualifier:读文件
  101. // Parameter: void
  102. //************************************
  103. MYLEX* Read_file(MYLEX* current)  
  104. {  
  105.     current->line=0;  
  106.     current->next=NULL;  
  107.     current->read=T_0;  
  108.   
  109.     MYLEX* Temp;  
  110.     Temp=current;  
  111. FILE* READ_FILE=fopen("GRAMER.txt","r");  
  112. if(!READ_FILE)  
  113.     {  
  114. "can`t load file GRAMER.txt, a file like GRAMER.txt is expectd here \n");  
  115.         exit(0);  
  116.     }  
  117. while(!feof(READ_FILE))  
  118.     {  
  119. sizeof(MYLEX));  
  120.         Temp=Temp->next;  
  121. if(!Temp)  
  122.         {  
  123. "can`t malloc a space for this program!\n");  
  124.             emergency_exit();  
  125.         }  
  126.         Temp->line=0;  
  127.         Temp->next=NULL;  
  128.         Temp->read=T_0;  
  129. "%d\t%d\n",&(Temp->line),&(Temp->read));  
  130.     }  
  131.     fclose(READ_FILE);  
  132. return
  133. }  
  134.   
  135. //************************************
  136. // Method:    Advance
  137. // FullName:  Advance
  138. // Access:    public
  139. // Returns:   Token
  140. // Qualifier:   前进移向下一个TOKEN
  141. // Parameter: void
  142. //************************************
  143. MYLEX* Advance(MYLEX* current)  
  144. {  
  145. FILE*EAT_FILE=fopen("symtab2.txt","a");  
  146. FILE* LEFT_FILE=fopen("detail.txt","a");  
  147. if((!EAT_FILE)||(!LEFT_FILE))  
  148.     {  
  149. "can`t open file");  
  150.         emergency_exit();  
  151.     }  
  152.     MYLEX* Temp=current->next;  
  153. "you have eat the one is :%3d\n\n follow is \n",current->read);  
  154.     fprintf(EAT_FILE,  
  155. "\nyou have eat the one is line:%3d\tToken:%3d\n",  
  156.             current->line,current->read);  
  157.     fprintf(LEFT_FILE,  
  158. "\n\ncurrent eat the one is line:%3d\tToken:%3d\nfollow is\n",  
  159.             current->line,current->read);  
  160. for(Temp; Temp!=NULL; Temp=Temp->next)  
  161.     {  
  162. "line:%3d \t token=%3d\n",  
  163.                Temp->line,Temp->read);  
  164. "line:%3d \t token=%3d\n",  
  165.                 Temp->line,Temp->read);  
  166.     }  
  167.     fclose(EAT_FILE);  
  168.     fclose(LEFT_FILE);  
  169. if(current==NULL)  
  170.     {  
  171. "all work is to be done!,there is an error in your project!\n ");  
  172.         emergency_exit();  
  173.     }  
  174. return
  175. }  
  176.   
  177. //************************************
  178. // Method:    main
  179. // FullName:  main
  180. // Access:    public
  181. // Returns:   int
  182. // Qualifier:   主程序
  183. // Parameter: int agrc
  184. // Parameter: char * agrv[]
  185. //************************************
  186. int main(int agrc, char*agrv[])  
  187. {  
  188.     error_temp.line=0;  
  189.     error_temp.next=NULL;  
  190.     error_temp.read=T_0;  
  191.   
  192. "\t编译原理实验二\n\tXXXXXXXXX\n\t\t—NEWPLAN\n");  
  193.     current=Read_file(&lex_head);  
  194. "pause");  
  195.   
  196. if(Main_Program())  
  197.     {  
  198. "\n\ncongratulation\tsuccessfully!\n\n");  
  199. "del error.txt");  
  200.     }  
  201. else
  202.     {  
  203. " sorry you have failed!\n");  
  204. "error in line:%d\tTOKEN:%d\texpeced Token is :%d\n",  
  205.                error_temp.line,error_temp.read,error_TOKEN);  
  206.     }  
  207. "pause");  
  208.     emergency_exit();/*释放空间,函数返回*/  
  209. return
  210. }  
  211.   
  212. //************************************
  213. // Method:    match
  214. // FullName:  match
  215. // Access:    public
  216. // Returns:   int
  217. // Qualifier:   匹配
  218. // Parameter: Token read
  219. // Parameter: Token aim
  220. //************************************
  221. int
  222. {  
  223. return
  224. }  
  225.   
  226. //************************************
  227. // Method:    Main_Program
  228. // FullName:  Main_Program
  229. // Access:    public
  230. // Returns:   int
  231. // Qualifier:   开始主程序
  232. // Parameter: void
  233. //************************************
  234. int Main_Program(void)  
  235. {  
  236. return
  237. }  
  238.   
  239. //************************************
  240. // Method:    Block
  241. // FullName:  Block
  242. // Access:    public
  243. // Returns:   int
  244. // Qualifier:/*分程序*/
  245. // Parameter: Token read
  246. //************************************
  247. int Block(void)  
  248. {  
  249.     MYLEX* Temp=current;  
  250. return
  251.             Execute_statement_table()&&match(current->read,T_END))?SUCCESS:(current=Temp,!SUCCESS);  
  252. }  
  253.   
  254.   
  255. //************************************
  256. // Method:    Declarative_statement_table
  257. // FullName:  Declarative_statement_table
  258. // Access:    public
  259. // Returns:   int
  260. // Qualifier:/*说明语句表*/
  261. // Parameter: Token read
  262. //************************************
  263. int
  264. {  
  265.     MYLEX* Temp=current;  
  266. if(!Declarative_statement())  
  267.     {  
  268.         current=Temp;  
  269. return
  270.     }  
  271.     /*采用扩展的BNF方法消除左递归*/  
  272. for(;;)  
  273.     {  
  274.         Temp=current;  
  275. if(!match(current->read,T_SEM))  
  276. break;  
  277. if(!Declarative_statement())  
  278.         {  
  279.             current=Temp;  
  280. break;  
  281.         }  
  282.     }  
  283. return
  284. }  
  285.   
  286.   
  287. //************************************
  288. // Method:    Declarative_statement
  289. // FullName:  Declarative_statement
  290. // Access:    public
  291. // Returns:   int
  292. // Qualifier:/*说明语句*/
  293. // Parameter: Token read
  294. //************************************
  295. int Declarative_statement(void)  
  296. {  
  297.     MYLEX* Temp=current;  
  298. return
  299.            (current=Temp,Function_declaration()? SUCCESS:!SUCCESS);  
  300. }  
  301.   
  302.   
  303. //************************************
  304. // Method:    Execute_statement_table
  305. // FullName:  Execute_statement_table
  306. // Access:    public
  307. // Returns:   int
  308. // Qualifier:/*执行语句表*/
  309. // Parameter: Token read
  310. //************************************
  311. int Execute_statement_table(void)  
  312. {  
  313.     MYLEX* Temp=current;  
  314. if(!Execute_statement())  
  315.     {  
  316.         current=Temp;  
  317. return
  318.     }  
  319. for(;;)  
  320.     {  
  321.         Temp=current;  
  322. if(!match(current->read,T_SEM))  
  323. break;  
  324. if(!Execute_statement())  
  325.         {  
  326.             current=Temp;  
  327. break;  
  328.         }  
  329.     }  
  330. return
  331. }  
  332.   
  333.   
  334. //************************************
  335. // Method:    Execute_statement
  336. // FullName:  Execute_statement
  337. // Access:    public
  338. // Returns:   int
  339. // Qualifier:/*执行语句*/
  340. // Parameter: Token read
  341. //************************************
  342. int Execute_statement(void)  
  343. {  
  344.     MYLEX* Temp=current;  
  345. if(Read_statement())  
  346. return
  347.     current=Temp;  
  348. if(Write_statement())  
  349. return
  350.     current=Temp;  
  351. if(Conditional_statement())  
  352. return
  353.     current=Temp;  
  354. if(Assignment_statement())  
  355. return
  356.     current=Temp;  
  357. return
  358. }  
  359.   
  360.   
  361. //************************************
  362. // Method:    Variable_declaration
  363. // FullName:  Variable_declaration
  364. // Access:    public
  365. // Returns:   int
  366. // Qualifier:/*变量说明*/
  367. // Parameter: Token read
  368. //************************************
  369. int Variable_declaration(void)  
  370. {  
  371.     MYLEX* Temp=current;  
  372. return
  373. }  
  374.   
  375.   
  376. //************************************
  377. // Method:    Function_declaration
  378. // FullName:  Function_declaration
  379. // Access:    public
  380. // Returns:   int
  381. // Qualifier:/*函数说明*/
  382. // Parameter: Token read
  383. //************************************
  384. int Function_declaration(void)  
  385. {  
  386.     MYLEX* Temp=current;  
  387. return
  388.             match(current->read, T_LPAR)&&Parameter()&&match(current->read, T_RPAR)&&  
  389.             match(current->read,T_SEM)&&Function())? SUCCESS:(current=Temp,!SUCCESS);  
  390. }  
  391.   
  392.   
  393. //************************************
  394. // Method:    Variable
  395. // FullName:  Variable
  396. // Access:    public
  397. // Returns:   int
  398. // Qualifier:/*变量*/
  399. // Parameter: Token read
  400. //************************************
  401. int Variable(void)  
  402. {  
  403. return
  404. }  
  405.   
  406. //************************************
  407. // Method:    Identifier
  408. // FullName:  Identifier
  409. // Access:    public
  410. // Returns:   int
  411. // Qualifier:/*标识符*/
  412. // Parameter: Token read
  413. //************************************
  414. int Identifier  (void)  
  415. {  
  416. return
  417. }  
  418.   
  419.   
  420. //************************************
  421. // Method:    Parameter
  422. // FullName:  Parameter
  423. // Access:    public
  424. // Returns:   int
  425. // Qualifier:/*参数*/
  426. // Parameter: Token read
  427. //************************************
  428. int Parameter  (void)  
  429. {  
  430.     MYLEX* Temp=current;  
  431. return
  432. }  
  433.   
  434.   
  435. //************************************
  436. // Method:    Function
  437. // FullName:  Function
  438. // Access:    public
  439. // Returns:   int
  440. // Qualifier:/*函数体*/
  441. // Parameter: Token read
  442. //************************************
  443. int Function(void)  
  444. {  
  445.     MYLEX* Temp=current;  
  446. return
  447.             Execute_statement_table()&&match(current->read,T_END))?SUCCESS:(current=Temp,!SUCCESS);  
  448. }  
  449.   
  450.   
  451. //************************************
  452. // Method:    Read_statement
  453. // FullName:  Read_statement
  454. // Access:    public
  455. // Returns:   int
  456. // Qualifier:/*读语句*/
  457. // Parameter: Token read
  458. //************************************
  459. int Read_statement(void)  
  460. {  
  461.     MYLEX* Temp=current;  
  462. return
  463.             match(current->read,T_RPAR))?SUCCESS:(current=Temp,!SUCCESS);  
  464. }  
  465.   
  466.   
  467. //************************************
  468. // Method:    Write_statement
  469. // FullName:  Write_statement
  470. // Access:    public
  471. // Returns:   int
  472. // Qualifier:/*写语句*/
  473. // Parameter: Token read
  474. //************************************
  475. int Write_statement(void)  
  476. {  
  477.     MYLEX* Temp=current;  
  478. return
  479.             match(current->read,T_RPAR))?SUCCESS:(current=Temp,!SUCCESS);  
  480. }  
  481.   
  482.   
  483. //************************************
  484. // Method:    Assignment_statement
  485. // FullName:  Assignment_statement
  486. // Access:    public
  487. // Returns:   int
  488. // Qualifier:/*赋值语句*/
  489. // Parameter: Token read
  490. //************************************
  491. int Assignment_statement(void)  
  492. {  
  493.     MYLEX* Temp=current;  
  494. return
  495.             Arithmetic_expression())? SUCCESS:(current=Temp,!SUCCESS);  
  496. }  
  497.   
  498. //************************************
  499. // Method:    Conditional_statement
  500. // FullName:  Conditional_statement
  501. // Access:    public
  502. // Returns:   int
  503. // Qualifier:/*条件语句*/
  504. // Parameter: Token read
  505. //************************************
  506. int Conditional_statement(void)  
  507. {  
  508.     MYLEX* Temp=current;  
  509. return
  510.             match(current->read,T_THEN)&&Execute_statement()&&  
  511.             match(current->read,T_ELSE)&&Execute_statement()  
  512.            )?SUCCESS:(current=Temp,!SUCCESS);  
  513. }  
  514.   
  515. //************************************
  516. // Method:    Arithmetic_expression
  517. // FullName:  Arithmetic_expression
  518. // Access:    public
  519. // Returns:   int
  520. // Qualifier:/*算术表达式*/
  521. // Parameter: Token read
  522. //************************************
  523. int Arithmetic_expression(void)  
  524. {  
  525.     MYLEX* Temp=current;  
  526. if(!item())  
  527.     {  
  528.         current=Temp;  
  529. return
  530.     }  
  531. for(;;)  
  532.     {  
  533.         Temp=current;  
  534. if(!match(current->read,T_SUB))  
  535. break;  
  536. if(!item())  
  537.         {  
  538.             current=Temp;  
  539. break;  
  540.         }  
  541.     }  
  542. return
  543. }  
  544.   
  545. //************************************
  546. // Method:    item
  547. // FullName:  item
  548. // Access:    public
  549. // Returns:   int
  550. // Qualifier:/*项*/
  551. // Parameter: Token read
  552. //************************************
  553. int item(void)  
  554. {  
  555.     MYLEX* Temp=current;  
  556. if(!Factor())  
  557.     {  
  558.         current=Temp;  
  559. return
  560.     }  
  561. for(;;)  
  562.     {  
  563.         Temp=current;  
  564. if(!match(current->read,T_MUL))  
  565. break;  
  566. if(!Factor())  
  567.         {  
  568.             current=Temp;  
  569. break;  
  570.         }  
  571.     }  
  572. return
  573. }  
  574.   
  575. //************************************
  576. // Method:    Constant
  577. // FullName:  Constant
  578. // Access:    public
  579. // Returns:   int
  580. // Qualifier:/*常数*/
  581. // Parameter: Token read
  582. //************************************
  583. int Constant(void)  
  584. {  
  585. return
  586. }  
  587.   
  588. //************************************
  589. // Method:    Conditional_expression
  590. // FullName:  Conditional_expression
  591. // Access:    public
  592. // Returns:   int
  593. // Qualifier:/*条件表达式*/
  594. // Parameter: Token read
  595. //************************************
  596. int Conditional_expression(void)  
  597. {  
  598.     MYLEX* Temp=current;  
  599. return
  600.             Arithmetic_expression())? SUCCESS:(current=Temp,!SUCCESS);  
  601. }  
  602.   
  603. //************************************
  604. // Method:    Relational_operators
  605. // FullName:  Relational_operators
  606. // Access:    public
  607. // Returns:   int
  608. // Qualifier:/*关系运算符*/
  609. // Parameter: Token read
  610. //************************************
  611. int Relational_operators(void)  
  612. {  
  613. return
  614.              match(current->read,T_GE)||match(current->read,T_E)||match(current->read,T_NE)  
  615.            )?SUCCESS:!SUCCESS;  
  616.   
  617. }  
  618.   
  619.   
  620. //************************************
  621. // Method:    Factor
  622. // FullName:  Factor
  623. // Access:    public
  624. // Returns:   int
  625. // Qualifier:/*因子*/
  626. // Parameter: Token read
  627. //************************************
  628. int Factor(void)  
  629. {  
  630.     MYLEX* Temp=current;  
  631. if(Function_call())  
  632. return
  633.     current=Temp;  
  634. if(Variable())  
  635. return
  636.     current=Temp;  
  637. if(Constant())  
  638. return
  639.     current=Temp;  
  640. return
  641. }  
  642.   
  643. //************************************
  644. // Method:    Function_call
  645. // FullName:  Function_call
  646. // Access:    public
  647. // Returns:   int
  648. // Qualifier:/*函数调用*/
  649. // Parameter: Token read
  650. //************************************
  651. int Function_call(void)  
  652. {  
  653.     MYLEX* Temp=current;  
  654. return
  655.             match(current->read,T_RPAR))?SUCCESS:(current=Temp,!SUCCESS);  
  656. }  



源码版本2(更容易理解)

[cpp] ​​ view plain​​ ​​ copy​​



  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.   
  5. #define MAX_ID_LENGTH   256
  6. #define MAX_TABLE_SIZE 2048
  7. #define SUCCESS         1
  8.   
  9. typedef enum
  10. {  
  11.   
  12.     T_0=0,  
  13.     T_1=1,  
  14.     T_2=2,  
  15.   
  16.     T_INT=3,  
  17.     T_IF=4,  
  18.     T_ELSE=5,  
  19.     T_WHILE=6,  
  20.     T_FOR=7,  
  21.     T_READ=8,  
  22.     T_WRITE=9,  
  23.     T_BEGIN=10,  
  24.     T_FOUNCTION=11,  
  25.     T_END=12,  
  26.     T_THEN=13,  
  27.   
  28.     T_ADD=14,  
  29.     T_SUB=15,  
  30.     T_MUL=16,  
  31.     T_DIV=17,  
  32.     T_L=18,  
  33.     T_LE=19,  
  34.     T_G=20,  
  35.     T_GE=21,  
  36.     T_NE=22,  
  37.     T_E=23,  
  38.     T_ASSIGN=24,  
  39.     T_LPAR=25,  
  40.     T_RPAR=26,  
  41.     T_COM=27,  
  42.     T_SEM=28,  
  43.   
  44.     T_RETURN=29,  
  45.     T_ERROR=30,  
  46.     T_SYMBOL=31,  
  47.     T_CONSTANT=32  
  48. } Token;  
  49.   
  50. typedef struct
  51. {  
  52.     Token read;  
  53. struct
  54. size_t
  55. }MYLEX;  
  56.   
  57.   
  58. #ifndef SUCCESS
  59. #define SUCCESS   1
  60. #endif
  61.   
  62. MYLEX lex_head,error_temp;  
  63. MYLEX* current;  
  64. Token error_TOKEN=T_0;  
  65. /*初始化信息*/
  66.   
  67. /*函数申明*/
  68. int item(void);  
  69. int Block(void);  
  70. int Factor(void);  
  71. int Variable(void);  
  72. int Function(void);  
  73. int Constant(void);  
  74. int Parameter (void
  75. int Identifier (void);  
  76. int Main_Program(void);  
  77. int Function_call(void);  
  78. void emergency_exit(void);  
  79. int Read_statement(void);  
  80. int Write_statement(void);  
  81. int Execute_statement(void);  
  82. MYLEX* Advance(MYLEX* read);  
  83. MYLEX* Read_file(MYLEX* read);  
  84. int Relational_operators(void);  
  85. int Assignment_statement(void);  
  86. int Variable_declaration(void);  
  87. int Function_declaration(void);  
  88. int
  89. int Conditional_statement(void);  
  90. int Arithmetic_expression(void);  
  91. int Declarative_statement(void);  
  92. int Conditional_expression(void);  
  93. int Execute_statement_table(void);  
  94. int
  95. int Declarative_statement_table(void);  
  96.   
  97.   
  98.   
  99. void emergency_exit(void)  
  100. {  
  101.     MYLEX* EXIT_TEEMP=lex_head.next;  
  102.     current=EXIT_TEEMP;  
  103. while(!current)  
  104.     {  
  105.         current=EXIT_TEEMP->next;  
  106.         free(EXIT_TEEMP);  
  107.     }  
  108.     exit(0);  
  109. }  
  110.   
  111. int
  112. {  
  113. FILE *error_file=fopen("error.txt","a");  
  114. if(!error_file)  
  115.     {  
  116. "can`t open file \n");  
  117.     }  
  118. if(error_temp.line<current->line)  
  119.     {  
  120.         error_temp=*current;  
  121.         error_TOKEN=aim;  
  122. "error in line:%d\tTOKEN:%d\texpeced Token is :%d\n",  
  123.                 error_temp.line,error_temp.read,error_TOKEN);  
  124.   
  125.     }  
  126.     fclose(error_file);  
  127.   
  128. return
  129. }  
  130. //************************************
  131. // Method:    Read_file
  132. // FullName:  Read_file
  133. // Access:    public
  134. // Returns:   int
  135. // Qualifier:读文件
  136. // Parameter: void
  137. //************************************
  138. MYLEX* Read_file(MYLEX* current)  
  139. {  
  140.     current->line=0;  
  141.     current->next=NULL;  
  142.     current->read=T_0;  
  143.   
  144.     MYLEX* Temp;  
  145.     Temp=current;  
  146. FILE* READ_FILE=fopen("GRAMER.txt","r");  
  147. if(!READ_FILE)  
  148.     {  
  149. "can`t load file GRAMER.txt, a file like GRAMER.txt is expectd here \n");  
  150.         exit(0);  
  151.     }  
  152.   
  153. while(!feof(READ_FILE))  
  154.     {  
  155. sizeof(MYLEX));  
  156.         Temp=Temp->next;  
  157. if(!Temp)  
  158.         {  
  159. "can`t malloc a space for this program!\n");  
  160.             emergency_exit();  
  161.         }  
  162.         Temp->line=0;  
  163.         Temp->next=NULL;  
  164.         Temp->read=T_0;  
  165. "%d\t%d\n",&(Temp->line),&(Temp->read));  
  166.   
  167.     }  
  168.     fclose(READ_FILE);  
  169. return
  170. }  
  171.   
  172. //************************************
  173. // Method:    Advance
  174. // FullName:  Advance
  175. // Access:    public
  176. // Returns:   Token
  177. // Qualifier:   前进移向下一个TOKEN
  178. // Parameter: void
  179. //************************************
  180. MYLEX* Advance(MYLEX* current)  
  181. {  
  182. FILE*EAT_FILE=fopen("symtab2.txt","a");  
  183. FILE* LEFT_FILE=fopen("detail.txt","a");  
  184. if((!EAT_FILE)||(!LEFT_FILE))  
  185.     {  
  186. "can`t open file");  
  187.         emergency_exit();  
  188.     }  
  189.     MYLEX* Temp=current->next;  
  190. "you have eat the one is :%3d\n\n follow is \n",current->read);  
  191.     fprintf(EAT_FILE,  
  192. "\nyou have eat the one is line:%3d\tToken:%3d\n",  
  193.             current->line,  
  194.             current->read);  
  195.     fprintf(LEFT_FILE,  
  196. "\n\ncurrent eat the one is line:%3d\tToken:%3d\nfollow is\n",  
  197.             current->line,  
  198.             current->read);  
  199. for(Temp; Temp!=NULL; Temp=Temp->next)  
  200.     {  
  201. "line:%3d \t token=%3d\n",  
  202.                Temp->line,Temp->read);  
  203. "line:%3d \t token=%3d\n",  
  204.                 Temp->line,Temp->read);  
  205.     }  
  206.     fclose(EAT_FILE);  
  207.     fclose(LEFT_FILE);  
  208. if(current==NULL)  
  209.     {  
  210. "all work is to be done!,there is an error in your project!\n ");  
  211.         emergency_exit();  
  212.     }  
  213. return
  214. }  
  215.   
  216. //************************************
  217. // Method:    main
  218. // FullName:  main
  219. // Access:    public
  220. // Returns:   int
  221. // Qualifier:   主程序
  222. // Parameter: int agrc
  223. // Parameter: char * agrv[]
  224. //************************************
  225. int main(int agrc, char*agrv[])  
  226. {  
  227.     error_temp.line=0;  
  228.     error_temp.next=NULL;  
  229.     error_temp.read=T_0;  
  230.   
  231. "\t编译原理实验二\n\tXXXXXXXXX\n\tNEWPLAN\n");  
  232.     current=Read_file(&lex_head);  
  233. "pause");  
  234.   
  235. if(Main_Program())  
  236.     {  
  237. "\n\ncongratulation\tsuccessfully!\n\n");  
  238. "del error.txt");  
  239.     }  
  240. else
  241.     {  
  242. " sorry you have failed!\n");  
  243. "error in line:%d\tTOKEN:%d\texpeced Token is :%d\n",  
  244.                error_temp.line,error_temp.read,error_TOKEN);  
  245.     }  
  246.   
  247. "pause");  
  248.     emergency_exit();/*释放空间,函数返回*/  
  249. return
  250. }  
  251.   
  252. //************************************
  253. // Method:    match
  254. // FullName:  match
  255. // Access:    public
  256. // Returns:   int
  257. // Qualifier:   匹配
  258. // Parameter: Token read
  259. // Parameter: Token aim
  260. //************************************
  261. int
  262. {  
  263. if(read==aim)  
  264. return
  265.     error(current,aim);  
  266. return
  267.   
  268.   
  269. //    return read==aim? SUCCESS : !SUCCESS;
  270. }  
  271.   
  272. //************************************
  273. // Method:    Main_Program
  274. // FullName:  Main_Program
  275. // Access:    public
  276. // Returns:   int
  277. // Qualifier:   开始主程序
  278. // Parameter: void
  279. //************************************
  280. int Main_Program(void)  
  281. {  
  282. if(!Block())  
  283. return
  284. return
  285. }  
  286.   
  287. //************************************
  288. // Method:    Block
  289. // FullName:  Block
  290. // Access:    public
  291. // Returns:   int
  292. // Qualifier:/*分程序*/
  293. // Parameter: Token read
  294. //************************************
  295. int Block(void)  
  296. {  
  297.     MYLEX* Temp=current;  
  298. if(!match(current->read,T_BEGIN))  
  299.     {  
  300.         current=Temp;  
  301. return
  302.     }  
  303.     current= Advance(current);  
  304. if(!Declarative_statement_table())  
  305.     {  
  306.   
  307.         current=Temp;  
  308. return
  309.     }  
  310.   
  311. if(!match(current->read,T_SEM))  
  312.     {  
  313.         current=Temp;  
  314. return
  315.     }  
  316.     current=Advance(current);  
  317.   
  318.   
  319. if(!Execute_statement_table())  
  320.     {  
  321.         current=Temp;  
  322. return
  323.     }  
  324. if(!match(current->read,T_END))  
  325.     {  
  326.         current=Temp;  
  327. return
  328.     }  
  329.     current=Advance(current);  
  330. return
  331. }  
  332.   
  333.   
  334. //************************************
  335. // Method:    Declarative_statement_table
  336. // FullName:  Declarative_statement_table
  337. // Access:    public
  338. // Returns:   int
  339. // Qualifier:/*说明语句表*/
  340. // Parameter: Token read
  341. //************************************
  342. int
  343. {  
  344.     MYLEX* Temp=current;  
  345. if(!Declarative_statement())  
  346.     {  
  347.         current=Temp;  
  348. return
  349.     }  
  350.     /*采用扩展的BNF方法消除左递归*/  
  351. for(;;)  
  352.     {  
  353. if(!match(current->read,T_SEM))  
  354. break;  
  355.   
  356.         Temp=current;  
  357.         current =Advance(current);  
  358.   
  359. if(!Declarative_statement())  
  360.         {  
  361.             current=Temp;  
  362. break;  
  363.         }  
  364.     }  
  365. return
  366. }  
  367.   
  368.   
  369. //************************************
  370. // Method:    Declarative_statement
  371. // FullName:  Declarative_statement
  372. // Access:    public
  373. // Returns:   int
  374. // Qualifier:/*说明语句*/
  375. // Parameter: Token read
  376. //************************************
  377. int Declarative_statement(void)  
  378. {  
  379.     MYLEX* Temp=current;  
  380. if(Variable_declaration())  
  381.     {  
  382. return
  383.     }  
  384. else
  385.     {  
  386.         current=Temp;  
  387.     }  
  388. if(Function_declaration())  
  389. return
  390.   
  391.   
  392.     current=Temp;  
  393. return
  394.   
  395. }  
  396.   
  397.   
  398. //************************************
  399. // Method:    Execute_statement_table
  400. // FullName:  Execute_statement_table
  401. // Access:    public
  402. // Returns:   int
  403. // Qualifier:/*执行语句表*/
  404. // Parameter: Token read
  405. //************************************
  406. int Execute_statement_table(void)  
  407. {  
  408.     MYLEX* Temp=current;  
  409. if(!Execute_statement())  
  410.     {  
  411.         current=Temp;  
  412. return
  413.     }  
  414.   
  415. for(;;)  
  416.     {  
  417. if(!match(current->read,T_SEM))  
  418. break;  
  419.         Temp=current;  
  420.         current=Advance(current);  
  421.   
  422. if(!Execute_statement())  
  423.         {  
  424.             current=Temp;  
  425. break;  
  426.         }  
  427.     }  
  428. return
  429. }  
  430.   
  431.   
  432. //************************************
  433. // Method:    Execute_statement
  434. // FullName:  Execute_statement
  435. // Access:    public
  436. // Returns:   int
  437. // Qualifier:/*执行语句*/
  438. // Parameter: Token read
  439. //************************************
  440. int Execute_statement(void)  
  441. {  
  442.     MYLEX* Temp=current;  
  443.   
  444. if(Read_statement())  
  445.     {  
  446. return
  447.     }  
  448. else
  449.     {  
  450.         current=Temp;  
  451.     }  
  452. if(Write_statement())  
  453.     {  
  454. return
  455.     }  
  456. else
  457.     {  
  458.         current=Temp;  
  459.     }  
  460.   
  461. if(Conditional_statement())  
  462.     {  
  463. return
  464.     }  
  465. else
  466.     {  
  467.         current=Temp;  
  468.     }  
  469. if(Assignment_statement())  
  470.     {  
  471. return
  472.     }  
  473.   
  474.   
  475.     current=Temp;  
  476. return
  477. }  
  478.   
  479.   
  480. //************************************
  481. // Method:    Variable_declaration
  482. // FullName:  Variable_declaration
  483. // Access:    public
  484. // Returns:   int
  485. // Qualifier:/*变量说明*/
  486. // Parameter: Token read
  487. //************************************
  488. int Variable_declaration(void)  
  489. {  
  490.     MYLEX* Temp=current;  
  491. if(!match(current->read , T_INT))  
  492.     {  
  493.         current=Temp;  
  494. return
  495.     }  
  496.     current =Advance(current);  
  497. if(Variable())  
  498. return
  499.     current=Temp;  
  500. return
  501. }  
  502.   
  503.   
  504. //************************************
  505. // Method:    Function_declaration
  506. // FullName:  Function_declaration
  507. // Access:    public
  508. // Returns:   int
  509. // Qualifier:/*函数说明*/
  510. // Parameter: Token read
  511. //************************************
  512. int Function_declaration(void)  
  513. {  
  514.     MYLEX* Temp=current;  
  515. if(!match(current->read, T_INT))  
  516.     {  
  517.         current=Temp;  
  518. return
  519.     }  
  520.     current=Advance(current);  
  521.   
  522. if(!match(current->read, T_FOUNCTION))  
  523.     {  
  524.         current=Temp;  
  525. return
  526.     }  
  527.     current=Advance(current);  
  528.   
  529. if(!Identifier())  
  530.     {  
  531.         current=Temp;  
  532. return
  533.     }  
  534. if(!match(current->read, T_LPAR))  
  535.     {  
  536.         current=Temp;  
  537. return
  538.     }  
  539.     current=Advance(current);  
  540.   
  541. if(!Parameter())  
  542.     {  
  543.         current=Temp;  
  544. return
  545.     }  
  546. if(!match(current->read, T_RPAR))  
  547.     {  
  548.         current=Temp;  
  549. return
  550.     }  
  551.     current=Advance(current);  
  552. if(!match(current->read,T_SEM))  
  553.     {  
  554.         current=Temp;  
  555. return
  556.     }  
  557.     current =Advance(current);  
  558.   
  559. if(!Function())  
  560.     {  
  561.         current=Temp;  
  562. return
  563.     }  
  564.   
  565. return
  566. }  
  567.   
  568.   
  569. //************************************
  570. // Method:    Variable
  571. // FullName:  Variable
  572. // Access:    public
  573. // Returns:   int
  574. // Qualifier:/*变量*/
  575. // Parameter: Token read
  576. //************************************
  577. int Variable(void)  
  578. {  
  579.     MYLEX* Temp=current;  
  580. if(! match(current->read,T_SYMBOL))  
  581.     {  
  582.         current=Temp;  
  583. return
  584.     }  
  585.     current=Advance(current);  
  586. return
  587. }  
  588.   
  589.   
  590.   
  591. //************************************
  592. // Method:    Identifier
  593. // FullName:  Identifier
  594. // Access:    public
  595. // Returns:   int
  596. // Qualifier:/*标识符*/
  597. // Parameter: Token read
  598. //************************************
  599. int Identifier  (void)  
  600. {  
  601.     MYLEX* Temp=current;  
  602. if(! match(current->read,T_SYMBOL))  
  603.     {  
  604.         current=Temp;  
  605. return
  606.     }  
  607.     current=Advance(current);  
  608. return
  609. }  
  610.   
  611.   
  612. //************************************
  613. // Method:    Parameter
  614. // FullName:  Parameter
  615. // Access:    public
  616. // Returns:   int
  617. // Qualifier:/*参数*/
  618. // Parameter: Token read
  619. //************************************
  620. int Parameter  (void)  
  621. {  
  622.     MYLEX* Temp=current;  
  623. if(!Variable())  
  624.     {  
  625.         current=Temp;  
  626. return
  627.     }  
  628. return
  629. }  
  630.   
  631.   
  632. //************************************
  633. // Method:    Function
  634. // FullName:  Function
  635. // Access:    public
  636. // Returns:   int
  637. // Qualifier:/*函数体*/
  638. // Parameter: Token read
  639. //************************************
  640. int Function(void)  
  641. {  
  642.     MYLEX* Temp=current;  
  643. if(!match(current->read, T_BEGIN))  
  644.     {  
  645.         current=Temp;  
  646. return
  647.     }  
  648.     current=Advance(current);  
  649.   
  650. if(!Declarative_statement_table())  
  651.     {  
  652.         current=Temp;  
  653. return
  654.     }  
  655.   
  656. if(!match(current->read, T_SEM))  
  657.     {  
  658.         current=Temp;  
  659. return
  660.     }  
  661.     current=Advance(current);  
  662.   
  663. if(!Execute_statement_table())  
  664.     {  
  665.         current=Temp;  
  666. return
  667.     }  
  668.   
  669. if(!match(current->read,T_END))  
  670.     {  
  671.         current=Temp;  
  672. return
  673.     }  
  674.     current=Advance(current);  
  675. return
  676. }  
  677.   
  678.   
  679. //************************************
  680. // Method:    Read_statement
  681. // FullName:  Read_statement
  682. // Access:    public
  683. // Returns:   int
  684. // Qualifier:/*读语句*/
  685. // Parameter: Token read
  686. //************************************
  687. int Read_statement(void)  
  688. {  
  689.     MYLEX* Temp=current;  
  690. if(!match(current->read,T_READ))  
  691.     {  
  692.         current=Temp;  
  693. return
  694.     }  
  695.     current=Advance(current);  
  696. if(!match(current->read,T_LPAR))  
  697.     {  
  698.         current=Temp;  
  699. return
  700.     }  
  701.     current=Advance(current);  
  702.   
  703. if(!Variable())  
  704.     {  
  705.         current=Temp;  
  706. return
  707.     }  
  708.   
  709. if(!match(current->read,T_RPAR))  
  710.     {  
  711.         current=Temp;  
  712. return
  713.     }  
  714.     current=Advance(current);  
  715. return
  716. }  
  717.   
  718.   
  719. //************************************
  720. // Method:    Write_statement
  721. // FullName:  Write_statement
  722. // Access:    public
  723. // Returns:   int
  724. // Qualifier:/*写语句*/
  725. // Parameter: Token read
  726. //************************************
  727. int Write_statement(void)  
  728. {  
  729.     MYLEX* Temp=current;  
  730. if(!match(current->read,T_WRITE))  
  731.     {  
  732.         current=Temp;  
  733. return
  734.     }  
  735.     current=Advance(current);  
  736.   
  737. if(!match(current->read,T_LPAR))  
  738.     {  
  739.         current=Temp;  
  740. return
  741.     }  
  742.     current=Advance(current);  
  743.   
  744. if(!Variable())  
  745.     {  
  746.         current=Temp;  
  747. return
  748.     }  
  749.   
  750. if(!match(current->read,T_RPAR))  
  751.     {  
  752.         current=Temp;  
  753. return
  754.     }  
  755.     current=Advance(current);  
  756. "current to be got is:line=%d\t %d\n",current->line,current->read);  
  757. return
  758. }  
  759.   
  760.   
  761. //************************************
  762. // Method:    Assignment_statement
  763. // FullName:  Assignment_statement
  764. // Access:    public
  765. // Returns:   int
  766. // Qualifier:/*赋值语句*/
  767. // Parameter: Token read
  768. //************************************
  769. int Assignment_statement(void)  
  770. {  
  771.     MYLEX* Temp=current;  
  772. if(!Variable())  
  773.     {  
  774.         current=Temp;  
  775. return
  776.     }  
  777.   
  778. if(!match(current->read,T_ASSIGN))  
  779.     {  
  780.         current=Temp;  
  781. return
  782.     }  
  783.     current =Advance(current);  
  784.   
  785. if(Arithmetic_expression())  
  786. return
  787.     current=Temp;  
  788. return
  789. }  
  790.   
  791. //************************************
  792. // Method:    Conditional_statement
  793. // FullName:  Conditional_statement
  794. // Access:    public
  795. // Returns:   int
  796. // Qualifier:/*条件语句*/
  797. // Parameter: Token read
  798. //************************************
  799. int Conditional_statement(void)  
  800. {  
  801.     MYLEX* Temp=current;  
  802. if(!match(current->read,T_IF))  
  803.     {  
  804.         current=Temp;  
  805. return
  806.     }  
  807.     current=Advance(current);  
  808.   
  809. if(!Conditional_expression())  
  810.     {  
  811.   
  812.         current=Temp;  
  813. return
  814.     }  
  815.   
  816. if(!match(current->read,T_THEN))  
  817.     {  
  818.         current=Temp;  
  819. return
  820.     }  
  821.     current=Advance(current);  
  822.   
  823. if(!Execute_statement())  
  824.     {  
  825.         current=Temp;  
  826. return
  827.     }  
  828.   
  829. if(!match(current->read,T_ELSE))  
  830.     {  
  831.         current=Temp;  
  832. return
  833.     }  
  834.     current=Advance(current);  
  835. if(Execute_statement())  
  836. return
  837.     current=Temp;  
  838. return
  839. }  
  840.   
  841. //************************************
  842. // Method:    Arithmetic_expression
  843. // FullName:  Arithmetic_expression
  844. // Access:    public
  845. // Returns:   int
  846. // Qualifier:/*算术表达式*/
  847. // Parameter: Token read
  848. //************************************
  849. int Arithmetic_expression(void)  
  850. {  
  851.     MYLEX* Temp=current;  
  852. if(!item())  
  853.     {  
  854.         current=Temp;  
  855. return
  856.     }  
  857.   
  858. for(;;)  
  859.     {  
  860. if(!match(current->read,T_SUB))  
  861. break;  
  862.   
  863.         Temp=current;  
  864.         current=Advance(current);  
  865. if(!item())  
  866.         {  
  867.             current=Temp;  
  868. break;  
  869.         }  
  870.     }  
  871. return
  872. }  
  873.   
  874. //************************************
  875. // Method:    item
  876. // FullName:  item
  877. // Access:    public
  878. // Returns:   int
  879. // Qualifier:/*项*/
  880. // Parameter: Token read
  881. //************************************
  882. int item(void)  
  883. {  
  884.     MYLEX* Temp=current;  
  885. if(!Factor())  
  886.     {  
  887.         current=Temp;  
  888. return
  889.     }  
  890.   
  891. for(;;)  
  892.     {  
  893. if(!match(current->read,T_MUL))  
  894. break;  
  895.         Temp=current;  
  896.         current=Advance(current);  
  897. if(!Factor())  
  898.         {  
  899.             current=Temp;  
  900. break;  
  901.         }  
  902.     }  
  903. return
  904. }  
  905.   
  906. //************************************
  907. // Method:    Constant
  908. // FullName:  Constant
  909. // Access:    public
  910. // Returns:   int
  911. // Qualifier:/*常数*/
  912. // Parameter: Token read
  913. //************************************
  914. int Constant(void)  
  915. {  
  916.     MYLEX* Temp=current;  
  917. if(!match(current->read,T_CONSTANT))  
  918.     {  
  919. return
  920.     }  
  921.     current=Advance(current);  
  922. return
  923. }  
  924.   
  925. //************************************
  926. // Method:    Conditional_expression
  927. // FullName:  Conditional_expression
  928. // Access:    public
  929. // Returns:   int
  930. // Qualifier:/*条件表达式*/
  931. // Parameter: Token read
  932. //************************************
  933. int Conditional_expression(void)  
  934. {  
  935.     MYLEX* Temp=current;  
  936. if(!Arithmetic_expression())  
  937.     {  
  938.         current=Temp;  
  939. return
  940.     }  
  941. "line = %d,token=%d\n");  
  942. if(!Relational_operators())  
  943.     {  
  944.         current=Temp;  
  945. return
  946.     }  
  947. if(!Arithmetic_expression())  
  948.     {  
  949.         current=Temp;  
  950. return
  951.     }  
  952. return
  953. }  
  954.   
  955. //************************************
  956. // Method:    Relational_operators
  957. // FullName:  Relational_operators
  958. // Access:    public
  959. // Returns:   int
  960. // Qualifier:/*关系运算符*/
  961. // Parameter: Token read
  962. //************************************
  963. int Relational_operators(void)  
  964. {  
  965. if(match(current->read,T_L))  
  966.     {  
  967.         current=Advance(current);  
  968. return
  969.     }  
  970. if(match(current->read,T_LE))  
  971.     {  
  972.         current=Advance(current);  
  973. return
  974.     }  
  975. if(match(current->read,T_G))  
  976.     {  
  977.         current=Advance(current);  
  978. return
  979.     }  
  980. if(match(current->read,T_GE))  
  981.     {  
  982.         current=Advance(current);  
  983. return
  984.     }  
  985. if(match(current->read,T_E))  
  986.     {  
  987.         current=Advance(current);  
  988. return
  989.     }  
  990. if(match(current->read,T_NE))  
  991.     {  
  992.         current=Advance(current);  
  993. return
  994.     }  
  995. return
  996.   
  997. }  
  998.   
  999.   
  1000. //************************************
  1001. // Method:    Factor
  1002. // FullName:  Factor
  1003. // Access:    public
  1004. // Returns:   int
  1005. // Qualifier:/*因子*/
  1006. // Parameter: Token read
  1007. //************************************
  1008. int Factor(void)  
  1009. {  
  1010.     MYLEX* Temp=current;  
  1011. if(Function_call())  
  1012.     {  
  1013. return
  1014.     }  
  1015. else
  1016.     {  
  1017.         current=Temp;  
  1018.     }  
  1019. if(Variable())  
  1020.     {  
  1021. return
  1022.     }  
  1023. else
  1024.     {  
  1025.         current=Temp;  
  1026.     }  
  1027. if(Constant())  
  1028.     {  
  1029. return
  1030.     }  
  1031.   
  1032.     current=Temp;  
  1033. return
  1034. }  
  1035.   
  1036. //************************************
  1037. // Method:    Function_call
  1038. // FullName:  Function_call
  1039. // Access:    public
  1040. // Returns:   int
  1041. // Qualifier:/*函数调用*/
  1042. // Parameter: Token read
  1043. //************************************
  1044. int Function_call(void)  
  1045. {  
  1046.     MYLEX* Temp=current;  
  1047. if(!Identifier())  
  1048.     {  
  1049.         current=Temp;  
  1050. return
  1051.     }  
  1052. if(!match(current->read,T_LPAR))  
  1053.     {  
  1054.         current=Temp;  
  1055. return
  1056.     }  
  1057.     current=Advance(current);  
  1058.   
  1059. if( !Arithmetic_expression())  
  1060.     {  
  1061.         current=Temp;  
  1062. return
  1063.     }  
  1064. if(!match(current->read,T_RPAR))  
  1065.     {  
  1066.         current=Temp;  
  1067. return
  1068.     }  
  1069.   
  1070.     current=Advance(current);  
  1071. return
  1072.   
  1073. }  



结果分析

成功结果

失败结果: