PageRenderTime 61ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/yacc.y

https://github.com/maxatome/mcc
Happy | 881 lines | 762 code | 119 blank | 0 comment | 0 complexity | d265e727737eae5f9370c78549f0f314 MD5 | raw file
  1. /*
  2. * Copyright (c) 1997,98,99,2000,2001,2002 David Stes.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU Library General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * $Id: yacc.ym,v 1.13 2003/09/29 16:52:05 stes Exp $
  19. */
  20. %{
  21. #include <EXTERN.h>
  22. #include <perl.h>
  23. #include <XSUB.h>
  24. #include <stdarg.h>
  25. #define YYERROR_VERBOSE
  26. #if defined(__DEBUG)
  27. # define MCC_DEBUG(action) (ps_last_token = (action), \
  28. printf("yacc.y:%d <<<%s>>>\n", \
  29. __LINE__, SvPV_nolen(ps_last_token)), \
  30. ps_last_token)
  31. #else
  32. # define MCC_DEBUG(action) (ps_last_token = (action))
  33. #endif
  34. SV *ps_last_token = NULL;
  35. SV *ps_last_lex_token = NULL;
  36. extern SV *perlsubf(char *pa_func, char *pa_format, ...);
  37. extern SV *perlsubn(char *pa_func, ...);
  38. #define F(perl_func, format, args...) \
  39. MCC_DEBUG(perlsubf("main::" #perl_func, format , ## args))
  40. #define N(perl_func, args...) \
  41. MCC_DEBUG(perlsubn("main::" #perl_func , ## args, NULL))
  42. #define J(first, args...) N(mcc_join, first , ## args)
  43. #define NEW_EMPTY newSVpvn("", 0)
  44. #define YYSTYPE SV*
  45. %}
  46. %start translunit
  47. %token identifier constant stringcomp builtinfun typeword
  48. %token storageclass typequal externlang classname
  49. %token mccclass
  50. %token cppdirect
  51. %token enumkeyw structkeyw ifkeyw elsekeyw whilekeyw dokeyw forkeyw
  52. %token switchkeyw casekeyw
  53. %token defaultkeyw breakkeyw continuekeyw returnkeyw gotokeyw
  54. %token asmkeyw sizeofop typeofop
  55. %token ellipsis
  56. %token assignop equalop relop shift plusplus logand logor arrow
  57. /* Objective C */
  58. %token atdefs atselector atinterface atimplementation atend atencode atrequires
  59. /* compiler specific */
  60. %token gnuextension attributekeyw
  61. /* precedence (lowest to highest) */
  62. %left ',' /* a,b,c -> (a,b),c */
  63. %right '=' /* a=b=c -> a=(b=c) */
  64. %right ifkeyw elsekeyw
  65. %right assignop
  66. %right '?' ':'
  67. %left logor
  68. %left logand
  69. %left '|'
  70. %left '^'
  71. %left '&'
  72. %left equalop
  73. %left relop
  74. %left shift
  75. %left '+' '-'
  76. %left '*' '%' '/'
  77. %right '!' '~' sizeofop typeofop unary plusplus
  78. %left arrow '.'
  79. %left hyperunary
  80. %left '(' '[' ')' ']'
  81. %%
  82. abstrdecl : pointer
  83. | abstrdeclx
  84. | pointer abstrdeclx
  85. { $$ = J($1, $2); }
  86. | gnuattribdecl abstrdecl
  87. { $$ = J($1, $2); }
  88. | pointer gnuattribdecl abstrdecl
  89. { $$ = J($1, $2, $3); }
  90. ;
  91. msabstrdecl : abstrdecl
  92. | typequallist abstrdecl
  93. { $$ = J($1, $2); }
  94. ;
  95. abstrdeclx : '(' msabstrdecl ')'
  96. { $$ = J($1, $2, $3); }
  97. | '[' optconstantexpr ']'
  98. { $$ = J($1, $2, $3); }
  99. | abstrdeclx '[' optconstantexpr ']'
  100. { $$ = J($1, $2, $3, $4); }
  101. | abstrdeclx '(' optparmdeflist ')'
  102. { $$ = J($1, $2, $3, $4); }
  103. | abstrdeclx gnuattribdecl
  104. { $$ = J($1, $2); }
  105. | abstrdeclx asmstring
  106. { $$ = J($1, $2); }
  107. ;
  108. andexpr : equalopexpr
  109. | andexpr '&' equalopexpr
  110. { $$ = J($1, $2, $3); }
  111. ;
  112. anyword : identifier | storageclass | typespec | typequal
  113. ;
  114. asmstring : asmkeyw '(' stringchain ')'
  115. { $$ = J($1, $2, $3, $4); }
  116. ;
  117. asmops : /* empty */
  118. { $$ = NEW_EMPTY; }
  119. | asmop
  120. | asmops ',' asmop
  121. { $$ = J($1, $2, $3); }
  122. ;
  123. asmop : stringchain '(' expr ')'
  124. { $$ = J($1, $2, $3, $4); }
  125. ;
  126. asmclobbers : stringchain
  127. | asmclobbers ',' stringchain
  128. { $$ = J($1, $2, $3); }
  129. ;
  130. assignexpr : condexpr
  131. | castexpr assignop assignexpr
  132. { $$ = J($1, $2, $3); }
  133. | castexpr '='
  134. { }
  135. assignexpr
  136. { $$ = J($1, $2, $4); }
  137. ;
  138. gnuattriblist : gnuattrib
  139. | gnuattriblist ',' gnuattrib
  140. { $$ = J($1, $2, $3); }
  141. ;
  142. builtinfunarg : typename /* as in builtin_isfloat(type) */
  143. | assignexpr
  144. ;
  145. builtinfunargs : builtinfunarg
  146. | builtinfunargs ',' builtinfunarg
  147. { $$ = J($1, $2, $3); }
  148. ;
  149. caretexpr : andexpr
  150. | caretexpr '^' andexpr
  151. { $$ = J($1, $2, $3); }
  152. ;
  153. castexpr : unaryexpr
  154. | '(' typename ')' castexpr %prec unary
  155. { $$ = J($1, $2, $3, $4); }
  156. | '(' typename ')' '{' initializerlist '}' %prec unary
  157. { $$ = J($1, $2, $3, $4, $5, $6); }
  158. | '(' typename ')' '{' initializerlist ',' '}' %prec unary
  159. { $$ = J($1, $2, $3, $4, $5, $6, $7); }
  160. ;
  161. classnamezz : atinterface identifier
  162. {
  163. N(add_class_type, $2);
  164. $$ = $2;
  165. }
  166. ;
  167. classdef : classnamezz ivardef
  168. { $$ = N(atinterface, $1, &PL_sv_undef, $2); }
  169. | classnamezz ivardef ':' ivardef
  170. { $$ = N(atinterface, $1, &PL_sv_undef, $2, $4); }
  171. | classnamezz
  172. { $$ = N(atinterface, $1); }
  173. | classnamezz ':' mccclass
  174. { $$ = N(atinterface, $1, $3); }
  175. | classnamezz ':' mccclass ivardef
  176. { $$ = N(atinterface, $1, $3, $4); }
  177. | classnamezz ':' mccclass ivardef ':' ivardef
  178. { $$ = N(atinterface, $1, $3, $4, $6); }
  179. ;
  180. classimpl : atimplementation mccclass
  181. { $$ = N(atimplementation, $1, $2); }
  182. | atimplementation identifier
  183. {
  184. yyerror("@implementation without preceding @interface keyword");
  185. YYERROR;
  186. }
  187. ;
  188. compoundstmt : '{' '}'
  189. { $$ = J($1, $2); }
  190. | '{' stmtlist '}'
  191. { $$ = J($1, $2, $3); }
  192. | '{' datadefcompoundlist '}'
  193. { $$ = J($1, $2, $3); }
  194. | '{' datadefcompoundlist stmtlist '}'
  195. { $$ = J($1, $2, $3, $4); }
  196. | '{' datadefcompoundlist stmtlist mixeddatastmtlist '}'
  197. { $$ = J($1, $2, $3, $4, $5); }
  198. ;
  199. condexpr : logorexpr
  200. | logorexpr '?' expr ':' condexpr
  201. { $$ = J($1, $2, $3, $4, $5); }
  202. | logorexpr '?' ':' condexpr
  203. { $$ = J($1, $2, $3, $4); }
  204. ;
  205. constantexpr : condexpr
  206. ;
  207. datadef : datadefspecs ';' /* id a,b; or id foo(id z); */
  208. { $$ = J($1, $2); }
  209. | datadefx ';'
  210. { $$ = J($1, $2); }
  211. | cppdirect
  212. { $$ = $1; }
  213. | requiresclause /* Objective C 3.3 */
  214. ;
  215. datadeflist : datadef
  216. | datadeflist datadef
  217. { $$ = J($1, $2); }
  218. ;
  219. datadefcompound : nestedfundef
  220. | datadef
  221. ;
  222. datadefcompoundlist : datadefcompound
  223. | datadefcompoundlist datadefcompound
  224. { $$ = J($1, $2); }
  225. ;
  226. datadefspecs : storageclass
  227. | datadefspecs storageclass
  228. { $$ = J($1, $2); }
  229. | typespec
  230. | datadefspecs typespec
  231. { $$ = J($1, $2); }
  232. | datadefspecs gnuattribdecl typespec
  233. { $$ = J($1, $2, $3); }
  234. | externlang
  235. ;
  236. datadefx : datadefspecs decl
  237. { }
  238. optinitializer
  239. {
  240. N(add_type, $1, $2); /* Add new type if $1=typedef */
  241. $$ = J($1, $2, $4);
  242. }
  243. | datadefx ',' decl
  244. { }
  245. optinitializer
  246. {
  247. N(add_type, $1, $3); /* Add new type if $1=typedef */
  248. $$ = J($1, $2, $3, $5);
  249. }
  250. ;
  251. decl : declx
  252. | pointer declx
  253. { $$ = J($1, $2); }
  254. | gnuattribdecl decl
  255. { $$ = J($1, $2); }
  256. | pointer gnuattribdecl decl
  257. { $$ = J($1, $2, $3); }
  258. ;
  259. declx : identifier
  260. | '(' decl ')'
  261. { $$ = J($1, $2, $3); }
  262. | '(' typequallist decl ')'
  263. { $$ = J($1, $2, $3, $4); }
  264. | declx '[' optconstantexpr ']'
  265. { $$ = J($1, $2, $3, $4); }
  266. | declx '(' optparmdeflist ')'
  267. { $$ = J($1, $2, $3, $4); }
  268. | declx gnuattribdecl
  269. { $$ = J($1, $2); }
  270. | declx asmstring
  271. { $$ = J($1, $2); }
  272. ;
  273. encodeexpr : atencode '(' typename ')'
  274. { $$ = J($1, $2, $3, $4); }
  275. ;
  276. equalopexpr : relopexpr
  277. | relopexpr equalop relopexpr
  278. { $$ = J($1, $2, $3); }
  279. ;
  280. enumspec : enumkeyw identifier '{' enumlist '}'
  281. { $$ = J($1, $2, $3, $4, $5); }
  282. | enumkeyw identifier '{' enumlist ',' '}'
  283. { $$ = J($1, $2, $3, $4, $5, $6); }
  284. | enumkeyw '{' enumlist '}'
  285. { $$ = J($1, $2, $3, $4); }
  286. | enumkeyw '{' enumlist ',' '}'
  287. { $$ = J($1, $2, $3, $4, $5); }
  288. | enumkeyw identifier
  289. { $$ = J($1, $2); }
  290. ;
  291. enumlist : enumerator
  292. | enumlist enumerator
  293. { $$ = J($1, $2); }
  294. | enumlist ',' enumerator
  295. { $$ = J($1, $2, $3); }
  296. ;
  297. enumerator : identifier
  298. | identifier '=' constantexpr
  299. { $$ = J($1, $2, $3); }
  300. | cppdirect
  301. { $$ = $1; }
  302. ;
  303. expr : assignexpr
  304. | expr ',' assignexpr
  305. { $$ = J($1, $2, $3); }
  306. ;
  307. exprlist : assignexpr
  308. | exprlist ',' assignexpr
  309. { $$ = J($1, $2, $3); }
  310. ;
  311. extdef : fundef
  312. | datadef
  313. | classdef
  314. | classimpl
  315. | methoddef
  316. | atend
  317. { $$ = N(atend, $1); }
  318. | ';'
  319. | gnuasmstmt /* gcc allows asm() at toplevel */
  320. | externlangblock
  321. ;
  322. externlangblock : externlang '{' '}'
  323. { $$ = J($1, $2, $3); }
  324. | externlang '{'
  325. { }
  326. translunit '}'
  327. { $$ = J($1, $2, $4, $5); }
  328. ;
  329. funbody : /* id a,b; { } */
  330. compoundstmt
  331. | datadeflist compoundstmt
  332. { $$ = J($1, $2); }
  333. ;
  334. fundef : decl /* f(id z) { } */
  335. { }
  336. funbody
  337. { $$ = J($1, $3); }
  338. | datadefspecs decl /* id f(id z) { } */
  339. { }
  340. funbody
  341. { $$ = J($1, $2, $4); }
  342. ;
  343. nestedfundef : datadefspecs decl /* id f(id z) { } */
  344. { }
  345. compoundstmt
  346. { $$ = J($1, $2, $4); }
  347. ;
  348. /* gcc stuff like : asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
  349. gnuasmstmt : asmkeyw opttypequal '(' expr ')' ';'
  350. { $$ = J($1, $2, $3, $4, $5, $6); }
  351. | asmkeyw opttypequal '(' expr ':' asmops ')' ';'
  352. { $$ = J($1, $2, $3, $4, $5, $6, $7, $8); }
  353. | asmkeyw opttypequal '(' expr ':' asmops ':' asmops ')' ';'
  354. { $$ = J($1, $2, $3, $4, $5, $6, $7, $8, $9, $10); }
  355. | asmkeyw opttypequal '(' expr ':' asmops ':' asmops ':' asmclobbers ')' ';'
  356. { $$ = J($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); }
  357. ;
  358. gnuattribdecl : attributekeyw '(' '(' gnuattriblist ')' ')'
  359. { $$ = J($1, $2, $3, $4, $5, $6); }
  360. ;
  361. gnuattrib : /* empty */
  362. { $$ = NEW_EMPTY; }
  363. | anyword
  364. | anyword '(' exprlist ')'
  365. { $$ = J($1, $2, $3, $4); }
  366. ;
  367. initializer : assignexpr
  368. | identifier ':' assignexpr
  369. { $$ = J($1, $2, $3); }
  370. | '.' identifier assignexpr
  371. { $$ = J($1, $2, $3); }
  372. | '{' initializerlist '}'
  373. { $$ = J($1, $2, $3); }
  374. | '{' initializerlist ',' '}'
  375. { $$ = J($1, $2, $3, $4); }
  376. ;
  377. initializerlist : initializer
  378. | initializerlist ',' initializer
  379. { $$ = J($1, $2, $3); }
  380. ;
  381. identifiers : identifier
  382. | identifiers ',' identifier
  383. { $$ = J($1, $2, $3); }
  384. ;
  385. ivardef : '{' '}'
  386. { $$ = &PL_sv_undef; }
  387. | '{' componentdeflist '}'
  388. { $$ = J($1, $2, $3); }
  389. ;
  390. keywarglist : keywarg
  391. { $$ = N(keywarg_add, $1); }
  392. | keywarglist keywarg
  393. { $$ = N(keywarg_add, $2, $1); }
  394. ;
  395. keywarg : unaryselector ':' { } expr
  396. { $$ = N(keywarg, $4, $1); }
  397. | ':' { } expr
  398. { $$ = N(keywarg, $3); }
  399. ;
  400. keywdecl : unaryselector ':' identifier
  401. { $$ = N(keywdecl, $1, &PL_sv_undef, $3); }
  402. | unaryselector ':' '(' typename ')' identifier
  403. { $$ = N(keywdecl, $1, $4, $6); }
  404. | ':' identifier
  405. { $$ = N(keywdecl, &PL_sv_undef, &PL_sv_undef, $2); }
  406. | ':' '(' typename ')' identifier
  407. { $$ = N(keywdecl, &PL_sv_undef, $3, $5); }
  408. ;
  409. keywselector : keywdecl
  410. { $$ = N(keywdecl_add, $1); }
  411. | keywselector keywdecl
  412. { $$ = N(keywdecl_add, $2, $1); }
  413. ;
  414. logandexpr : orexpr
  415. | logandexpr logand orexpr
  416. { $$ = J($1, $2, $3); }
  417. ;
  418. logorexpr : logandexpr
  419. | logorexpr logor logandexpr
  420. { $$ = J($1, $2, $3); }
  421. ;
  422. methoddef : '+' methodproto ';'
  423. { $$ = N(methoddef, $1, $2, $3); }
  424. | '-' methodproto ';'
  425. { $$ = N(methoddef, $1, $2, $3); }
  426. | '+' methodproto
  427. { }
  428. compoundstmt
  429. { $$ = N(methoddef, $1, $2, $4); }
  430. | '-' methodproto
  431. { }
  432. compoundstmt
  433. { $$ = N(methoddef, $1, $2, $4); }
  434. ;
  435. methodproto : '(' typename ')' unaryselector
  436. { $$ = N(methodproto, $2, $4); }
  437. | '(' typename ')' keywselector
  438. { $$ = N(methodproto, $2, $4); }
  439. | '(' typename ')' keywselector ',' ellipsis
  440. { $$ = N(methodproto, $2, $4, $6); }
  441. | unaryselector
  442. { $$ = N(methodproto, &PL_sv_undef, $1); }
  443. | keywselector
  444. { $$ = N(methodproto, &PL_sv_undef, $1); }
  445. | keywselector ',' ellipsis /* +sprintf:(char*)format,... */
  446. { $$ = N(methodproto, &PL_sv_undef, $1, $3); }
  447. ;
  448. msgargs : unaryselector
  449. | keywarglist
  450. ;
  451. msgexpr : '[' { } expr { } msgargs ']'
  452. { $$ = N(msgexpr, $3, $5); } /* XXX faut virer ] et laisser le reste */
  453. ;
  454. mixeddatastmtlist : datadeflist
  455. | datadeflist stmtlist
  456. { $$ = J($1, $2); }
  457. | datadeflist stmtlist mixeddatastmtlist
  458. { $$ = J($1, $2, $3); }
  459. ;
  460. optbuiltinfunargs : /* empty */
  461. { $$ = NEW_EMPTY; }
  462. | builtinfunargs
  463. ;
  464. optexpr : /* empty */
  465. { $$ = NEW_EMPTY; }
  466. | expr
  467. ;
  468. optexprlist : /* empty */
  469. { $$ = NEW_EMPTY; }
  470. | exprlist
  471. ;
  472. optconstantexpr : /* empty */
  473. { $$ = NEW_EMPTY; }
  474. | constantexpr
  475. ;
  476. optinitializer : /* empty */
  477. { $$ = NEW_EMPTY; }
  478. | '=' initializer
  479. { $$ = J($1, $2); }
  480. ;
  481. opttypequal : /* empty */
  482. { $$ = NEW_EMPTY; }
  483. | typequal
  484. ;
  485. optparmdeflist : /* empty */
  486. { $$ = NEW_EMPTY; }
  487. | ellipsis
  488. | identifiers
  489. | parmdeflist
  490. | parmdeflist ',' ellipsis
  491. { $$ = J($1, $2, $3); }
  492. ;
  493. orexpr : caretexpr
  494. | orexpr '|' caretexpr
  495. { $$ = J($1, $2, $3); }
  496. ;
  497. plusexpr : timesexpr
  498. | plusexpr '+' timesexpr
  499. { $$ = J($1, $2, $3); }
  500. | plusexpr '-' timesexpr
  501. { $$ = J($1, $2, $3); }
  502. ;
  503. ppiname : identifier
  504. ;
  505. ppinamelist : ppiname
  506. | ppinamelist ',' ppiname
  507. { $$ = J($1, $2, $3); }
  508. ;
  509. primaryexpr : identifier
  510. | constant
  511. | stringchain
  512. | ellipsis
  513. | '(' expr ')'
  514. { $$ = J($1, $2, $3); }
  515. | '(' compoundstmt ')' /* gnu braced group ({ ... }) */
  516. { $$ = J($1, $2, $3); }
  517. | primaryexpr '[' expr ']' %prec hyperunary
  518. { $$ = J($1, $2, $3, $4); }
  519. | primaryexpr '(' optexprlist ')' %prec hyperunary
  520. { $$ = J($1, $2, $3, $4); }
  521. | primaryexpr '(' compoundstmt ')' %prec hyperunary
  522. { $$ = J($1, $2, $3, $4); }
  523. | primaryexpr '.' identifier
  524. { $$ = J($1, $2, $3); }
  525. | primaryexpr '.' typeword
  526. { $$ = J($1, $2, $3); }
  527. | primaryexpr arrow identifier
  528. { $$ = J($1, $2, $3); }
  529. | primaryexpr arrow typeword
  530. { $$ = J($1, $2, $3); }
  531. | mccclass arrow identifier
  532. { $$ = J(N(class2mcc, $1), $2, $3); }
  533. | mccclass arrow typeword
  534. { $$ = J(N(class2mcc, $1), $2, $3); }
  535. | primaryexpr plusplus
  536. { $$ = J($1, $2); }
  537. | msgexpr
  538. | selectorexpr
  539. | encodeexpr
  540. ;
  541. parmdeflist : parmdef
  542. | parmdeflist ',' parmdef
  543. { $$ = J($1, $2, $3); }
  544. ;
  545. parmdef : typespeclist
  546. | storageclass typespeclist
  547. { $$ = J($1, $2); }
  548. | typespeclist abstrdecl /* unsigned char* */
  549. { $$ = J($1, $2); }
  550. | storageclass typespeclist abstrdecl
  551. { $$ = J($1, $2, $3); }
  552. | typespeclist decl /* unsigned char*c */
  553. { $$ = J($1, $2); }
  554. | storageclass typespeclist decl
  555. { $$ = J($1, $2, $3); }
  556. ;
  557. pointer : '*'
  558. | '*' typespeclist
  559. { $$ = J($1, $2); }
  560. | '*' pointer
  561. { $$ = J($1, $2); }
  562. | '*' typespeclist pointer
  563. { $$ = J($1, $2); }
  564. ;
  565. relopexpr : shiftexpr
  566. | relopexpr relop shiftexpr
  567. { $$ = J($1, $2, $3); }
  568. ;
  569. requiresclause : atrequires ppinamelist ';'
  570. { warn("ignoring @requires"); }
  571. ;
  572. reservedword : enumkeyw | structkeyw | ifkeyw | elsekeyw | whilekeyw
  573. | dokeyw | forkeyw | switchkeyw | casekeyw | defaultkeyw | breakkeyw
  574. | continuekeyw | returnkeyw | gotokeyw | asmkeyw | sizeofop
  575. | typequal
  576. ;
  577. selectorarg : unaryselector
  578. | selectorarg ':' /* add:: */
  579. { $$ = J($1, $2); }
  580. | selectorarg unaryselector ':' /* add:modulo: */
  581. { $$ = J($1, $2, $3); }
  582. ;
  583. selectorexpr : atselector '(' selectorarg ')'
  584. { $$ = J($1, $2, $3, $4); }
  585. ;
  586. shiftexpr : plusexpr
  587. | plusexpr shift plusexpr
  588. { $$ = J($1, $2, $3); }
  589. ;
  590. structspec : structkeyw identifier '{' optcomponentdeflist '}'
  591. { $$ = J($1, $2, $3, $4, $5); }
  592. | structkeyw typeword '{' optcomponentdeflist '}'
  593. { $$ = J($1, $2, $3, $4, $5); }
  594. | structkeyw '{' optcomponentdeflist '}'
  595. { $$ = J($1, $2, $3, $4); }
  596. | structkeyw identifier
  597. { $$ = J($1, $2); }
  598. | structkeyw typeword
  599. { $$ = J($1, $2); }
  600. | structspec gnuattribdecl
  601. { $$ = J($1, $2); }
  602. ;
  603. optcomponentdeflist : /* empty */
  604. { $$ = NEW_EMPTY; }
  605. | componentdeflist
  606. ;
  607. componentdeflist : componentdef
  608. | componentdeflist componentdef
  609. { $$ = J($1, $2); }
  610. | atdefs '(' identifier ')'
  611. { $$ = J($1, $2, $3, $4); }
  612. | componentdeflist atdefs '(' identifier ')'
  613. { $$ = J($1, $2, $3, $4, $5); }
  614. ;
  615. componentdef : componentdefx ';'
  616. { $$ = J($1, $2); }
  617. | typespeclist ';'
  618. { $$ = J($1, $2); }
  619. | cppdirect
  620. { $$ = $1; }
  621. ;
  622. componentdefx : typespeclist bitfielddecl
  623. { $$ = J($1, $2); }
  624. | componentdefx ',' bitfielddecl
  625. { $$ = J($1, $2, $3); }
  626. ;
  627. bitfielddecl : decl
  628. | ':' constantexpr
  629. { $$ = J($1, $2); }
  630. | decl ':' constantexpr
  631. { $$ = J($1, $2, $3); }
  632. ;
  633. stmt : stmtrc
  634. ;
  635. stmtrc : optexpr ';'
  636. { $$ = J($1, $2); }
  637. | compoundstmt
  638. | identifier ':' stmt
  639. { $$ = J($1, $2, $3); }
  640. | casekeyw constantexpr ':' stmt
  641. { $$ = J($1, $2, $3, $4); }
  642. | casekeyw constantexpr ellipsis constantexpr ':' stmt
  643. { $$ = J($1, $2, $3, $4, $5, $6); }
  644. | defaultkeyw ':' stmt
  645. { $$ = J($1, $2, $3); }
  646. | ifkeyw '(' expr ')' stmt %prec ifkeyw
  647. { $$ = J($1, $2, $3, $4, $5); }
  648. | ifkeyw '(' expr ')' stmt elsekeyw stmt
  649. { $$ = J($1, $2, $3, $4, $5, $6, $7); }
  650. | ifkeyw '(' expr ')' stmt cppdirect elsekeyw stmt
  651. { $$ = J($1, $2, $3, $4, $5, $6, $7, $8); }
  652. | switchkeyw '(' expr ')' stmt
  653. { $$ = J($1, $2, $3, $4, $5); }
  654. | whilekeyw '(' expr ')' stmt
  655. { $$ = J($1, $2, $3, $4, $5); }
  656. | dokeyw stmt whilekeyw '(' expr ')' ';'
  657. { $$ = J($1, $2, $3, $4, $5, $6, $7); }
  658. | forkeyw '(' optexpr ';' optexpr ';' optexpr ')' stmt
  659. { $$ = J($1, $2, $3, $4, $5, $6, $7, $8, $9); }
  660. | gotokeyw identifier ';'
  661. { $$ = J($1, $2, $3); }
  662. | gotokeyw '*' expr ';'
  663. { $$ = J($1, $2, $3, $4); }
  664. | continuekeyw ';'
  665. { $$ = J($1, $2); }
  666. | breakkeyw ';'
  667. { $$ = J($1, $2); }
  668. | returnkeyw ';'
  669. { $$ = J($1, $2); }
  670. | returnkeyw expr ';'
  671. { $$ = J($1, $2, $3); }
  672. | gnuasmstmt
  673. | cppdirect
  674. { $$ = $1; }
  675. ;
  676. stmtlist : stmt
  677. | stmtlist stmt
  678. { $$ = J($1, $2); }
  679. ;
  680. stringchain : stringcomp /* string continuation */
  681. | stringchain stringcomp
  682. { $$ = J($1, $2); }
  683. ;
  684. timesexpr : castexpr
  685. | timesexpr '*' castexpr
  686. { $$ = J($1, $2, $3); }
  687. | timesexpr '/' castexpr
  688. { $$ = J($1, $2, $3); }
  689. | timesexpr '%' castexpr
  690. { $$ = J($1, $2, $3); }
  691. ;
  692. translunit : extdef
  693. {
  694. N(output_top_level, $1);
  695. if (yychar == -1)
  696. ps_last_lex_token = NULL;
  697. ps_last_token = $$ = NULL;
  698. }
  699. | translunit extdef
  700. {
  701. N(output_top_level, $2);
  702. if (yychar == -1)
  703. ps_last_lex_token = NULL;
  704. ps_last_token = $$ = NULL;
  705. }
  706. ;
  707. typename : typespeclist /* unsigned char */
  708. | typespeclist abstrdecl /* unsigned char* */
  709. { $$ = J($1, $2); }
  710. ;
  711. typespec : typeword
  712. | mccclass
  713. | typequal
  714. | structspec cppdirect
  715. { $$ = J($1, $2); }
  716. | structspec
  717. | enumspec
  718. | gnuextension
  719. | typeofop '(' expr ')'
  720. { $$ = J($1, $2, $3, $4); }
  721. ;
  722. typespeclist : typespec
  723. | typespeclist typespec
  724. { $$ = J($1, $2); }
  725. ;
  726. typequallist : typequal
  727. | typequallist typequal
  728. { $$ = J($1, $2); }
  729. ;
  730. unaryexpr : primaryexpr
  731. | mccclass
  732. { $$ = N(class2mcc, $1); }
  733. | plusplus castexpr %prec unary
  734. { $$ = J($1, $2); }
  735. | unary castexpr %prec unary
  736. { $$ = J($1, $2); }
  737. | '!' castexpr %prec unary
  738. { $$ = J($1, $2); }
  739. | '~' castexpr %prec unary
  740. { $$ = J($1, $2); }
  741. | '&' castexpr %prec unary
  742. { $$ = J($1, $2); }
  743. | '*' castexpr %prec unary
  744. { $$ = J($1, $2); }
  745. | '+' castexpr %prec unary
  746. { $$ = J($1, $2); }
  747. | '-' castexpr %prec unary
  748. { $$ = J($1, $2); }
  749. | sizeofop unaryexpr %prec unary
  750. { $$ = J($1, $2); }
  751. | sizeofop '(' typename ')' %prec hyperunary
  752. { $$ = J($1, $2, $3, $4); }
  753. | builtinfun '(' optbuiltinfunargs ')' %prec hyperunary
  754. { $$ = J($1, $2, $3, $4); }
  755. | gnuextension castexpr %prec unary
  756. { $$ = J($1, $2); }
  757. | logand identifier
  758. { $$ = J($1, $2); }
  759. ;
  760. unaryselector : identifier | reservedword | typeword | builtinfun | mccclass
  761. ;
  762. %%