PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/gbdk-297/sdcc/src/SDCC.y

#
Happy | 1432 lines | 1298 code | 134 blank | 0 comment | 0 complexity | c01f930aee78706fb2264446c3346ce1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, GPL-3.0
  1. /*-----------------------------------------------------------------------
  2. SDCC.y - parser definition file for sdcc :
  3. Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. In other words, you are welcome to use, share and improve this program.
  16. You are forbidden to forbid anyone else to use, share and improve
  17. what you give them. Help stamp out software-hoarding!
  18. -------------------------------------------------------------------------*/
  19. %{
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <string.h>
  23. #include "SDCCglobl.h"
  24. #include "SDCCsymt.h"
  25. #include "SDCChasht.h"
  26. #include "SDCCval.h"
  27. #include "SDCCmem.h"
  28. #include "SDCCast.h"
  29. #include "port.h"
  30. #include "newalloc.h"
  31. #include "SDCCerr.h"
  32. extern int yyerror (char *);
  33. extern FILE *yyin;
  34. int NestLevel = 0 ; /* current NestLevel */
  35. int stackPtr = 1 ; /* stack pointer */
  36. int xstackPtr = 0 ; /* xstack pointer */
  37. int reentrant = 0 ;
  38. int blockNo = 0 ; /* sequential block number */
  39. int currBlockno=0 ;
  40. extern int yylex();
  41. int yyparse(void);
  42. extern int noLineno ;
  43. char lbuff[1024]; /* local buffer */
  44. /* break & continue stacks */
  45. STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
  46. STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
  47. STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
  48. STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
  49. STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
  50. value *cenum = NULL ; /* current enumeration type chain*/
  51. %}
  52. %expect 6
  53. %union {
  54. symbol *sym ; /* symbol table pointer */
  55. structdef *sdef; /* structure definition */
  56. char yychar[SDCC_NAME_MAX+1];
  57. sym_link *lnk ; /* declarator or specifier */
  58. int yyint; /* integer value returned */
  59. value *val ; /* for integer constant */
  60. initList *ilist; /* initial list */
  61. char *yyinline; /* inlined assembler code */
  62. ast *asts; /* expression tree */
  63. }
  64. %token <yychar> IDENTIFIER TYPE_NAME
  65. %token <val> CONSTANT STRING_LITERAL
  66. %token SIZEOF TYPEOF
  67. %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
  68. %token AND_OP OR_OP
  69. %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
  70. %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
  71. %token <yyint> XOR_ASSIGN OR_ASSIGN
  72. %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
  73. %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
  74. %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
  75. %token STRUCT UNION ENUM ELIPSIS RANGE FAR
  76. %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
  77. %token NAKED JAVANATIVE OVERLAY
  78. %token <yyinline> INLINEASM
  79. %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
  80. %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
  81. %token RRC RLC
  82. %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
  83. %type <yyint> Interrupt_storage
  84. %type <sym> identifier declarator declarator2 enumerator_list enumerator
  85. %type <sym> struct_declarator
  86. %type <sym> struct_declarator_list struct_declaration struct_declaration_list
  87. %type <sym> declaration init_declarator_list init_declarator
  88. %type <sym> declaration_list identifier_list parameter_identifier_list
  89. %type <sym> declarator2_function_attributes while do for
  90. %type <lnk> pointer type_specifier_list type_specifier type_name
  91. %type <lnk> storage_class_specifier struct_or_union_specifier
  92. %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
  93. %type <lnk> function_attribute function_attributes enum_specifier
  94. %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
  95. %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
  96. %type <sdef> stag opt_stag
  97. %type <asts> primary_expr
  98. %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
  99. %type <asts> additive_expr shift_expr relational_expr equality_expr
  100. %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
  101. %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
  102. %type <asts> expr argument_expr_list function_definition expr_opt
  103. %type <asts> statement_list statement labeled_statement compound_statement
  104. %type <asts> expression_statement selection_statement iteration_statement
  105. %type <asts> jump_statement function_body else_statement string_literal
  106. %type <ilist> initializer initializer_list
  107. %type <yyint> unary_operator assignment_operator struct_or_union
  108. %start file
  109. %%
  110. file
  111. : external_definition
  112. | file external_definition
  113. ;
  114. external_definition
  115. : function_definition {
  116. blockNo=0;
  117. }
  118. | declaration {
  119. if ($1 && $1->type
  120. && IS_FUNC($1->type))
  121. {
  122. /* The only legal storage classes for
  123. * a function prototype (declaration)
  124. * are extern and static. extern is the
  125. * default. Thus, if this function isn't
  126. * explicitly marked static, mark it
  127. * extern.
  128. */
  129. if ($1->etype
  130. && IS_SPEC($1->etype)
  131. && !SPEC_STAT($1->etype))
  132. {
  133. SPEC_EXTR($1->etype) = 1;
  134. }
  135. }
  136. addSymChain ($1);
  137. allocVariables ($1) ;
  138. cleanUpLevel (SymbolTab,1);
  139. }
  140. ;
  141. function_definition
  142. : declarator function_body { /* function type not specified */
  143. /* assume it to be 'int' */
  144. addDecl($1,0,newIntLink());
  145. $$ = createFunction($1,$2);
  146. }
  147. | declaration_specifiers declarator function_body
  148. {
  149. pointerTypes($2->type,copyLinkChain($1));
  150. addDecl($2,0,$1);
  151. $$ = createFunction($2,$3);
  152. }
  153. ;
  154. function_attribute
  155. : function_attributes
  156. | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
  157. ;
  158. function_attributes
  159. : USING CONSTANT {
  160. $$ = newLink() ;
  161. $$->class = SPECIFIER ;
  162. FUNC_REGBANK($$) = (int) floatFromVal($2);
  163. }
  164. | REENTRANT { $$ = newLink ();
  165. $$->class = SPECIFIER ;
  166. FUNC_ISREENT($$)=1;
  167. }
  168. | CRITICAL { $$ = newLink ();
  169. $$->class = SPECIFIER ;
  170. FUNC_ISCRITICAL($$) = 1;
  171. }
  172. | NAKED { $$ = newLink ();
  173. $$->class = SPECIFIER ;
  174. FUNC_ISNAKED($$)=1;
  175. }
  176. | JAVANATIVE { $$ = newLink ();
  177. $$->class = SPECIFIER ;
  178. FUNC_ISJAVANATIVE($$)=1;
  179. }
  180. | OVERLAY { $$ = newLink ();
  181. $$->class = SPECIFIER ;
  182. FUNC_ISOVERLAY($$)=1;
  183. }
  184. | NONBANKED {$$ = newLink ();
  185. $$->class = SPECIFIER ;
  186. FUNC_NONBANKED($$) = 1;
  187. if (FUNC_BANKED($$)) {
  188. werror(W_BANKED_WITH_NONBANKED);
  189. }
  190. }
  191. | BANKED {$$ = newLink ();
  192. $$->class = SPECIFIER ;
  193. FUNC_BANKED($$) = 1;
  194. if (FUNC_NONBANKED($$)) {
  195. werror(W_BANKED_WITH_NONBANKED);
  196. }
  197. if (SPEC_STAT($$)) {
  198. werror(W_BANKED_WITH_STATIC);
  199. }
  200. }
  201. | Interrupt_storage
  202. {
  203. $$ = newLink () ;
  204. $$->class = SPECIFIER ;
  205. FUNC_INTNO($$) = $1 ;
  206. FUNC_ISISR($$) = 1;
  207. }
  208. ;
  209. function_body
  210. : compound_statement
  211. | declaration_list compound_statement
  212. {
  213. werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
  214. exit(1);
  215. }
  216. ;
  217. primary_expr
  218. : identifier { $$ = newAst_VALUE(symbolVal($1)); }
  219. | CONSTANT { $$ = newAst_VALUE($1); }
  220. | string_literal
  221. | '(' expr ')' { $$ = $2 ; }
  222. ;
  223. string_literal
  224. : STRING_LITERAL { $$ = newAst_VALUE($1); }
  225. ;
  226. postfix_expr
  227. : primary_expr
  228. | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
  229. | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
  230. $$->left->funcName = 1;}
  231. | postfix_expr '(' argument_expr_list ')'
  232. {
  233. $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
  234. }
  235. | postfix_expr '.' identifier
  236. {
  237. $3 = newSymbol($3->name,NestLevel);
  238. $3->implicit = 1;
  239. $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
  240. /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
  241. }
  242. | postfix_expr PTR_OP identifier
  243. {
  244. $3 = newSymbol($3->name,NestLevel);
  245. $3->implicit = 1;
  246. $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
  247. }
  248. | postfix_expr INC_OP
  249. { $$ = newNode(INC_OP,$1,NULL);}
  250. | postfix_expr DEC_OP
  251. { $$ = newNode(DEC_OP,$1,NULL); }
  252. ;
  253. argument_expr_list
  254. : assignment_expr
  255. | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
  256. ;
  257. unary_expr
  258. : postfix_expr
  259. | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
  260. | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
  261. | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
  262. | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
  263. | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
  264. | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
  265. ;
  266. unary_operator
  267. : '&' { $$ = '&' ;}
  268. | '*' { $$ = '*' ;}
  269. | '+' { $$ = '+' ;}
  270. | '-' { $$ = '-' ;}
  271. | '~' { $$ = '~' ;}
  272. | '!' { $$ = '!' ;}
  273. ;
  274. cast_expr
  275. : unary_expr
  276. | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
  277. ;
  278. multiplicative_expr
  279. : cast_expr
  280. | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
  281. | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
  282. | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
  283. ;
  284. additive_expr
  285. : multiplicative_expr
  286. | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
  287. | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
  288. ;
  289. shift_expr
  290. : additive_expr
  291. | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
  292. | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
  293. ;
  294. relational_expr
  295. : shift_expr
  296. | relational_expr '<' shift_expr {
  297. $$ = (port->lt_nge ?
  298. newNode('!',newNode(GE_OP,$1,$3),NULL) :
  299. newNode('<', $1,$3));
  300. }
  301. | relational_expr '>' shift_expr {
  302. $$ = (port->gt_nle ?
  303. newNode('!',newNode(LE_OP,$1,$3),NULL) :
  304. newNode('>',$1,$3));
  305. }
  306. | relational_expr LE_OP shift_expr {
  307. $$ = (port->le_ngt ?
  308. newNode('!', newNode('>', $1 , $3 ), NULL) :
  309. newNode(LE_OP,$1,$3));
  310. }
  311. | relational_expr GE_OP shift_expr {
  312. $$ = (port->ge_nlt ?
  313. newNode('!', newNode('<', $1 , $3 ), NULL) :
  314. newNode(GE_OP,$1,$3));
  315. }
  316. ;
  317. equality_expr
  318. : relational_expr
  319. | equality_expr EQ_OP relational_expr {
  320. $$ = (port->eq_nne ?
  321. newNode('!',newNode(NE_OP,$1,$3),NULL) :
  322. newNode(EQ_OP,$1,$3));
  323. }
  324. | equality_expr NE_OP relational_expr {
  325. $$ = (port->ne_neq ?
  326. newNode('!', newNode(EQ_OP,$1,$3), NULL) :
  327. newNode(NE_OP,$1,$3));
  328. }
  329. ;
  330. and_expr
  331. : equality_expr
  332. | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
  333. ;
  334. exclusive_or_expr
  335. : and_expr
  336. | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
  337. ;
  338. inclusive_or_expr
  339. : exclusive_or_expr
  340. | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
  341. ;
  342. logical_and_expr
  343. : inclusive_or_expr
  344. | logical_and_expr AND_OP inclusive_or_expr
  345. { $$ = newNode(AND_OP,$1,$3);}
  346. ;
  347. logical_or_expr
  348. : logical_and_expr
  349. | logical_or_expr OR_OP logical_and_expr
  350. { $$ = newNode(OR_OP,$1,$3); }
  351. ;
  352. conditional_expr
  353. : logical_or_expr
  354. | logical_or_expr '?' logical_or_expr ':' conditional_expr
  355. {
  356. $$ = newNode(':',$3,$5) ;
  357. $$ = newNode('?',$1,$$) ;
  358. }
  359. ;
  360. assignment_expr
  361. : conditional_expr
  362. | unary_expr assignment_operator assignment_expr
  363. {
  364. switch ($2) {
  365. case '=':
  366. $$ = newNode($2,$1,$3);
  367. break;
  368. case MUL_ASSIGN:
  369. $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
  370. break;
  371. case DIV_ASSIGN:
  372. $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
  373. break;
  374. case MOD_ASSIGN:
  375. $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
  376. break;
  377. case ADD_ASSIGN:
  378. $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
  379. break;
  380. case SUB_ASSIGN:
  381. $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
  382. break;
  383. case LEFT_ASSIGN:
  384. $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
  385. break;
  386. case RIGHT_ASSIGN:
  387. $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
  388. break;
  389. case AND_ASSIGN:
  390. $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
  391. break;
  392. case XOR_ASSIGN:
  393. $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
  394. break;
  395. case OR_ASSIGN:
  396. $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
  397. break;
  398. default :
  399. $$ = NULL;
  400. }
  401. }
  402. ;
  403. assignment_operator
  404. : '=' { $$ = '=' ;}
  405. | MUL_ASSIGN
  406. | DIV_ASSIGN
  407. | MOD_ASSIGN
  408. | ADD_ASSIGN
  409. | SUB_ASSIGN
  410. | LEFT_ASSIGN
  411. | RIGHT_ASSIGN
  412. | AND_ASSIGN
  413. | XOR_ASSIGN
  414. | OR_ASSIGN
  415. ;
  416. expr
  417. : assignment_expr
  418. | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
  419. ;
  420. constant_expr
  421. : conditional_expr
  422. ;
  423. declaration
  424. : declaration_specifiers ';' { $$ = NULL ; }
  425. | declaration_specifiers init_declarator_list ';'
  426. {
  427. /* add the specifier list to the id */
  428. symbol *sym , *sym1;
  429. for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
  430. sym_link *lnk = copyLinkChain($1);
  431. /* do the pointer stuff */
  432. pointerTypes(sym->type,lnk);
  433. addDecl (sym,0,lnk) ;
  434. }
  435. $$ = sym1 ;
  436. }
  437. ;
  438. declaration_specifiers
  439. : storage_class_specifier { $$ = $1; }
  440. | storage_class_specifier declaration_specifiers {
  441. /* if the decl $2 is not a specifier */
  442. /* find the spec and replace it */
  443. if ( !IS_SPEC($2)) {
  444. sym_link *lnk = $2 ;
  445. while (lnk && !IS_SPEC(lnk->next))
  446. lnk = lnk->next;
  447. lnk->next = mergeSpec($1,lnk->next, yytext);
  448. $$ = $2 ;
  449. }
  450. else
  451. $$ = mergeSpec($1,$2, yytext);
  452. }
  453. | type_specifier { $$ = $1; }
  454. | type_specifier declaration_specifiers {
  455. /* if the decl $2 is not a specifier */
  456. /* find the spec and replace it */
  457. if ( !IS_SPEC($2)) {
  458. sym_link *lnk = $2 ;
  459. while (lnk && !IS_SPEC(lnk->next))
  460. lnk = lnk->next;
  461. lnk->next = mergeSpec($1,lnk->next, yytext);
  462. $$ = $2 ;
  463. }
  464. else
  465. $$ = mergeSpec($1,$2, yytext);
  466. }
  467. ;
  468. init_declarator_list
  469. : init_declarator
  470. | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
  471. ;
  472. init_declarator
  473. : declarator { $1->ival = NULL ; }
  474. | declarator '=' initializer { $1->ival = $3 ; }
  475. ;
  476. storage_class_specifier
  477. : TYPEDEF {
  478. $$ = newLink () ;
  479. $$->class = SPECIFIER ;
  480. SPEC_TYPEDEF($$) = 1 ;
  481. }
  482. | EXTERN {
  483. $$ = newLink();
  484. $$->class = SPECIFIER ;
  485. SPEC_EXTR($$) = 1 ;
  486. }
  487. | STATIC {
  488. $$ = newLink ();
  489. $$->class = SPECIFIER ;
  490. SPEC_STAT($$) = 1 ;
  491. }
  492. | AUTO {
  493. $$ = newLink () ;
  494. $$->class = SPECIFIER ;
  495. SPEC_SCLS($$) = S_AUTO ;
  496. }
  497. | REGISTER {
  498. $$ = newLink ();
  499. $$->class = SPECIFIER ;
  500. SPEC_SCLS($$) = S_REGISTER ;
  501. }
  502. ;
  503. Interrupt_storage
  504. : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
  505. ;
  506. type_specifier
  507. : type_specifier2
  508. | type_specifier2 AT constant_expr
  509. {
  510. /* add this to the storage class specifier */
  511. SPEC_ABSA($1) = 1; /* set the absolute addr flag */
  512. /* now get the abs addr from value */
  513. SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
  514. }
  515. ;
  516. type_specifier2
  517. : CHAR {
  518. $$=newLink();
  519. $$->class = SPECIFIER ;
  520. SPEC_NOUN($$) = V_CHAR ;
  521. }
  522. | SHORT {
  523. $$=newLink();
  524. $$->class = SPECIFIER ;
  525. $$->select.s._short = 1 ;
  526. }
  527. | INT {
  528. $$=newLink();
  529. $$->class = SPECIFIER ;
  530. SPEC_NOUN($$) = V_INT ;
  531. }
  532. | LONG {
  533. $$=newLink();
  534. $$->class = SPECIFIER ;
  535. SPEC_LONG($$) = 1 ;
  536. }
  537. | SIGNED {
  538. $$=newLink();
  539. $$->class = SPECIFIER ;
  540. $$->select.s._signed = 1;
  541. }
  542. | UNSIGNED {
  543. $$=newLink();
  544. $$->class = SPECIFIER ;
  545. SPEC_USIGN($$) = 1 ;
  546. }
  547. | VOID {
  548. $$=newLink();
  549. $$->class = SPECIFIER ;
  550. SPEC_NOUN($$) = V_VOID ;
  551. }
  552. | CONST {
  553. $$=newLink();
  554. $$->class = SPECIFIER ;
  555. SPEC_CONST($$) = 1;
  556. }
  557. | VOLATILE {
  558. $$=newLink();
  559. $$->class = SPECIFIER ;
  560. SPEC_VOLATILE($$) = 1 ;
  561. }
  562. | FLOAT {
  563. $$=newLink();
  564. SPEC_NOUN($$) = V_FLOAT;
  565. $$->class = SPECIFIER ;
  566. }
  567. | XDATA {
  568. $$ = newLink ();
  569. $$->class = SPECIFIER ;
  570. SPEC_SCLS($$) = S_XDATA ;
  571. }
  572. | CODE {
  573. $$ = newLink () ;
  574. $$->class = SPECIFIER ;
  575. SPEC_SCLS($$) = S_CODE ;
  576. }
  577. | EEPROM {
  578. $$ = newLink () ;
  579. $$->class = SPECIFIER ;
  580. SPEC_SCLS($$) = S_EEPROM ;
  581. }
  582. | DATA {
  583. $$ = newLink ();
  584. $$->class = SPECIFIER ;
  585. SPEC_SCLS($$) = S_DATA ;
  586. }
  587. | IDATA {
  588. $$ = newLink ();
  589. $$->class = SPECIFIER ;
  590. SPEC_SCLS($$) = S_IDATA ;
  591. }
  592. | PDATA {
  593. $$ = newLink ();
  594. $$->class = SPECIFIER ;
  595. SPEC_SCLS($$) = S_PDATA ;
  596. }
  597. | BIT {
  598. $$=newLink();
  599. $$->class = SPECIFIER ;
  600. SPEC_NOUN($$) = V_BIT ;
  601. SPEC_SCLS($$) = S_BIT ;
  602. SPEC_BLEN($$) = 1;
  603. SPEC_BSTR($$) = 0;
  604. }
  605. | struct_or_union_specifier
  606. | enum_specifier {
  607. cenum = NULL ;
  608. $$ = $1 ;
  609. }
  610. | TYPE_NAME
  611. {
  612. symbol *sym;
  613. sym_link *p ;
  614. sym = findSym(TypedefTab,NULL,$1) ;
  615. $$ = p = copyLinkChain(sym->type);
  616. SPEC_TYPEDEF(getSpec(p)) = 0;
  617. }
  618. | sfr_reg_bit
  619. ;
  620. sfr_reg_bit
  621. : SBIT {
  622. $$ = newLink() ;
  623. $$->class = SPECIFIER ;
  624. SPEC_NOUN($$) = V_SBIT;
  625. SPEC_SCLS($$) = S_SBIT;
  626. }
  627. | SFR {
  628. $$ = newLink() ;
  629. $$->class = SPECIFIER ;
  630. SPEC_NOUN($$) = V_CHAR;
  631. SPEC_SCLS($$) = S_SFR ;
  632. SPEC_USIGN($$) = 1 ;
  633. }
  634. ;
  635. struct_or_union_specifier
  636. : struct_or_union opt_stag '{' struct_declaration_list '}'
  637. {
  638. structdef *sdef ;
  639. /* Create a structdef */
  640. sdef = $2 ;
  641. sdef->fields = reverseSyms($4) ; /* link the fields */
  642. sdef->size = compStructSize($1,sdef); /* update size of */
  643. /* Create the specifier */
  644. $$ = newLink () ;
  645. $$->class = SPECIFIER ;
  646. SPEC_NOUN($$) = V_STRUCT;
  647. SPEC_STRUCT($$)= sdef ;
  648. }
  649. | struct_or_union stag
  650. {
  651. $$ = newLink() ;
  652. $$->class = SPECIFIER ;
  653. SPEC_NOUN($$) = V_STRUCT;
  654. SPEC_STRUCT($$) = $2 ;
  655. }
  656. ;
  657. struct_or_union
  658. : STRUCT { $$ = STRUCT ; }
  659. | UNION { $$ = UNION ; }
  660. ;
  661. opt_stag
  662. : stag
  663. | { /* synthesize a name add to structtable */
  664. $$ = newStruct(genSymName(NestLevel)) ;
  665. $$->level = NestLevel ;
  666. addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
  667. };
  668. stag
  669. : identifier { /* add name to structure table */
  670. $$ = findSymWithBlock (StructTab,$1,currBlockno);
  671. if (! $$ ) {
  672. $$ = newStruct($1->name) ;
  673. $$->level = NestLevel ;
  674. addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
  675. }
  676. };
  677. struct_declaration_list
  678. : struct_declaration
  679. | struct_declaration_list struct_declaration
  680. {
  681. symbol *sym = $2;
  682. /* go to the end of the chain */
  683. while (sym->next) sym = sym->next;
  684. sym->next = $1 ;
  685. $$ = $2;
  686. }
  687. ;
  688. struct_declaration
  689. : type_specifier_list struct_declarator_list ';'
  690. {
  691. /* add this type to all the symbols */
  692. symbol *sym ;
  693. for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
  694. /* make the symbol one level up */
  695. sym->level-- ;
  696. pointerTypes(sym->type,copyLinkChain($1));
  697. if (!sym->type) {
  698. sym->type = copyLinkChain($1);
  699. sym->etype = getSpec(sym->type);
  700. }
  701. else
  702. addDecl (sym,0,cloneSpec($1));
  703. /* make sure the type is complete and sane */
  704. checkTypeSanity(sym->etype, sym->name);
  705. }
  706. $$ = $2;
  707. }
  708. ;
  709. struct_declarator_list
  710. : struct_declarator
  711. | struct_declarator_list ',' struct_declarator
  712. {
  713. $3->next = $1 ;
  714. $$ = $3 ;
  715. }
  716. ;
  717. struct_declarator
  718. : declarator
  719. | ':' constant_expr {
  720. $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
  721. $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
  722. }
  723. | declarator ':' constant_expr
  724. {
  725. $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
  726. }
  727. ;
  728. enum_specifier
  729. : ENUM '{' enumerator_list '}' {
  730. //addSymChain ($3);
  731. //allocVariables(reverseSyms($3)) ;
  732. $$ = copyLinkChain(cenum->type);
  733. }
  734. | ENUM identifier '{' enumerator_list '}' {
  735. symbol *csym ;
  736. $2->type = copyLinkChain(cenum->type);
  737. $2->etype = getSpec($2->type);
  738. /* add this to the enumerator table */
  739. if (!(csym=findSym(enumTab,$2,$2->name)) &&
  740. (csym && csym->level == $2->level))
  741. werror(E_DUPLICATE_TYPEDEF,csym->name);
  742. addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
  743. //addSymChain ($4);
  744. //allocVariables (reverseSyms($4));
  745. $$ = copyLinkChain(cenum->type);
  746. SPEC_SCLS(getSpec($$)) = 0 ;
  747. }
  748. | ENUM identifier {
  749. symbol *csym ;
  750. /* check the enumerator table */
  751. if ((csym = findSym(enumTab,$2,$2->name)))
  752. $$ = copyLinkChain(csym->type);
  753. else {
  754. $$ = newLink() ;
  755. $$->class = SPECIFIER ;
  756. SPEC_NOUN($$) = V_INT ;
  757. }
  758. SPEC_SCLS(getSpec($$)) = 0 ;
  759. }
  760. ;
  761. enumerator_list
  762. : enumerator
  763. | enumerator_list ',' {
  764. }
  765. | enumerator_list ',' enumerator {
  766. $3->next = $1 ;
  767. $$ = $3 ;
  768. }
  769. ;
  770. enumerator
  771. : identifier opt_assign_expr
  772. {
  773. /* make the symbol one level up */
  774. $1->level-- ;
  775. $1->type = copyLinkChain($2->type);
  776. $1->etype= getSpec($1->type);
  777. SPEC_ENUM($1->etype) = 1;
  778. $$ = $1 ;
  779. // do this now, so we can use it for the next enums in the list
  780. addSymChain($1);
  781. }
  782. ;
  783. opt_assign_expr
  784. : '=' constant_expr {
  785. value *val ;
  786. val = constExprValue($2,TRUE);
  787. $$ = cenum = val ;
  788. }
  789. | {
  790. if (cenum) {
  791. sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
  792. $$ = cenum = constVal(lbuff);
  793. }
  794. else {
  795. sprintf(lbuff,"%d",0);
  796. $$ = cenum = constVal(lbuff);
  797. }
  798. }
  799. ;
  800. declarator
  801. : declarator2_function_attributes { $$ = $1; }
  802. | pointer declarator2_function_attributes
  803. {
  804. addDecl ($2,0,reverseLink($1));
  805. $$ = $2 ;
  806. }
  807. ;
  808. declarator2_function_attributes
  809. : declarator2 { $$ = $1 ; }
  810. | declarator2 function_attribute {
  811. // copy the functionAttributes (not the args and hasVargs !!)
  812. sym_link *funcType=$1->etype;
  813. struct value *args=FUNC_ARGS(funcType);
  814. unsigned hasVargs=FUNC_HASVARARGS(funcType);
  815. memcpy (&funcType->funcAttrs, &$2->funcAttrs,
  816. sizeof($2->funcAttrs));
  817. FUNC_ARGS(funcType)=args;
  818. FUNC_HASVARARGS(funcType)=hasVargs;
  819. // just to be sure
  820. memset (&$2->funcAttrs, 0,
  821. sizeof($2->funcAttrs));
  822. addDecl ($1,0,$2);
  823. }
  824. ;
  825. declarator2
  826. : identifier
  827. | '(' declarator ')' { $$ = $2; }
  828. | declarator2 '[' ']'
  829. {
  830. sym_link *p;
  831. p = newLink ();
  832. DCL_TYPE(p) = ARRAY ;
  833. DCL_ELEM(p) = 0 ;
  834. addDecl($1,0,p);
  835. }
  836. | declarator2 '[' constant_expr ']'
  837. {
  838. sym_link *p ;
  839. value *tval;
  840. p = (tval = constExprValue($3,TRUE))->etype;
  841. /* if it is not a constant then Error */
  842. if ( SPEC_SCLS(p) != S_LITERAL)
  843. werror(E_CONST_EXPECTED) ;
  844. else {
  845. p = newLink ();
  846. DCL_TYPE(p) = ARRAY ;
  847. DCL_ELEM(p) = (int) floatFromVal(tval) ;
  848. addDecl($1,0,p);
  849. }
  850. }
  851. | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
  852. | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
  853. {
  854. addDecl ($1,FUNCTION,NULL) ;
  855. FUNC_HASVARARGS($1->type) = IS_VARG($4);
  856. FUNC_ARGS($1->type) = reverseVal($4);
  857. /* nest level was incremented to take care of the parms */
  858. NestLevel-- ;
  859. currBlockno--;
  860. // if this was a pointer (to a function)
  861. if (IS_PTR($1->type)) {
  862. // move the args and hasVargs to the function
  863. FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
  864. FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
  865. memset (&$1->type->funcAttrs, 0,
  866. sizeof($1->type->funcAttrs));
  867. // remove the symbol args (if any)
  868. cleanUpLevel(SymbolTab,NestLevel+1);
  869. }
  870. $$ = $1;
  871. }
  872. | declarator2 '(' parameter_identifier_list ')'
  873. {
  874. werror(E_OLD_STYLE,$1->name) ;
  875. /* assume it returns an int */
  876. $1->type = $1->etype = newIntLink();
  877. $$ = $1 ;
  878. }
  879. ;
  880. pointer
  881. : unqualified_pointer { $$ = $1 ;}
  882. | unqualified_pointer type_specifier_list
  883. {
  884. $$ = $1 ;
  885. DCL_TSPEC($1) = $2;
  886. }
  887. | unqualified_pointer pointer
  888. {
  889. $$ = $1 ;
  890. $$->next = $2 ;
  891. DCL_TYPE($2)=port->unqualified_pointer;
  892. }
  893. | unqualified_pointer type_specifier_list pointer
  894. {
  895. $$ = $1 ;
  896. if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
  897. DCL_PTR_CONST($1) = SPEC_CONST($2);
  898. DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
  899. switch (SPEC_SCLS($2)) {
  900. case S_XDATA:
  901. DCL_TYPE($3) = FPOINTER;
  902. break;
  903. case S_IDATA:
  904. DCL_TYPE($3) = IPOINTER ;
  905. break;
  906. case S_PDATA:
  907. DCL_TYPE($3) = PPOINTER ;
  908. break;
  909. case S_DATA:
  910. DCL_TYPE($3) = POINTER ;
  911. break;
  912. case S_CODE:
  913. DCL_PTR_CONST($3) = 1;
  914. DCL_TYPE($3) = CPOINTER ;
  915. break;
  916. case S_EEPROM:
  917. DCL_TYPE($3) = EEPPOINTER;
  918. break;
  919. default:
  920. // this could be just "constant"
  921. // werror(W_PTR_TYPE_INVALID);
  922. }
  923. }
  924. else
  925. werror (W_PTR_TYPE_INVALID);
  926. $$->next = $3 ;
  927. }
  928. ;
  929. unqualified_pointer
  930. : '*'
  931. {
  932. $$ = newLink();
  933. DCL_TYPE($$)=UPOINTER;
  934. }
  935. ;
  936. type_specifier_list
  937. : type_specifier
  938. //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
  939. | type_specifier_list type_specifier {
  940. /* if the decl $2 is not a specifier */
  941. /* find the spec and replace it */
  942. if ( !IS_SPEC($2)) {
  943. sym_link *lnk = $2 ;
  944. while (lnk && !IS_SPEC(lnk->next))
  945. lnk = lnk->next;
  946. lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
  947. $$ = $2 ;
  948. }
  949. else
  950. $$ = mergeSpec($1,$2, "type_specifier_list");
  951. }
  952. ;
  953. parameter_identifier_list
  954. : identifier_list
  955. | identifier_list ',' ELIPSIS
  956. ;
  957. identifier_list
  958. : identifier
  959. | identifier_list ',' identifier
  960. {
  961. $3->next = $1;
  962. $$ = $3 ;
  963. }
  964. ;
  965. parameter_type_list
  966. : parameter_list
  967. | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
  968. ;
  969. parameter_list
  970. : parameter_declaration
  971. | parameter_list ',' parameter_declaration
  972. {
  973. $3->next = $1 ;
  974. $$ = $3 ;
  975. }
  976. ;
  977. parameter_declaration
  978. : type_specifier_list declarator
  979. {
  980. symbol *loop ;
  981. pointerTypes($2->type,$1);
  982. addDecl ($2,0,$1);
  983. for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
  984. addSymChain ($2);
  985. $$ = symbolVal($2);
  986. }
  987. | type_name {
  988. $$ = newValue() ;
  989. $$->type = $1;
  990. $$->etype = getSpec($$->type);
  991. }
  992. ;
  993. type_name
  994. : type_specifier_list { $$ = $1 ;}
  995. | type_specifier_list abstract_declarator
  996. {
  997. /* go to the end of the list */
  998. sym_link *p;
  999. pointerTypes($2,$1);
  1000. for ( p = $2 ; p->next ; p=p->next);
  1001. p->next = $1 ;
  1002. $$ = $2 ;
  1003. }
  1004. ;
  1005. abstract_declarator
  1006. : pointer { $$ = reverseLink($1); }
  1007. | abstract_declarator2
  1008. | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
  1009. ;
  1010. abstract_declarator2
  1011. : '(' abstract_declarator ')' { $$ = $2 ; }
  1012. | '[' ']' {
  1013. $$ = newLink ();
  1014. DCL_TYPE($$) = ARRAY ;
  1015. DCL_ELEM($$) = 0 ;
  1016. }
  1017. | '[' constant_expr ']' {
  1018. value *val ;
  1019. $$ = newLink ();
  1020. DCL_TYPE($$) = ARRAY ;
  1021. DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
  1022. }
  1023. | abstract_declarator2 '[' ']' {
  1024. $$ = newLink ();
  1025. DCL_TYPE($$) = ARRAY ;
  1026. DCL_ELEM($$) = 0 ;
  1027. $$->next = $1 ;
  1028. }
  1029. | abstract_declarator2 '[' constant_expr ']'
  1030. {
  1031. value *val ;
  1032. $$ = newLink ();
  1033. DCL_TYPE($$) = ARRAY ;
  1034. DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
  1035. $$->next = $1 ;
  1036. }
  1037. | '(' ')' { $$ = NULL;}
  1038. | '(' parameter_type_list ')' { $$ = NULL;}
  1039. | abstract_declarator2 '(' ')' {
  1040. // $1 must be a pointer to a function
  1041. sym_link *p=newLink();
  1042. DCL_TYPE(p) = FUNCTION;
  1043. if (!$1) {
  1044. // ((void (code *) ()) 0) ()
  1045. $1=newLink();
  1046. DCL_TYPE($1)=CPOINTER;
  1047. $$ = $1;
  1048. }
  1049. $1->next=p;
  1050. }
  1051. | abstract_declarator2 '(' parameter_type_list ')' {
  1052. if (!IS_VOID($3->type)) {
  1053. // this is nonsense, so let's just burp something
  1054. werror(E_TOO_FEW_PARMS);
  1055. } else {
  1056. // $1 must be a pointer to a function
  1057. sym_link *p=newLink();
  1058. DCL_TYPE(p) = FUNCTION;
  1059. if (!$1) {
  1060. // ((void (code *) (void)) 0) ()
  1061. $1=newLink();
  1062. DCL_TYPE($1)=CPOINTER;
  1063. $$ = $1;
  1064. }
  1065. $1->next=p;
  1066. }
  1067. }
  1068. initializer
  1069. : assignment_expr { $$ = newiList(INIT_NODE,$1); }
  1070. | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
  1071. | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
  1072. ;
  1073. initializer_list
  1074. : initializer
  1075. | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
  1076. ;
  1077. statement
  1078. : labeled_statement
  1079. | compound_statement
  1080. | expression_statement
  1081. | selection_statement
  1082. | iteration_statement
  1083. | jump_statement
  1084. | INLINEASM ';' {
  1085. ast *ex = newNode(INLINEASM,NULL,NULL);
  1086. ex->values.inlineasm = malloc(strlen($1)+1);
  1087. strcpy(ex->values.inlineasm,$1);
  1088. $$ = ex;
  1089. }
  1090. ;
  1091. labeled_statement
  1092. // : identifier ':' statement { $$ = createLabel($1,$3); }
  1093. : identifier ':' { $$ = createLabel($1,NULL); }
  1094. | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
  1095. | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
  1096. ;
  1097. start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
  1098. ;
  1099. end_block : '}' { currBlockno = STACK_POP(blockNum); }
  1100. ;
  1101. compound_statement
  1102. : start_block end_block { $$ = createBlock(NULL,NULL); }
  1103. | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
  1104. | start_block
  1105. declaration_list { addSymChain($2); }
  1106. end_block { $$ = createBlock($2,NULL) ; }
  1107. | start_block
  1108. declaration_list { addSymChain ($2); }
  1109. statement_list
  1110. end_block {$$ = createBlock($2,$4) ; }
  1111. | error ';' { $$ = NULL ; }
  1112. ;
  1113. declaration_list
  1114. : declaration
  1115. {
  1116. /* if this is typedef declare it immediately */
  1117. if ( $1 && IS_TYPEDEF($1->etype)) {
  1118. allocVariables ($1);
  1119. $$ = NULL ;
  1120. }
  1121. else
  1122. $$ = $1 ;
  1123. }
  1124. | declaration_list declaration
  1125. {
  1126. symbol *sym;
  1127. /* if this is a typedef */
  1128. if ($2 && IS_TYPEDEF($2->etype)) {
  1129. allocVariables ($2);
  1130. $$ = $1 ;
  1131. }
  1132. else {
  1133. /* get to the end of the previous decl */
  1134. if ( $1 ) {
  1135. $$ = sym = $1 ;
  1136. while (sym->next)
  1137. sym = sym->next ;
  1138. sym->next = $2;
  1139. }
  1140. else
  1141. $$ = $2 ;
  1142. }
  1143. }
  1144. ;
  1145. statement_list
  1146. : statement
  1147. | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
  1148. ;
  1149. expression_statement
  1150. : ';' { $$ = NULL;}
  1151. | expr ';'
  1152. ;
  1153. else_statement
  1154. : ELSE statement { $$ = $2 ; }
  1155. | { $$ = NULL;}
  1156. ;
  1157. selection_statement
  1158. : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
  1159. | SWITCH '(' expr ')' {
  1160. ast *ex ;
  1161. static int swLabel = 0 ;
  1162. /* create a node for expression */
  1163. ex = newNode(SWITCH,$3,NULL);
  1164. STACK_PUSH(swStk,ex); /* save it in the stack */
  1165. ex->values.switchVals.swNum = swLabel ;
  1166. /* now create the label */
  1167. sprintf(lbuff,"_swBrk_%d",swLabel++);
  1168. $<sym>$ = newSymbol(lbuff,NestLevel);
  1169. /* put label in the break stack */
  1170. STACK_PUSH(breakStack,$<sym>$);
  1171. }
  1172. statement {
  1173. /* get back the switch form the stack */
  1174. $$ = STACK_POP(swStk) ;
  1175. $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
  1176. STACK_POP(breakStack);
  1177. }
  1178. ;
  1179. while : WHILE { /* create and push the continue , break & body labels */
  1180. static int Lblnum = 0 ;
  1181. /* continue */
  1182. sprintf (lbuff,"_whilecontinue_%d",Lblnum);
  1183. STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
  1184. /* break */
  1185. sprintf (lbuff,"_whilebreak_%d",Lblnum);
  1186. STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
  1187. /* body */
  1188. sprintf (lbuff,"_whilebody_%d",Lblnum++);
  1189. $$ = newSymbol(lbuff,NestLevel);
  1190. }
  1191. do : DO { /* create and push the continue , break & body Labels */
  1192. static int Lblnum = 0 ;
  1193. /* continue */
  1194. sprintf(lbuff,"_docontinue_%d",Lblnum);
  1195. STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
  1196. /* break */
  1197. sprintf (lbuff,"_dobreak_%d",Lblnum);
  1198. STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
  1199. /* do body */
  1200. sprintf (lbuff,"_dobody_%d",Lblnum++);
  1201. $$ = newSymbol (lbuff,NestLevel);
  1202. }
  1203. for : FOR { /* create & push continue, break & body labels */
  1204. static int Lblnum = 0 ;
  1205. /* continue */
  1206. sprintf (lbuff,"_forcontinue_%d",Lblnum);
  1207. STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
  1208. /* break */
  1209. sprintf (lbuff,"_forbreak_%d",Lblnum);
  1210. STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
  1211. /* body */
  1212. sprintf (lbuff,"_forbody_%d",Lblnum);
  1213. $$ = newSymbol(lbuff,NestLevel);
  1214. /* condition */
  1215. sprintf (lbuff,"_forcond_%d",Lblnum++);
  1216. STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
  1217. }
  1218. iteration_statement
  1219. : while '(' expr ')' statement
  1220. {
  1221. noLineno++ ;
  1222. $$ = createWhile ( $1, STACK_POP(continueStack),
  1223. STACK_POP(breakStack), $3, $5 );
  1224. $$->lineno = $1->lineDef ;
  1225. noLineno-- ;
  1226. }
  1227. | do statement WHILE '(' expr ')' ';'
  1228. {
  1229. noLineno++ ;
  1230. $$ = createDo ( $1 , STACK_POP(continueStack),
  1231. STACK_POP(breakStack), $5, $2);
  1232. $$->lineno = $1->lineDef ;
  1233. noLineno-- ;
  1234. }
  1235. | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
  1236. {
  1237. noLineno++ ;
  1238. /* if break or continue statement present
  1239. then create a general case loop */
  1240. if (STACK_PEEK(continueStack)->isref ||
  1241. STACK_PEEK(breakStack)->isref) {
  1242. $$ = createFor ($1, STACK_POP(continueStack),
  1243. STACK_POP(breakStack) ,
  1244. STACK_POP(forStack) ,
  1245. $3 , $5 , $7, $9 );
  1246. } else {
  1247. $$ = newNode(FOR,$9,NULL);
  1248. AST_FOR($$,trueLabel) = $1;
  1249. AST_FOR($$,continueLabel) = STACK_POP(continueStack);
  1250. AST_FOR($$,falseLabel) = STACK_POP(breakStack);
  1251. AST_FOR($$,condLabel) = STACK_POP(forStack) ;
  1252. AST_FOR($$,initExpr) = $3;
  1253. AST_FOR($$,condExpr) = $5;
  1254. AST_FOR($$,loopExpr) = $7;
  1255. }
  1256. noLineno-- ;
  1257. }
  1258. ;
  1259. expr_opt
  1260. : { $$ = NULL ; }
  1261. | expr
  1262. ;
  1263. jump_statement
  1264. : GOTO identifier ';' {
  1265. $2->islbl = 1;
  1266. $$ = newAst_VALUE(symbolVal($2));
  1267. $$ = newNode(GOTO,$$,NULL);
  1268. }
  1269. | CONTINUE ';' {
  1270. /* make sure continue is in context */
  1271. if (STACK_PEEK(continueStack) == NULL) {
  1272. werror(E_BREAK_CONTEXT);
  1273. $$ = NULL;
  1274. }
  1275. else {
  1276. $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
  1277. $$ = newNode(GOTO,$$,NULL);
  1278. /* mark the continue label as referenced */
  1279. STACK_PEEK(continueStack)->isref = 1;
  1280. }
  1281. }
  1282. | BREAK ';' {
  1283. if (STACK_PEEK(breakStack) == NULL) {
  1284. werror(E_BREAK_CONTEXT);
  1285. $$ = NULL;
  1286. } else {
  1287. $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
  1288. $$ = newNode(GOTO,$$,NULL);
  1289. STACK_PEEK(breakStack)->isref = 1;
  1290. }
  1291. }
  1292. | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
  1293. | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
  1294. ;
  1295. identifier
  1296. : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
  1297. ;
  1298. %%