PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/sdcc-221-pre1/sdcc/src/SDCC.y

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