parse.y
上传用户:wqdrylgs
上传日期:2007-02-09
资源大小:65k
文件大小:12k
源码类别:

汇编语言

开发平台:

WINDOWS

  1. %{
  2. #define YYPARSER /* distinguishes Yacc output from other code files */
  3. #include "globals.h"
  4. #include "util.h"
  5. #include "scan.h"
  6. #include "parse.h"
  7. static char * savedFunName; /* for use in assignments */
  8. static char * savedIdName;
  9. static int savedLineNo;  /* ditto */
  10. static TreeNode * savedTree; /* stores syntax tree for later return */
  11. %}
  12. %token ENDFILE ERROR 
  13. %token INT CHAR FLOAT IF ELSE WHILE VOID RETURN BREAK CONTINUE
  14. %token ID NUM FNUM SCHAR
  15. %token PLUS SUB MUT DIV LT LE GT GE EQ NEQ AND OR NOT ASSIGN SEMI COMMA LP RP LSP RSP LFP RFP 
  16. %union { TreeNode * ptree;
  17.          Type type; 
  18.        }
  19.        
  20. %type <ptree> program dec_list dec var_dec fun_dec fun_def params param_list param comp_stmt local_dec stmt_list stmt 
  21.               exp_stmt sele_stmt iter_stmt return_stmt exp var simple_exp factor call args arg_list
  22.               id_list 
  23. %type <type> type_spec
  24. %left COMMA
  25. %right ASSIGN
  26. %left OR    
  27. %left AND
  28. %left EQ NEQ
  29. %left LT LE GT GE
  30. %left PLUS SUB
  31. %left MUT DIV
  32. %left LP RP LSP RSP LFP RFP
  33. %right ELSE
  34. %include {
  35.     void yyerror(const char * message);
  36. TreeNode * parse(void);
  37. }
  38. %% /* Grammar for C_minus */
  39. program     : dec_list
  40.                  { savedTree = $1;} 
  41.             ;
  42. dec_list    : dec_list dec
  43. { TreeNode * t = $1;
  44.   if (t != NULL)
  45.   { while (t->sibling != NULL)
  46. t = t->sibling;
  47. t->sibling = $2;
  48. $$ = $1; }
  49.   else $$ = $2;
  50. }                  
  51.             | dec  
  52.                 { $$ = $1; }
  53.             ;
  54. dec         : var_dec { $$ = $1; }
  55.             | fun_dec { $$ = $1; }
  56.             | fun_def   { $$ = $1; }
  57.             ;
  58. id          : ID { savedIdName = copyString(tokenString); }
  59.             ;
  60. fid         : { savedFunName = savedIdName; }
  61.             ;
  62. var_dec     : type_spec id_list SEMI
  63. { if($1 == Void)
  64.   ;
  65.   // err
  66.   else
  67.     {
  68.   $$ = newDecNode(VarK); 
  69.   $$ -> type = $1;
  70.   $$ -> child[0] = $2;
  71. }
  72.             ;
  73. id_list     : id_list COMMA var
  74.                 { 
  75.                   TreeNode * t = $1;
  76.   if (t != NULL)
  77.   { while (t->sibling != NULL)
  78. t = t->sibling;
  79. t->sibling = $3;
  80. $$ = $1; }
  81.   else $$ = $3;
  82.                 } // i,str[5],j
  83.             | var { $$ = $1; }
  84.             | id_list COMMA id ASSIGN simple_exp
  85.               { 
  86.   TreeNode * new_node = newStmtNode(AssignK);
  87.   TreeNode * t = $1;
  88.   if (t != NULL)
  89.   { while (t->sibling != NULL)
  90. t = t->sibling;
  91. t->sibling = new_node;
  92. $$ = $1; }
  93.   else $$ = new_node;
  94.               }
  95.             | id ASSIGN simple_exp
  96.               { 
  97.  $$ = newStmtNode(AssignK);
  98.  $$ -> child[0] = newExpNode(IdK);
  99.  $$ -> child[0] -> attr.name = savedIdName;
  100.  $$ -> child[1] = $3;
  101.               }
  102.             ; 
  103. type_spec   : INT { $$ = Integer; }         
  104.             | FLOAT { $$ = Float; }         
  105.             | CHAR { $$ = Char; }         
  106.             | VOID { $$ = Void; }         
  107.             ;
  108. fun_def     : type_spec id fid LP params RP comp_stmt 
  109. { $$ = newDecNode(FunDefK);
  110.   $$ -> attr.name = savedFunName;
  111.   $$ -> type = $1;
  112.   $$ -> child[0] = $5;
  113.   $$ -> child[1] = $7; 
  114. }
  115.             | id fid LP params RP comp_stmt
  116. { $$ = newDecNode(FunDefK);
  117.   $$ -> attr.name = savedFunName;
  118.   $$ -> type = Void;
  119.   $$ -> child[0] = $4;
  120.   $$ -> child[1] = $6; 
  121. }
  122.             ;
  123. fun_dec     : type_spec id fid LP params RP SEMI
  124. { $$ = newDecNode(FunDecK);
  125.   $$ -> attr.name = savedFunName;
  126.   $$ -> type = $1;
  127.   $$ -> child[0] = $5;
  128.   $$ -> child[1] = NULL;
  129. }
  130. | id fid LP params RP SEMI
  131. { $$ = newDecNode(FunDecK);
  132.   $$ -> attr.name = savedFunName;
  133.   $$ -> type = Void;
  134.   $$ -> child[0] = $4;
  135.   $$ -> child[1] = NULL;
  136. }
  137.             ;             
  138. params      : param_list
  139.                 { $$ = $1; }
  140.             | 
  141. { $$ = NULL; }
  142.             ;         
  143. param_list  : param_list COMMA param
  144.              { TreeNode * t = $1;
  145.   if (t != NULL)
  146.   { while (t->sibling != NULL)
  147. t = t->sibling;
  148. t->sibling = $3;
  149. $$ = $1; }
  150.   else $$ = $3;
  151. }                  
  152.             | param
  153.                 { $$ = $1; }
  154.             ;
  155. param       : type_spec 
  156.                 { $$ = newDecNode(ParamK);
  157.                   $$ -> type = $1;
  158.                 }            
  159. | type_spec id
  160.                 { $$ = newDecNode(ParamK);
  161.                   $$ -> type = $1;
  162.                   $$ -> attr.name = savedIdName;
  163.                 }            
  164.             | type_spec id LSP RSP
  165.                 { $$ = newDecNode(ParamK);
  166.                   $$ -> type = $1;
  167.                   $$ -> attr.name = savedIdName;
  168.                 }            
  169.             | type_spec id LSP simple_exp RSP
  170.                 { $$ = newDecNode(ParamK);
  171.                   $$ -> type = $1;
  172.                   $$ -> attr.name = savedIdName;
  173.                   $$ -> child[0] = $4;
  174.                 }            
  175.             ;
  176. comp_stmt   : LFP local_dec stmt_list RFP
  177.                 { $$ = newDecNode(CompK);
  178.                   $$ -> child[0] = $2;
  179.                   $$ -> child[1] = $3;
  180.                 }            
  181.             ;
  182. local_dec   : local_dec var_dec            
  183.              { TreeNode * t = $1;
  184.   if (t != NULL)
  185.   { while (t->sibling != NULL)
  186. t = t->sibling;
  187. t->sibling = $2;
  188. $$ = $1; }
  189.   else $$ = $2;
  190. }                  
  191.             | 
  192.                 { $$ = NULL; }
  193.             ;
  194. stmt_list   : stmt_list stmt            
  195.              { TreeNode * t = $1;
  196.   if (t != NULL)
  197.   { while (t->sibling != NULL)
  198. t = t->sibling;
  199. t->sibling = $2;
  200. $$ = $1; }
  201.   else $$ = $2;
  202. }                  
  203.             | 
  204.                 { $$ = NULL; }
  205.             ;
  206. stmt        : exp_stmt { $$ = $1; }            
  207.             | sele_stmt { $$ = $1; }
  208.             | iter_stmt { $$ = $1; }
  209.             | return_stmt { $$ = $1; }
  210.             | comp_stmt { $$ = $1; }
  211.             | CONTINUE SEMI { $$ = newStmtNode(ContinueK); }
  212.             | BREAK SEMI    { $$ = newStmtNode(BreakK); }
  213.             ;
  214. exp_stmt    : exp SEMI
  215.                 { $$ = $1; }
  216.             | SEMI
  217.                 { $$ = NULL; }            
  218.             ;
  219. sele_stmt   : IF LP exp RP stmt %prec ELSE
  220.                 { $$ = newStmtNode(IfK);
  221.                   $$ -> child[0] = $3;
  222.                   $$ -> child[1] = $5;
  223.                 }            
  224.             | IF LP exp RP stmt ELSE stmt
  225.                 { $$ = newStmtNode(IfK);
  226.                   $$ -> child[0] = $3;
  227.                   $$ -> child[1] = $5;
  228.   $$ -> child[2] = $7;
  229.                 }
  230.             ;
  231. iter_stmt   : WHILE LP exp RP stmt
  232. { $$ = newStmtNode(WhileK);
  233.                   $$ -> child[0] = $3;
  234.                   $$ -> child[1] = $5;
  235.                 }            
  236.             ;    
  237. return_stmt : RETURN SEMI
  238.                 { $$ = newStmtNode(ReturnK);
  239.                   $$ -> child[0] = NULL;
  240.                 }
  241.             | RETURN exp SEMI
  242.                 { $$ = newStmtNode(ReturnK);
  243.                   $$ -> child[0] = $2;
  244.                 }
  245.             ;                   
  246. exp         : var ASSIGN exp
  247.                 { $$ = newStmtNode(AssignK);
  248.                   $$ -> child[0] = $1;
  249.                   $$ -> child[1] = $3;
  250.                 }
  251.             | simple_exp
  252.                 { $$ = $1; }
  253.             ;
  254. var         : id
  255.                 { $$ = newExpNode(IdK);
  256.                   $$ -> attr.name = savedIdName;
  257.                 }            
  258.             | id LSP simple_exp RSP
  259. { $$ = newExpNode(IdK);
  260.   $$ -> attr.name = savedIdName;
  261.                   $$ -> child[0] = $3;
  262.                 }           
  263.             ;
  264. simple_exp : simple_exp OR simple_exp 
  265. { $$ = newExpNode(OpK);
  266.   $$ -> child[0] = $1;
  267.   $$ -> child[1] = $3;
  268.   $$ -> attr.op = OR;
  269. }
  270. |simple_exp AND simple_exp 
  271. { $$ = newExpNode(OpK);
  272.   $$ -> child[0] = $1;
  273.   $$ -> child[1] = $3;
  274.   $$ -> attr.op = AND;
  275. }
  276. |simple_exp LT simple_exp 
  277. { $$ = newExpNode(OpK);
  278.   $$ -> child[0] = $1;
  279.   $$ -> child[1] = $3;
  280.   $$ -> attr.op = LT;
  281.   $$ -> type = Boolean;
  282. }
  283. |simple_exp LE simple_exp 
  284. { $$ = newExpNode(OpK);
  285.   $$ -> child[0] = $1;
  286.   $$ -> child[1] = $3;
  287.   $$ -> attr.op = LE;
  288.   $$ -> type = Boolean;
  289. }
  290. |simple_exp GT simple_exp 
  291. { $$ = newExpNode(OpK);
  292.   $$ -> child[0] = $1;
  293.   $$ -> child[1] = $3;
  294.   $$ -> attr.op = GT;
  295.   $$ -> type = Boolean;
  296. }
  297. |simple_exp GE simple_exp 
  298. { $$ = newExpNode(OpK);
  299.   $$ -> child[0] = $1;
  300.   $$ -> child[1] = $3;
  301.   $$ -> attr.op = GE;
  302.   $$ -> type = Boolean;
  303. }
  304. |simple_exp EQ simple_exp 
  305. { $$ = newExpNode(OpK);
  306.   $$ -> child[0] = $1;
  307.   $$ -> child[1] = $3;
  308.   $$ -> attr.op = EQ;
  309.   $$ -> type = Boolean;
  310. }
  311. |simple_exp NEQ simple_exp 
  312. { $$ = newExpNode(OpK);
  313.   $$ -> child[0] = $1;
  314.   $$ -> child[1] = $3;
  315.   $$ -> attr.op = NEQ;
  316.   $$ -> type = Boolean;
  317. }
  318. |simple_exp PLUS simple_exp 
  319. { $$ = newExpNode(OpK);
  320.   $$ -> child[0] = $1;
  321.   $$ -> child[1] = $3;
  322.   $$ -> attr.op = PLUS;
  323. }
  324. |simple_exp SUB simple_exp 
  325. { $$ = newExpNode(OpK);
  326.   $$ -> child[0] = $1;
  327.   $$ -> child[1] = $3;
  328.   $$ -> attr.op = SUB;
  329. }
  330. |simple_exp MUT simple_exp 
  331. { $$ = newExpNode(OpK);
  332.   $$ -> child[0] = $1;
  333.   $$ -> child[1] = $3;
  334.   $$ -> attr.op = MUT;
  335. }
  336. |simple_exp DIV simple_exp 
  337. { $$ = newExpNode(OpK);
  338.   $$ -> child[0] = $1;
  339.   $$ -> child[1] = $3;
  340.   $$ -> attr.op = DIV;
  341. }
  342. | factor
  343.     { $$ = $1; }
  344. ;
  345. factor      : LP exp RP
  346.                 { $$ = $2; }
  347.             | var
  348.                 { $$ = $1; }
  349. | call
  350.     { $$ = $1; }
  351. | NUM
  352.     { $$ = newExpNode(NumK);
  353.       $$ -> type = Integer;
  354.       $$ -> attr.val.i = atoi(tokenString);
  355.     }
  356. | FNUM
  357.     { $$ = newExpNode(FnumK);
  358.       $$ -> type = Float;
  359.       $$ -> attr.val.f = atof(tokenString);
  360.     }
  361. | SCHAR
  362.     { $$ = newExpNode(CharK);
  363.       $$ -> type = Char;
  364.       $$ -> attr.val.i = *(tokenString + 1);
  365.     }
  366. | NOT factor
  367.     { $$ = $2;
  368.       $$ -> attr.op = NOT;
  369.     }
  370. ;
  371. call        : var LP args RP
  372.                 { $$ = newStmtNode(CallK);
  373.   $$ -> attr.name = $1 -> attr.name;
  374.                   $$ -> child[0] = $3;
  375.                 }
  376.             ;
  377. arg_list    : arg_list COMMA exp            
  378. { TreeNode * t = $1;
  379.   if (t != NULL)
  380.   { while (t->sibling != NULL)
  381. t = t->sibling;
  382. t->sibling = $3;
  383. $$ = $1; }
  384.   else $$ = $3;
  385. }                  
  386.             | exp
  387.                 { $$ = $1; }
  388. ;
  389. args        : arg_list
  390.                 { $$ = $1; }           
  391.             | 
  392.                 { $$ = NULL; }
  393.             ;
  394. %%
  395. void yyerror(const char * message)
  396. { fprintf(listing,"Syntax error at line %d: %sn",lineno,message);
  397.   fprintf(listing,"Current token: ");
  398.   printToken(yychar,tokenString);
  399.   Error = TRUE;
  400. }
  401. /* yylex calls getToken to make Yacc/Bison output
  402.  * compatible with ealier versions of the TINY scanner
  403.  */
  404. #ifdef YYPROTOTYPE
  405. int YYCDECL yygettoken(void)
  406. #else
  407. int YYCDECL yygettoken()
  408. #endif
  409. {
  410. return yylex();
  411. }
  412. static TokenType yylex(void)
  413. { return getToken(); }
  414. TreeNode * parse(void)
  415. { yyparse();
  416.   return savedTree;
  417. }