PageRenderTime 69ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/q-7.11/src/qc.y

#
Happy | 2193 lines | 1917 code | 276 blank | 0 comment | 0 complexity | 21795b0ef7f5c4c6fb9d19812dbf976d MD5 | raw file
Possible License(s): GPL-2.0
  1. /* expect 3 shift/reduce, 82 reduce/reduce */
  2. %{
  3. /* qc.y: yacc source of Q parser and Q compiler main program */
  4. /* Special case constructs (unary minus) and dangling else cause a number of
  5. parsing conflicts which are resolved correctly. */
  6. /* Q eQuational Programming System
  7. Copyright (c) 1991-2002 by Albert Graef
  8. <ag@muwiinfa.geschichte.uni-mainz.de>
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 1, or (at your option)
  12. any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include "qcdefs.h"
  22. int nerrs, nwarns;
  23. bool dflag, hflag, nflag, vflag, Vflag, wflag;
  24. volatile bool int_sig;
  25. char *self = "qc", *list = "";
  26. char signon[] = QC_SIGNON;
  27. char usage[] = QC_USAGE;
  28. char opts[4096];
  29. char copying[] = COPYING;
  30. char helpmsg[] = HELPMSG;
  31. DECLARE_YYTEXT
  32. extern int context, dcontext;
  33. static int type, fno_min, fno_max;
  34. static short flags, sflags;
  35. static unsigned long argv;
  36. static int qualtest = 0;
  37. static int isvsym(char *s);
  38. static void start_qualifiers(void), qualifiers(void);
  39. static void add_qualifier(EXPR *x);
  40. static void start_where_clauses(void), end_where_clauses(void),
  41. add_where_clause(EXPR *l, EXPR *r);
  42. static xvect_t *exprlist(void);
  43. static xvect_t *addexpr(xvect_t *v, EXPR *x);
  44. static xvect_t *groupexpr(xvect_t *v);
  45. static EXPR *tupleexpr(xvect_t *v);
  46. static EXPR *listexpr(xvect_t *v);
  47. static EXPR *streamexpr(xvect_t *v);
  48. %}
  49. %union {
  50. int ival;
  51. mpz_t zval;
  52. double fval;
  53. char *sval;
  54. EXPR *xval;
  55. xvect_t *xvval;
  56. }
  57. /* keywords and multi-character literals: */
  58. %token AS CONST DEF ELSE EXTERN FROM IF IMPORT INCLUDE OTHERWISE
  59. %token PRIVATE PUBLIC SPECIAL THEN TYPE UNDEF VAR VIRTUAL WHERE
  60. %token DOTDOT EQUIV
  61. /* identifiers and constants: */
  62. %token <ival> STR
  63. %token <sval> UID LID QUID QLID ID1 STR1
  64. %token <zval> INT
  65. %token <fval> FLOAT
  66. /* user-defined operators */
  67. %token <ival> OP0 OP1 OP2 OP3 OP4 OP5 OP6 OP7 OP8 OP9
  68. /* special tokens */
  69. %token ERRTOK EOFTOK
  70. /* ccc, xxx: identifiers in special declaration contexts. CAUTION: These must
  71. only be used in contexts where no lookahead is needed, so that the symbol
  72. to be handled has not been processed by the lexer already! */
  73. %type <ival> cccnid cccnfid
  74. /* CAUTION: The xxx nonterminals return unnormalized identifiers! */
  75. %type <ival> xxxqid xxxqfid xxxqfvid xxxqfid_or_op xxxqfid_or_op2 xxxqtid
  76. %type <ival> id nid fid nfid vid tid ntid fvid nfvid qvid vid_list
  77. %type <ival> opt_type type_alias id_alias op_alias op_prec
  78. %type <xval> condition
  79. %type <xval> lexpression0 llambda0 lsequence0 lcond0 lrightapp0 lrelation0
  80. %type <xval> expression0 lambda0 sequence0 cond0 rightapp0 relation0
  81. %type <xval> lexpression llambda lsequence lcond lrightapp lrelation laddition
  82. %type <xval> lmultiplication lunary lscript lcomposition lapplication lprimary
  83. %type <xval> expression lambda sequence cond rightapp relation addition
  84. %type <xval> multiplication unary script composition application primary atom
  85. %type <xvval> lexpr_list expr_list lexpr_list1 expr_list1 lexpr_list2 expr_list2
  86. %type <ival> op builtin_op seqop rappop relop0 relop addop mulop unop scriptop compop quoteop
  87. %type <sval> module_id
  88. %start source
  89. %%
  90. /* error recovery is fairly simplistic (panic mode with ';' as stop symbol),
  91. I should really work out something more sophisticated in the future -AG */
  92. source : { srcstate(); }
  93. program
  94. ;
  95. program : /* empty */
  96. | program imports ';'
  97. { import(); newdecl(); }
  98. | program includes ';'
  99. { include(); newdecl(); }
  100. | program named_imports ';'
  101. { import(); newdecl(); }
  102. | program named_includes ';'
  103. { include(); newdecl(); }
  104. | program priority
  105. { newdecl(); }
  106. | program declaration
  107. { newdecl(); }
  108. | program definition
  109. { newrule(); }
  110. | program rule
  111. { newrule(); }
  112. | program EOFTOK { wrapover(); }
  113. | program error { if (yychar == EOFTOK) wrapover(); }
  114. stopsyms
  115. { yyerrok; srcstate(); newrule(); newdecl(); clear_imports(); }
  116. ;
  117. stopsyms : ';' | EOFTOK
  118. ;
  119. imports : IMPORT import
  120. | imports ',' import
  121. ;
  122. includes : INCLUDE import
  123. | includes ',' import
  124. ;
  125. import : module_id
  126. { add_import($1, NULL); }
  127. | module_id AS module_id
  128. { add_import($1, $3); }
  129. ;
  130. module_id : ID1
  131. | STR1
  132. ;
  133. named_imports : FROM import IMPORT opt_imported_names
  134. ;
  135. named_includes : FROM import INCLUDE opt_imported_names
  136. ;
  137. opt_imported_names
  138. : /* empty: create a dummy list */
  139. { add_import_name(NULL, NULL); }
  140. | imported_names
  141. ;
  142. imported_names : imported_name
  143. | imported_names ',' imported_name
  144. ;
  145. imported_name : ID1
  146. { add_import_name($1, NULL); }
  147. | ID1 AS ID1
  148. { add_import_name($1, $3); }
  149. ;
  150. priority : '@' INT
  151. { priority($2); mpz_clear($2); }
  152. | '@' OP3 INT
  153. { if ($2 != ADDOP) {
  154. yyerror(qcmsg[SYNTAX_ERROR]);
  155. YYERROR;
  156. } else {
  157. priority($3); mpz_clear($3);
  158. }
  159. }
  160. | '@' '-' INT
  161. { mpz_neg($3,$3);
  162. priority($3); mpz_clear($3); }
  163. ;
  164. declaration : prefix
  165. { type = 0; }
  166. headers ';'
  167. | TYPE xxxqtid type_alias ';'
  168. { if ($2 == NONE)
  169. ;
  170. else if (!(symtb[$2].flags&DCL)) {
  171. yyerror(qcmsg[AS_DCL_ERROR]);
  172. YYERROR;
  173. } else
  174. astype($2, $3, flags); }
  175. | scope TYPE xxxqtid type_alias ';'
  176. { if ($3 == NONE)
  177. ;
  178. else if (!(symtb[$3].flags&DCL)) {
  179. yyerror(qcmsg[AS_DCL_ERROR]);
  180. YYERROR;
  181. } else
  182. astype($3, $4, flags); }
  183. | TYPE ntid EQUIV tid ';'
  184. { if (checktype($4) != NONE &&
  185. (symtb[$4].flags&DCL))
  186. astype($4, $2, flags); }
  187. | scope TYPE ntid EQUIV tid ';'
  188. { if (checktype($5) != NONE &&
  189. (symtb[$5].flags&DCL))
  190. astype($5, $3, flags); }
  191. | TYPE ntid opt_type
  192. { type = dcltype($2, $3, flags);
  193. sflags = flags; fno_min = symtbsz; }
  194. opt_header_sects ';'
  195. { /* check for enumeration type */
  196. int enumtype = 1, i;
  197. fno_max = symtbsz-1;
  198. for (i = fno_min; i <= fno_max; i++)
  199. if (!(symtb[i].flags & CST) ||
  200. (symtb[i].flags & VIRT) ||
  201. symtb[i].argc > 0) {
  202. enumtype = 0; break;
  203. }
  204. if (enumtype && type) {
  205. symtb[type].fno_min = fno_min;
  206. symtb[type].fno_max = fno_max;
  207. }
  208. }
  209. | scope TYPE ntid opt_type
  210. { type = dcltype($3, $4, flags);
  211. sflags = flags; fno_min = symtbsz; }
  212. opt_header_sects ';'
  213. { int enumtype = 1, i;
  214. fno_max = symtbsz-1;
  215. for (i = fno_min; i <= fno_max; i++)
  216. if (!(symtb[i].flags & CST) ||
  217. (symtb[i].flags & VIRT) ||
  218. symtb[i].argc > 0) {
  219. enumtype = 0; break;
  220. }
  221. if (enumtype && type) {
  222. symtb[type].fno_min = fno_min;
  223. symtb[type].fno_max = fno_max;
  224. }
  225. }
  226. | EXTERN TYPE ntid opt_type
  227. { type = dcltype($3, $4, flags|EXT);
  228. sflags = flags; }
  229. opt_header_sects ';'
  230. | scope EXTERN TYPE ntid opt_type
  231. { type = dcltype($4, $5, flags|EXT);
  232. sflags = flags; }
  233. opt_header_sects ';'
  234. ;
  235. type_alias : /* empty */
  236. { $$ = 0; }
  237. | AS ntid
  238. { $$ = $2; }
  239. ;
  240. opt_type : /* empty */
  241. { $$ = 0; }
  242. | ':' tid
  243. { $$ = checktype($2); }
  244. ;
  245. opt_header_sects: /* empty */
  246. | '=' header_sects
  247. ;
  248. header_sects : header_sect
  249. | header_sects '|' header_sect
  250. ;
  251. header_sect : { flags = sflags; }
  252. opt_prefix headers
  253. ;
  254. prefix : scope
  255. | modifiers
  256. | scope modifiers
  257. ;
  258. opt_prefix : /* empty */
  259. | prefix
  260. ;
  261. scope : PRIVATE
  262. { flags = PRIV; }
  263. | PUBLIC
  264. { flags = 0; }
  265. ;
  266. modifiers : modifier
  267. | modifiers modifier
  268. ;
  269. modifier : CONST
  270. { flags |= CST; }
  271. | SPECIAL
  272. { flags |= SPEC; }
  273. | EXTERN
  274. { flags |= EXT; }
  275. | VAR
  276. { flags |= VSYM; }
  277. | VIRTUAL
  278. { flags |= VIRT; }
  279. ;
  280. headers : header
  281. | headers ',' { argv = 0; } header
  282. ;
  283. header : nid '=' { if ($1 == NONE)
  284. YYERROR;
  285. else if ((symtb[$1].flags & DCL) &&
  286. symtb[$1].modno == modno &&
  287. (symtb[$1].flags & VSYM) !=
  288. (flags & VSYM)) {
  289. char msg[MAXSTRLEN];
  290. sprintf(msg, qcmsg[MISM_DCL],
  291. utf8_to_sys(strsp+symtb[$1].pname));
  292. yyerror(msg);
  293. YYERROR;
  294. } else if (!(flags & VSYM) || type ||
  295. (flags & (EXT|SPEC|VIRT))) {
  296. yyerror(qcmsg[DCL_ERROR]);
  297. YYERROR;
  298. } else {
  299. int vno = dclfvar($1, flags);
  300. init_def(); $<xval>$ = funexpr(vno);
  301. debug_info();
  302. }
  303. }
  304. expression0
  305. { definition($<xval>3, $4); }
  306. | nid vid_list
  307. { if ($1 == NONE)
  308. ;
  309. else if ((symtb[$1].flags & DCL) &&
  310. symtb[$1].modno == modno &&
  311. (symtb[$1].flags & VSYM) !=
  312. (flags & VSYM)) {
  313. char msg[MAXSTRLEN];
  314. sprintf(msg, qcmsg[MISM_DCL],
  315. utf8_to_sys(strsp+symtb[$1].pname));
  316. yyerror(msg);
  317. YYERROR;
  318. } else if ((flags & VSYM) && ($2 || type) ||
  319. (flags & VSYM) &&
  320. (flags & (EXT|SPEC|VIRT)) ||
  321. (flags & CST) && (flags & EXT) ||
  322. type &&
  323. (symtb[type].flags & EXT) &&
  324. !(flags & VIRT) ||
  325. !(flags & VSYM) &&
  326. isvsym(strsp+symtb[$1].pname)) {
  327. yyerror(qcmsg[DCL_ERROR]);
  328. YYERROR;
  329. } else if (flags & VSYM)
  330. dclfvar($1, flags);
  331. else
  332. dclfun($1, type, $2, argv, flags, NONE); }
  333. | '(' cccnfid ')' vid_list op_prec
  334. { int prec = $5;
  335. if (prec == NONE && $2 != NONE &&
  336. symtb[$2].modno == modno)
  337. prec = symtb[$2].prec;
  338. if (prec == NONE) prec = 2;
  339. if ($2 == NONE)
  340. ;
  341. else if ((flags & VSYM) ||
  342. (flags & CST) && (flags & EXT) ||
  343. type && (symtb[type].flags & EXT) &&
  344. !(flags & VIRT) ||
  345. (prec == 5 || prec == 9) && $4 != 1 ||
  346. (prec != 5 && prec != 9) && $4 != 2) {
  347. yyerror(qcmsg[DCL_ERROR]);
  348. YYERROR;
  349. } else
  350. dclfun($2, type, $4, argv, flags, prec); }
  351. | xxxqid vid_list id_alias
  352. { int sym = $1; $1 = xxxsym($1);
  353. if ($1 == NONE)
  354. ;
  355. else if (!(symtb[$1].flags&DCL)) {
  356. yyerror(qcmsg[AS_DCL_ERROR]);
  357. YYERROR;
  358. } else if ((symtb[$1].flags & DCL) &&
  359. (symtb[$1].flags & VSYM) !=
  360. (flags & VSYM)) {
  361. char msg[MAXSTRLEN];
  362. sprintf(msg, qcmsg[MISM_DCL],
  363. utf8_to_sys(strsp+symtb[$1].pname));
  364. yyerror(msg);
  365. YYERROR;
  366. } else if ((flags & VSYM) && ($2 || type) ||
  367. (flags & VSYM) && (flags & (EXT|SPEC|VIRT)) ||
  368. (flags & CST) && (flags & EXT) ||
  369. !(flags & VSYM) &&
  370. isvsym(strsp+symtb[$1].pname) ||
  371. type ||
  372. $3 && symtb[$3].modno == modno &&
  373. (symtb[$3].flags&DCL)) {
  374. yyerror(qcmsg[DCL_ERROR]);
  375. YYERROR;
  376. } else if (flags & VSYM)
  377. asfvar(sym, $3, flags);
  378. else
  379. asfun(sym, $3, $2, argv, flags, NONE); }
  380. | '(' xxxqfid_or_op ')' vid_list op_prec op_alias
  381. { int sym = $2; $2 = xxxsym($2);
  382. int prec = $5;
  383. if (prec == NONE && $2 != NONE)
  384. prec = symtb[$2].prec;
  385. if ($2 == NONE)
  386. ;
  387. else if (!(symtb[$2].flags&DCL)) {
  388. yyerror(qcmsg[AS_DCL_ERROR]);
  389. YYERROR;
  390. } else if ((flags & VSYM) ||
  391. (flags & CST) && (flags & EXT) ||
  392. type ||
  393. $6 && symtb[$6].modno == modno &&
  394. (symtb[$6].flags&DCL) ||
  395. prec == NONE ||
  396. (prec == 5 || prec == 9) && $4 != 1 ||
  397. (prec != 5 && prec != 9) && $4 != 2) {
  398. yyerror(qcmsg[DCL_ERROR]);
  399. YYERROR;
  400. } else
  401. asfun(sym, $6, $4, argv, flags, prec); }
  402. ;
  403. vid_list : /* empty */
  404. { $$ = 0; }
  405. | vid_list UID
  406. { if (flags & SPEC)
  407. if ($1 < sizeof(unsigned long)*8)
  408. argv |= 1<<$1;
  409. else {
  410. yyerror(qcmsg[DCL_ERROR]);
  411. YYERROR;
  412. }
  413. $$ = $1+1; }
  414. | vid_list '~' UID
  415. { if (!(flags & SPEC)) {
  416. yyerror(qcmsg[DCL_ERROR]);
  417. YYERROR;
  418. }
  419. $$ = $1+1; }
  420. ;
  421. op_prec : /* empty */
  422. { $$ = NONE; }
  423. | '@' INT
  424. { $$ = precval($2); }
  425. | '@' '(' op ')'
  426. { int prec = symtb[$3].prec;
  427. if (prec >= 0 && prec <= 9 && prec != 8)
  428. $$ = prec;
  429. else {
  430. yyerror(qcmsg[INVALID_PREC]);
  431. $$ = NONE;
  432. }
  433. }
  434. ;
  435. id_alias : /* empty */
  436. { $$ = 0; }
  437. | AS nid
  438. { $$ = $2; }
  439. ;
  440. op_alias : /* empty */
  441. { $$ = 0; }
  442. | AS cccnid
  443. { $$ = $2; }
  444. ;
  445. definition : DEF defs ';'
  446. | UNDEF undefs ';'
  447. ;
  448. defs : def
  449. | defs ',' def
  450. ;
  451. def : { init_def(); }
  452. lexpression0 '='
  453. { debug_info(); }
  454. expression0
  455. { definition($2, $5); }
  456. ;
  457. undefs : undef
  458. | undefs ',' undef
  459. ;
  460. undef : id
  461. { if ($1 != NONE) {
  462. init_def();
  463. if (!(symtb[$1].flags & VSYM))
  464. yyerror(qcmsg[INVALID_DEF]);
  465. else {
  466. symtb[$1].flags |= DCL;
  467. debug_info();
  468. definition(funexpr($1), NULL);
  469. }
  470. }
  471. }
  472. ;
  473. rule : lexpression0
  474. { debug_info(); left_hand_side($1);
  475. start_qualifiers(); }
  476. body
  477. { end_rule(); }
  478. ;
  479. body : opt_qualifiers '='
  480. { begin_rule(); start_qualifiers(); }
  481. expression0 qualifiers ';'
  482. { qualifiers(); right_hand_side($4);
  483. start_qualifiers(); }
  484. | body { qualtest = 1; }
  485. opt_qualifiers2 '='
  486. { qualtest = 0;
  487. begin_rule(); start_qualifiers(); }
  488. expression0 qualifiers ';'
  489. { qualifiers(); right_hand_side($6);
  490. start_qualifiers(); }
  491. ;
  492. opt_qualifiers : /* empty */
  493. { mark(); }
  494. | lqualifiers ':'
  495. { qualifiers(); mark(); }
  496. ;
  497. opt_qualifiers2 : /* empty */
  498. | lqualifiers ':'
  499. { qualifiers(); mark(); }
  500. ;
  501. lqualifiers : lqualifier
  502. | lqualifiers lqualifier
  503. lqualifier : condition
  504. { add_qualifier($1); }
  505. | where
  506. ;
  507. qualifiers : /* empty */
  508. | qualifiers condition
  509. { add_qualifier($2); }
  510. | qualifiers where
  511. ;
  512. condition : IF { if (qualtest) qualtest = 0,
  513. same_left_hand_side(); }
  514. expression
  515. { $$ = $3; }
  516. | OTHERWISE
  517. { if (qualtest) qualtest = 0,
  518. same_left_hand_side();
  519. $$ = NULL; }
  520. ;
  521. where : WHERE
  522. { if (qualtest) qualtest = 0,
  523. same_left_hand_side();
  524. start_where_clauses(); }
  525. where_clauses
  526. { end_where_clauses(); }
  527. ;
  528. where_clauses : where_clause
  529. | where_clauses ',' where_clause
  530. ;
  531. where_clause : lexpression0 '=' expression0
  532. { add_where_clause($1, $3); }
  533. ;
  534. /* top-level expressions (= operator and if-then-else not permitted here) */
  535. lexpression0 : lsequence0
  536. | '\\' llambda0 { $$ = $2; }
  537. ;
  538. llambda0 : lprimary '.' lexpression0
  539. { $$ = binexpr(LAMBDAOP, $1, $3); }
  540. | lprimary llambda0
  541. { $$ = binexpr(LAMBDAOP, $1, $2); }
  542. ;
  543. lsequence0 : lcond0
  544. | lsequence0 seqop lcond0
  545. { $$ = binexpr($2, $1, $3); }
  546. ;
  547. lcond0 : lrightapp0
  548. /* Q 7.7: eliminated lhs toplevel if-then-else construct to resolve syntactic
  549. ambiguity with left-hand guards
  550. | IF lrightapp THEN lcond0 ELSE lcond0
  551. { static char sym[20];
  552. int fno = getfun(strcpy(sym, "cond::ifelse"));
  553. if (fno == NONE) {
  554. yyerror(qcmsg[SYNTAX_ERROR]);
  555. YYERROR;
  556. } else
  557. $$ = ternexpr(fno, $2, $4, $6); }
  558. | IF lrightapp THEN lcond0
  559. { static char sym[20];
  560. int fno = getfun(strcpy(sym, "cond::when"));
  561. if (fno == NONE) {
  562. yyerror(qcmsg[SYNTAX_ERROR]);
  563. YYERROR;
  564. } else
  565. $$ = binexpr(fno, $2, $4); }
  566. */
  567. ;
  568. lrightapp0 : lrelation0
  569. | lrelation0 rappop lrightapp0
  570. { $$ = binexpr($2, $1, $3); }
  571. ;
  572. lrelation0 : laddition
  573. | laddition relop0 laddition
  574. { $$ = binexpr($2, $1, $3); }
  575. ;
  576. expression0 : sequence0
  577. | '\\' lambda0 { $$ = $2; }
  578. ;
  579. lambda0 : primary '.' expression0
  580. { $$ = binexpr(LAMBDAOP, $1, $3); }
  581. | primary lambda0
  582. { $$ = binexpr(LAMBDAOP, $1, $2); }
  583. ;
  584. sequence0 : cond0
  585. | sequence0 seqop cond0
  586. { $$ = binexpr($2, $1, $3); }
  587. ;
  588. cond0 : rightapp0
  589. | IF rightapp THEN cond0 ELSE cond0
  590. { static char sym[20];
  591. int fno = getfun(strcpy(sym, "cond::ifelse"));
  592. if (fno == NONE) {
  593. yyerror(qcmsg[SYNTAX_ERROR]);
  594. YYERROR;
  595. } else
  596. $$ = ternexpr(fno, $2, $4, $6); }
  597. | IF rightapp THEN cond0
  598. { static char sym[20];
  599. int fno = getfun(strcpy(sym, "cond::when"));
  600. if (fno == NONE) {
  601. yyerror(qcmsg[SYNTAX_ERROR]);
  602. YYERROR;
  603. } else
  604. $$ = binexpr(fno, $2, $4); }
  605. ;
  606. rightapp0 : relation0
  607. | relation0 rappop rightapp0
  608. { $$ = binexpr($2, $1, $3); }
  609. ;
  610. relation0 : addition
  611. | addition relop0 addition
  612. { $$ = binexpr($2, $1, $3); }
  613. ;
  614. relop0 : EQUIV { $$ = IDOP; }
  615. | OP2
  616. ;
  617. /* These are duplicated from below to keep track of whether we're in the lhs
  618. of a definition. */
  619. lexpression : lsequence
  620. | '\\' llambda { $$ = $2; }
  621. ;
  622. llambda : lprimary '.' lexpression
  623. { $$ = binexpr(LAMBDAOP, $1, $3); }
  624. | lprimary llambda
  625. { $$ = binexpr(LAMBDAOP, $1, $2); }
  626. ;
  627. lsequence : lcond
  628. | lsequence seqop lcond
  629. { $$ = binexpr($2, $1, $3); }
  630. ;
  631. lcond : lrightapp
  632. | IF lrightapp THEN lcond ELSE lcond
  633. { static char sym[20];
  634. int fno = getfun(strcpy(sym, "cond::ifelse"));
  635. if (fno == NONE) {
  636. yyerror(qcmsg[SYNTAX_ERROR]);
  637. YYERROR;
  638. } else
  639. $$ = ternexpr(fno, $2, $4, $6); }
  640. | IF lrightapp THEN lcond
  641. { static char sym[20];
  642. int fno = getfun(strcpy(sym, "cond::when"));
  643. if (fno == NONE) {
  644. yyerror(qcmsg[SYNTAX_ERROR]);
  645. YYERROR;
  646. } else
  647. $$ = binexpr(fno, $2, $4); }
  648. ;
  649. lrightapp : lrelation
  650. | lrelation rappop lrightapp
  651. { $$ = binexpr($2, $1, $3); }
  652. ;
  653. lrelation : laddition
  654. | laddition relop laddition
  655. { $$ = binexpr($2, $1, $3); }
  656. ;
  657. laddition : lmultiplication
  658. | laddition addop lmultiplication
  659. { $$ = binexpr($2, $1, $3); }
  660. | laddition '-' lmultiplication
  661. { $$ = binexpr(MINOP, $1, $3); }
  662. ;
  663. lmultiplication : lunary
  664. | lmultiplication mulop lunary
  665. { $$ = binexpr($2, $1, $3); }
  666. ;
  667. /* ! ambiguous rule */
  668. lunary : lscript
  669. | '-' INT { mpz_neg($2, $2); $$ = intexpr($2); }
  670. | '-' FLOAT { $$ = floatexpr(-$2); }
  671. | '-' lunary { $$ = unexpr(UMINOP, $2); }
  672. | unop lunary { $$ = unexpr($1, $2); }
  673. lscript : lcomposition
  674. | lcomposition scriptop lscript
  675. { $$ = binexpr($2, $1, $3); }
  676. ;
  677. lcomposition : lapplication
  678. | lcomposition compop lapplication
  679. { $$ = binexpr($2, $1, $3); }
  680. ;
  681. lapplication : lprimary
  682. | lapplication lprimary
  683. { $$ = appexpr($1, $2); }
  684. ;
  685. expression : sequence
  686. | '\\' lambda { $$ = $2; }
  687. ;
  688. lambda : primary '.' expression
  689. { $$ = binexpr(LAMBDAOP, $1, $3); }
  690. | primary lambda
  691. { $$ = binexpr(LAMBDAOP, $1, $2); }
  692. ;
  693. sequence : cond
  694. | sequence seqop cond
  695. { $$ = binexpr($2, $1, $3); }
  696. ;
  697. seqop : OP0
  698. ;
  699. cond : rightapp
  700. | IF rightapp THEN cond ELSE cond
  701. { static char sym[20];
  702. int fno = getfun(strcpy(sym, "cond::ifelse"));
  703. if (fno == NONE) {
  704. yyerror(qcmsg[SYNTAX_ERROR]);
  705. YYERROR;
  706. } else
  707. $$ = ternexpr(fno, $2, $4, $6); }
  708. | IF rightapp THEN cond
  709. { static char sym[20];
  710. int fno = getfun(strcpy(sym, "cond::when"));
  711. if (fno == NONE) {
  712. yyerror(qcmsg[SYNTAX_ERROR]);
  713. YYERROR;
  714. } else
  715. $$ = binexpr(fno, $2, $4); }
  716. ;
  717. rightapp : relation
  718. | relation rappop rightapp
  719. { $$ = binexpr($2, $1, $3); }
  720. ;
  721. rappop : OP1
  722. ;
  723. relation : addition
  724. | addition relop addition
  725. { $$ = binexpr($2, $1, $3); }
  726. ;
  727. relop : '=' { $$ = EQOP; }
  728. | EQUIV { $$ = IDOP; }
  729. | OP2
  730. ;
  731. addition : multiplication
  732. | addition addop multiplication
  733. { $$ = binexpr($2, $1, $3); }
  734. | addition '-' multiplication
  735. { $$ = binexpr(MINOP, $1, $3); }
  736. ;
  737. addop : OP3 ELSE { if ($1 != OROP) {
  738. yyerror(qcmsg[SYNTAX_ERROR]);
  739. YYERROR;
  740. } else
  741. $$ = ORELSEOP; }
  742. | OP3
  743. ;
  744. multiplication : unary
  745. | multiplication mulop unary
  746. { $$ = binexpr($2, $1, $3); }
  747. ;
  748. mulop : OP4 THEN { if ($1 != ANDOP) {
  749. yyerror(qcmsg[SYNTAX_ERROR]);
  750. YYERROR;
  751. } else
  752. $$ = ANDTHENOP; }
  753. | OP4
  754. ;
  755. /* ! ambiguous rule */
  756. unary : script
  757. | '-' INT { mpz_neg($2, $2); $$ = intexpr($2); }
  758. | '-' FLOAT { $$ = floatexpr(-$2); }
  759. | '-' unary { $$ = unexpr(UMINOP, $2); }
  760. | unop unary { $$ = unexpr($1, $2); }
  761. ;
  762. unop : OP5
  763. ;
  764. script : composition
  765. | composition scriptop script
  766. { $$ = binexpr($2, $1, $3); }
  767. ;
  768. scriptop : OP6
  769. ;
  770. composition : application
  771. | composition compop application
  772. { $$ = binexpr($2, $1, $3); }
  773. ;
  774. compop : '.' { $$ = COMPOP; }
  775. | OP7
  776. ;
  777. application : primary
  778. | application primary
  779. { $$ = appexpr($1, $2); }
  780. ;
  781. quoteop : '~' { $$ = FORCEOP; }
  782. | OP9
  783. ;
  784. /* type guards are only permitted in lhs expressions */
  785. lprimary : atom
  786. | vid ':' tid { checktype($3); vartb[$1].type = $3;
  787. $$ = varexpr($1); }
  788. /* quoted expressions */
  789. | quoteop lprimary
  790. { $$ = unexpr($1, $2); }
  791. /* sections: */
  792. | '(' lsequence seqop ')'
  793. { $$ = appexpr(funexpr($3), $2); }
  794. | '(' seqop lrightapp ')'
  795. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  796. funexpr($2)),
  797. $3); }
  798. | '(' lrelation rappop ')'
  799. { $$ = appexpr(funexpr($3), $2); }
  800. | '(' rappop lrightapp ')'
  801. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  802. funexpr($2)),
  803. $3); }
  804. | '(' laddition relop ')'
  805. { $$ = appexpr(funexpr($3), $2); }
  806. | '(' relop laddition ')'
  807. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  808. funexpr($2)),
  809. $3); }
  810. | '(' laddition addop ')'
  811. { $$ = appexpr(funexpr($3), $2); }
  812. | '(' laddition '-' ')'
  813. { $$ = appexpr(funexpr(MINOP), $2); }
  814. | '(' addop lmultiplication ')'
  815. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  816. funexpr($2)),
  817. $3); }
  818. | '(' lmultiplication mulop ')'
  819. { $$ = appexpr(funexpr($3), $2); }
  820. | '(' mulop lunary ')'
  821. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  822. funexpr($2)),
  823. $3); }
  824. | '(' lcomposition scriptop ')'
  825. { $$ = appexpr(funexpr($3), $2); }
  826. | '(' scriptop lscript ')'
  827. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  828. funexpr($2)),
  829. $3); }
  830. | '(' lcomposition compop ')'
  831. { $$ = appexpr(funexpr($3), $2); }
  832. | '(' compop lapplication ')'
  833. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  834. funexpr($2)),
  835. $3); }
  836. /* parenthesized expressions and tuples: */
  837. | '(' ')'
  838. { $$ = funexpr(VOIDOP); }
  839. | '(' lexpression ')'
  840. { $$ = $2; }
  841. | '(' lexpression ',' ')'
  842. { $$ = pairexpr($2, funexpr(VOIDOP)); }
  843. | '(' lexpression ';' ')'
  844. { $$ = pairexpr(pairexpr($2, funexpr(VOIDOP)),
  845. funexpr(VOIDOP)); }
  846. | '(' lexpression '|' lexpression ')'
  847. { $$ = pairexpr($2, $4); }
  848. | '(' lexpression DOTDOT lexpression ')'
  849. { $$ = appexpr(appexpr(funexpr(TENUMOP),
  850. listexpr(addexpr(addexpr(exprlist(), $2),
  851. funexpr(NILOP)))),
  852. $4); }
  853. | '(' lexpression DOTDOT ')'
  854. { $$ = appexpr(funexpr(TENUM1OP),
  855. listexpr(addexpr(addexpr(exprlist(), $2),
  856. funexpr(NILOP)))); }
  857. | '(' lexpression ',' lexpr_list1 ')'
  858. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  859. | '(' lexpression ',' lexpr_list1 ',' ')'
  860. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  861. | '(' lexpression ',' lexpr_list1 ';' ')'
  862. { if ($4->m < 0) $4->m = 0;
  863. $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  864. | '(' lexpression ',' lexpr_list1 '|' lexpression ')'
  865. { $$ = tupleexpr(addexpr($4, $6)); }
  866. | '(' lexpression ',' lexpr_list1 DOTDOT lexpression ')'
  867. { $$ = appexpr(appexpr(funexpr(TENUMOP),
  868. listexpr(addexpr($4, funexpr(NILOP)))),
  869. $6); }
  870. | '(' lexpression ',' lexpr_list1 DOTDOT ')'
  871. { $$ = appexpr(funexpr(TENUM1OP),
  872. listexpr(addexpr($4, funexpr(NILOP)))); }
  873. /* handle the special case of a group of size 1 at the beginning of the
  874. tuple */
  875. | '(' lexpression ';' lexpr_list2 ')'
  876. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  877. | '(' lexpression ';' lexpr_list2 ',' ')'
  878. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  879. | '(' lexpression ';' lexpr_list2 ';' ')'
  880. { if ($4->m < 0) $4->m = 0;
  881. $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  882. | '(' lexpression ';' lexpr_list2 '|' lexpression ')'
  883. { $$ = tupleexpr(addexpr($4, $6)); }
  884. /* lists: */
  885. | '[' ']'
  886. { $$ = funexpr(NILOP); }
  887. | '[' lexpr_list ']'
  888. { $$ = listexpr(
  889. addexpr($2, funexpr(NILOP))); }
  890. | '[' lexpr_list ',' ']'
  891. { $$ = listexpr(
  892. addexpr($2, funexpr(NILOP))); }
  893. | '[' lexpr_list ';' ']'
  894. { if ($2->m < 0) $2->m = 0;
  895. $$ = listexpr(
  896. addexpr($2, funexpr(NILOP))); }
  897. | '[' lexpr_list '|' lexpression ']'
  898. { $$ = listexpr(addexpr($2, $4)); }
  899. | '[' lexpr_list DOTDOT lexpression ']'
  900. { $$ = appexpr(appexpr(funexpr(ENUMOP),
  901. listexpr(addexpr($2, funexpr(NILOP)))),
  902. $4); }
  903. | '[' lexpr_list DOTDOT ']'
  904. { $$ = appexpr(funexpr(ENUM1OP),
  905. listexpr(addexpr($2, funexpr(NILOP)))); }
  906. /* streams: */
  907. | '{' '}'
  908. { $$ = funexpr(SNILOP); }
  909. | '{' lexpr_list '}'
  910. { $$ = streamexpr(
  911. addexpr($2, funexpr(SNILOP))); }
  912. | '{' lexpr_list ',' '}'
  913. { $$ = streamexpr(
  914. addexpr($2, funexpr(SNILOP))); }
  915. | '{' lexpr_list ';' '}'
  916. { if ($2->m < 0) $2->m = 0;
  917. $$ = streamexpr(
  918. addexpr($2, funexpr(SNILOP))); }
  919. | '{' lexpr_list '|' lexpression '}'
  920. { $$ = streamexpr(addexpr($2, $4)); }
  921. | '{' lexpr_list DOTDOT lexpression '}'
  922. { $$ = appexpr(appexpr(funexpr(SENUMOP),
  923. listexpr(addexpr($2, funexpr(NILOP)))),
  924. $4); }
  925. | '{' lexpr_list DOTDOT '}'
  926. { $$ = appexpr(funexpr(SENUM1OP),
  927. listexpr(addexpr($2, funexpr(NILOP)))); }
  928. ;
  929. /* inline var declarations and list/stream comprehensions are only permitted
  930. on the rhs of definitions */
  931. primary : atom
  932. /* inline var declaration */
  933. | VAR nid { int vno = $2;
  934. if (!(symtb[vno].flags&DCL) ||
  935. symtb[vno].modno != modno ||
  936. !(symtb[vno].flags&VSYM))
  937. vno = dclfvar(vno, PRIV|VSYM);
  938. $$ = funexpr(vno); }
  939. /* quoted expressions */
  940. | quoteop primary
  941. { $$ = unexpr($1, $2); }
  942. /* sections: */
  943. | '(' sequence seqop ')'
  944. { $$ = appexpr(funexpr($3), $2); }
  945. | '(' seqop rightapp ')'
  946. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  947. funexpr($2)),
  948. $3); }
  949. | '(' relation rappop ')'
  950. { $$ = appexpr(funexpr($3), $2); }
  951. | '(' rappop rightapp ')'
  952. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  953. funexpr($2)),
  954. $3); }
  955. | '(' addition relop ')'
  956. { $$ = appexpr(funexpr($3), $2); }
  957. | '(' relop addition ')'
  958. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  959. funexpr($2)),
  960. $3); }
  961. | '(' addition addop ')'
  962. { $$ = appexpr(funexpr($3), $2); }
  963. | '(' addition '-' ')'
  964. { $$ = appexpr(funexpr(MINOP), $2); }
  965. | '(' addop multiplication ')'
  966. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  967. funexpr($2)),
  968. $3); }
  969. | '(' multiplication mulop ')'
  970. { $$ = appexpr(funexpr($3), $2); }
  971. | '(' mulop unary ')'
  972. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  973. funexpr($2)),
  974. $3); }
  975. | '(' composition scriptop ')'
  976. { $$ = appexpr(funexpr($3), $2); }
  977. | '(' scriptop script ')'
  978. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  979. funexpr($2)),
  980. $3); }
  981. | '(' composition compop ')'
  982. { $$ = appexpr(funexpr($3), $2); }
  983. | '(' compop application ')'
  984. { $$ = appexpr(appexpr(funexpr(FLIPOP),
  985. funexpr($2)),
  986. $3); }
  987. /* parenthesized expressions and tuples: */
  988. | '(' ')'
  989. { $$ = funexpr(VOIDOP); }
  990. | '(' expression ')'
  991. { $$ = $2; }
  992. | '(' expression ',' ')'
  993. { $$ = pairexpr($2, funexpr(VOIDOP)); }
  994. | '(' expression ';' ')'
  995. { $$ = pairexpr(pairexpr($2, funexpr(VOIDOP)),
  996. funexpr(VOIDOP)); }
  997. | '(' expression '|' expression ')'
  998. { $$ = pairexpr($2, $4); }
  999. | '(' expression DOTDOT expression ')'
  1000. { $$ = appexpr(appexpr(funexpr(TENUMOP),
  1001. listexpr(addexpr(addexpr(exprlist(), $2),
  1002. funexpr(NILOP)))),
  1003. $4); }
  1004. | '(' expression DOTDOT ')'
  1005. { $$ = appexpr(funexpr(TENUM1OP),
  1006. listexpr(addexpr(addexpr(exprlist(), $2),
  1007. funexpr(NILOP)))); }
  1008. | '(' expression ',' expr_list1 ')'
  1009. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1010. | '(' expression ',' expr_list1 ',' ')'
  1011. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1012. | '(' expression ',' expr_list1 ';' ')'
  1013. { if ($4->m < 0) $4->m = 0;
  1014. $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1015. | '(' expression ',' expr_list1 '|' expression ')'
  1016. { $$ = tupleexpr(addexpr($4, $6)); }
  1017. | '(' expression ',' expr_list1 DOTDOT expression ')'
  1018. { $$ = appexpr(appexpr(funexpr(TENUMOP),
  1019. listexpr(addexpr($4, funexpr(NILOP)))),
  1020. $6); }
  1021. | '(' expression ',' expr_list1 DOTDOT ')'
  1022. { $$ = appexpr(funexpr(TENUM1OP),
  1023. listexpr(addexpr($4, funexpr(NILOP)))); }
  1024. | '(' expression ':'
  1025. { static char sym[20];
  1026. int fno = getfun(strcpy(sym, "cond::tupleof"));
  1027. if (fno == NONE) {
  1028. yyerror(qcmsg[SYNTAX_ERROR]);
  1029. YYERROR;
  1030. } else
  1031. $<ival>$ = fno; }
  1032. expr_list ')'
  1033. { $$ = appexpr(appexpr(funexpr($<ival>4), $2),
  1034. tupleexpr(addexpr($5, funexpr(VOIDOP)))); }
  1035. /* handle the special case of a group of size 1 at the beginning of the
  1036. tuple */
  1037. | '(' expression ';' expr_list2 ')'
  1038. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1039. | '(' expression ';' expr_list2 ',' ')'
  1040. { $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1041. | '(' expression ';' expr_list2 ';' ')'
  1042. { if ($4->m < 0) $4->m = 0;
  1043. $$ = tupleexpr(addexpr($4, funexpr(VOIDOP))); }
  1044. | '(' expression ';' expr_list2 '|' expression ')'
  1045. { $$ = tupleexpr(addexpr($4, $6)); }
  1046. /* lists: */
  1047. | '[' ']'
  1048. { $$ = funexpr(NILOP); }
  1049. | '[' expr_list ']'
  1050. { $$ = listexpr(
  1051. addexpr($2, funexpr(NILOP))); }
  1052. | '[' expr_list ',' ']'
  1053. { $$ = listexpr(
  1054. addexpr($2, funexpr(NILOP))); }
  1055. | '[' expr_list ';' ']'
  1056. { if ($2->m < 0) $2->m = 0;
  1057. $$ = listexpr(
  1058. addexpr($2, funexpr(NILOP))); }
  1059. | '[' expr_list '|' expression ']'
  1060. { $$ = listexpr(addexpr($2, $4)); }
  1061. | '[' expr_list DOTDOT expression ']'
  1062. { $$ = appexpr(appexpr(funexpr(ENUMOP),
  1063. listexpr(addexpr($2, funexpr(NILOP)))),
  1064. $4); }
  1065. | '[' expr_list DOTDOT ']'
  1066. { $$ = appexpr(funexpr(ENUM1OP),
  1067. listexpr(addexpr($2, funexpr(NILOP)))); }
  1068. | '[' expression ':'
  1069. { static char sym[20];
  1070. int fno = getfun(strcpy(sym, "cond::listof"));
  1071. if (fno == NONE) {
  1072. yyerror(qcmsg[SYNTAX_ERROR]);
  1073. YYERROR;
  1074. } else
  1075. $<ival>$ = fno; }
  1076. expr_list ']'
  1077. { $$ = appexpr(appexpr(funexpr($<ival>4), $2),
  1078. tupleexpr(addexpr($5, funexpr(VOIDOP)))); }
  1079. /* streams: */
  1080. | '{' '}'
  1081. { $$ = funexpr(SNILOP); }
  1082. | '{' expr_list '}'
  1083. { $$ = streamexpr(
  1084. addexpr($2, funexpr(SNILOP))); }
  1085. | '{' expr_list ',' '}'
  1086. { $$ = streamexpr(
  1087. addexpr($2, funexpr(SNILOP))); }
  1088. | '{' expr_list ';' '}'
  1089. { if ($2->m < 0) $2->m = 0;
  1090. $$ = streamexpr(
  1091. addexpr($2, funexpr(SNILOP))); }
  1092. | '{' expr_list '|' expression '}'
  1093. { $$ = streamexpr(addexpr($2, $4)); }
  1094. | '{' expr_list DOTDOT expression '}'
  1095. { $$ = appexpr(appexpr(funexpr(SENUMOP),
  1096. listexpr(addexpr($2, funexpr(NILOP)))),
  1097. $4); }
  1098. | '{' expr_list DOTDOT '}'
  1099. { $$ = appexpr(funexpr(SENUM1OP),
  1100. listexpr(addexpr($2, funexpr(NILOP)))); }
  1101. | '{' expression ':'
  1102. { static char sym[20];
  1103. int fno = getfun(strcpy(sym, "cond::streamof"));
  1104. if (fno == NONE) {
  1105. yyerror(qcmsg[SYNTAX_ERROR]);
  1106. YYERROR;
  1107. } else
  1108. $<ival>$ = fno; }
  1109. expr_list '}'
  1110. { $$ = appexpr(appexpr(funexpr($<ival>4), $2),
  1111. tupleexpr(addexpr($5, funexpr(VOIDOP)))); }
  1112. ;
  1113. /* atomic expressions (permitted on either side of a definition) */
  1114. atom
  1115. /* constants: */
  1116. : INT { $$ = intexpr($1); }
  1117. | FLOAT { $$ = floatexpr($1); }
  1118. | STR { $$ = strexpr($1); }
  1119. /* variable and function symbols: */
  1120. | '(' op ')' { $$ = funexpr($2); }
  1121. | fid { $$ = funexpr($1); }
  1122. | qvid { $$ = funexpr($1); }
  1123. | vid { vartb[$1].type = 0;
  1124. $$ = varexpr($1); }
  1125. ;
  1126. lexpr_list1 : lexpression
  1127. { $$ = addexpr(addexpr(exprlist(), $<xval>-1),
  1128. $1); }
  1129. | lexpr_list1 ',' lexpression
  1130. { $$ = addexpr($1, $3); }
  1131. | lexpr_list1 ';' lexpression
  1132. { $$ = groupexpr(addexpr($1, $3)); }
  1133. ;
  1134. lexpr_list2 : lexpression
  1135. { $$ = groupexpr(addexpr(addexpr(exprlist(),
  1136. $<xval>-1),
  1137. $1)); }
  1138. | lexpr_list2 ',' lexpression
  1139. { $$ = addexpr($1, $3); }
  1140. | lexpr_list2 ';' lexpression
  1141. { $$ = groupexpr(addexpr($1, $3)); }
  1142. ;
  1143. lexpr_list : lexpression
  1144. { $$ = addexpr(exprlist(), $1); }
  1145. | lexpr_list ',' lexpression
  1146. { $$ = addexpr($1, $3); }
  1147. | lexpr_list ';' lexpression
  1148. { $$ = groupexpr(addexpr($1, $3)); }
  1149. ;
  1150. expr_list1 : expression
  1151. { $$ = addexpr(addexpr(exprlist(), $<xval>-1),
  1152. $1); }
  1153. | expr_list1 ',' expression
  1154. { $$ = addexpr($1, $3); }
  1155. | expr_list1 ';' expression
  1156. { $$ = groupexpr(addexpr($1, $3)); }
  1157. ;
  1158. expr_list2 : expression
  1159. { $$ = groupexpr(addexpr(addexpr(exprlist(),
  1160. $<xval>-1),
  1161. $1)); }
  1162. | expr_list2 ',' expression
  1163. { $$ = addexpr($1, $3); }
  1164. | expr_list2 ';' expression
  1165. { $$ = groupexpr(addexpr($1, $3)); }
  1166. ;
  1167. expr_list : expression
  1168. { $$ = addexpr(exprlist(), $1); }
  1169. | expr_list ',' expression
  1170. { $$ = addexpr($1, $3); }
  1171. | expr_list ';' expression
  1172. { $$ = groupexpr(addexpr($1, $3)); }
  1173. ;
  1174. builtin_op : '=' { $$ = EQOP; }
  1175. | EQUIV { $$ = IDOP; }
  1176. | '-' { $$ = MINOP; }
  1177. | '~' { $$ = FORCEOP; }
  1178. | '.' { $$ = COMPOP; }
  1179. ;
  1180. op : builtin_op
  1181. | OP3 ELSE { if ($1 != OROP) {
  1182. yyerror(qcmsg[SYNTAX_ERROR]);
  1183. YYERROR;
  1184. } else
  1185. $$ = ORELSEOP; }
  1186. | OP4 THEN { if ($1 != ANDOP) {
  1187. yyerror(qcmsg[SYNTAX_ERROR]);
  1188. YYERROR;
  1189. } else
  1190. $$ = ANDTHENOP; }
  1191. | OP0
  1192. | OP1
  1193. | OP2
  1194. | OP3
  1195. | OP4
  1196. | OP5
  1197. | OP6
  1198. | OP7
  1199. | OP9
  1200. ;
  1201. id : fid
  1202. | fvid
  1203. ;
  1204. nid : nfid
  1205. | nfvid
  1206. ;
  1207. fid : LID
  1208. { $$ = mkfun($1); }
  1209. | QLID
  1210. { $$ = mkfun($1); }
  1211. ;
  1212. nfid : LID
  1213. { $$ = mkxfun($1); }
  1214. ;
  1215. vid : UID
  1216. { $$ = mkvar($1); }
  1217. ;
  1218. fvid : UID
  1219. { $$ = mkfvar($1); }
  1220. | QUID
  1221. { $$ = mkfvar($1); }
  1222. ;
  1223. nfvid : UID
  1224. { $$ = mkxfvar($1); }
  1225. ;
  1226. qvid : QUID
  1227. { $$ = mkfvar($1); }
  1228. ;
  1229. /* These need a special parsing context (declarations). */
  1230. c_on : { context = 1; }
  1231. ;
  1232. c_off : { context = 0; }
  1233. ;
  1234. cccnid : c_on nid c_off
  1235. { $$ = $2; }
  1236. ;
  1237. cccnfid : c_on nfid c_off
  1238. { $$ = $2; }
  1239. ;
  1240. tid : c_on UID c_off
  1241. { $$ = mktype($2); }
  1242. | c_on LID c_off
  1243. { $$ = mktype($2); }
  1244. | c_on QUID c_off
  1245. { $$ = mktype($2); }
  1246. | c_on QLID c_off
  1247. { $$ = mktype($2); }
  1248. ;
  1249. ntid : c_on UID c_off
  1250. { $$ = mkxtype($2); }
  1251. | c_on LID c_off
  1252. { $$ = mkxtype($2); }
  1253. ;
  1254. /* These also need special treatment (qualified symbols in alias
  1255. declarations). CAUTION: These symbols are returned unnormalized! */
  1256. xxxqid : xxxqfid
  1257. | xxxqfvid
  1258. ;
  1259. xxxqfid : QLID
  1260. { $$ = mkxxxfun($1); }
  1261. ;
  1262. xxxqfvid : QUID
  1263. { $$ = mkxxxfvar($1); }
  1264. ;
  1265. xxxqfid_or_op : c_on xxxqfid_or_op2 c_off
  1266. { $$ = $2; }
  1267. ;
  1268. /* Give the programmer a way to declare (and then) and (or else). */
  1269. xxxqfid_or_op2 : xxxqfid ELSE { if ($1 != OROP) {
  1270. yyerror(qcmsg[SYNTAX_ERROR]);
  1271. YYERROR;
  1272. } else
  1273. $$ = ORELSEOP; }
  1274. | xxxqfid THEN { if ($1 != ANDOP) {
  1275. yyerror(qcmsg[SYNTAX_ERROR]);
  1276. YYERROR;
  1277. } else
  1278. $$ = ANDTHENOP; }
  1279. | xxxqfid
  1280. ;
  1281. xxxqtid : c_on QUID c_off
  1282. { $$ = mkxxxtype($2); }
  1283. | c_on QLID c_off
  1284. { $$ = mkxxxtype($2); }
  1285. ;
  1286. %%
  1287. extern int yyleng, yylineno;
  1288. extern char *source;
  1289. yyerror(s)
  1290. char *s;
  1291. {
  1292. fprintf(stderr, "Error %s, line %d: %s", source, yylineno, s);
  1293. if (*yytext && (strcmp(s, "parse error") == 0 ||
  1294. strcmp(s, "syntax error") == 0))
  1295. fprintf(stderr, " at or near symbol `%s'",
  1296. utf8_to_sys(yytext));
  1297. fprintf(stderr, "\n");
  1298. nerrs++;
  1299. }
  1300. yywarn(s)
  1301. char *s;
  1302. {
  1303. if (wflag) {
  1304. fprintf(stderr, "Warning %s, line %d: %s\n", source,
  1305. yylineno, s);
  1306. nwarns++;
  1307. }
  1308. }
  1309. fatal(s)
  1310. char *s;
  1311. {
  1312. if (source && *source)
  1313. fprintf(stderr, "%s: %s: %s -- compilation aborted\n",
  1314. self, source, s);
  1315. else
  1316. fprintf(stderr, "%s: %s -- compilation aborted\n",
  1317. self, s);
  1318. if (codefp) {
  1319. fclose(codefp);
  1320. remove(code);
  1321. }
  1322. exit(1);
  1323. }
  1324. #define no(n) n, n==1?"":"s"
  1325. static
  1326. statistics()
  1327. {
  1328. int fno, k, n, b, bmax, btotal, n_data;
  1329. for (n = bmax = btotal = k = 0; k < hashtbsz; k++)
  1330. if (hashtb[k] != NONE) {
  1331. n++;
  1332. for (b = -1, fno = hashtb[k]; fno != NONE;
  1333. b++, fno = symtb[fno].next)
  1334. ;
  1335. btotal += b;
  1336. if (b+1>bmax)
  1337. bmax = b+1;
  1338. }
  1339. n_data = strspsz+limbspsz*sizeof(mp_limb_t);
  1340. printf("%d ops in %d module%s, ", codespsz, no(modtbsz));
  1341. printf("%d byte%s data, ", no(n_data));
  1342. printf("%d symbol%s,\n", no(symtbsz));
  1343. printf("%d hash key%s out of %d, %d collision%s, max bucket size = %d\n",
  1344. no(n), hashtbsz, no(btotal), bmax);
  1345. printf("%d state%s, %d transition%s, %d offset%s\n",
  1346. no(statetbsz), no(transtbsz), no(roffstbsz));
  1347. }
  1348. static void *
  1349. gmp_allocate (size)
  1350. size_t size;
  1351. {
  1352. void *ret;
  1353. ret = malloc (size);
  1354. if (ret == 0) fatal(qcmsg[MEM_OVF]);
  1355. return ret;
  1356. }
  1357. static void *
  1358. gmp_reallocate (oldptr, old_size, new_size)
  1359. void *oldptr;
  1360. size_t old_size;
  1361. size_t new_size;
  1362. {
  1363. void *ret;
  1364. ret = realloc (oldptr, new_size);
  1365. if (ret == 0) fatal(qcmsg[MEM_OVF]);
  1366. return ret;
  1367. }
  1368. static void
  1369. gmp_free (blk_ptr, blk_size)
  1370. void *blk_ptr;
  1371. size_t blk_size;
  1372. {
  1373. free (blk_ptr);
  1374. }
  1375. #ifdef HAVE_UNICODE
  1376. static inline long
  1377. u8decode(char *s)
  1378. {
  1379. size_t n;
  1380. unsigned p = 0, q = 0;
  1381. unsigned long c = 0;
  1382. if (s[0] == 0)
  1383. return -1;
  1384. else if (s[1] == 0)
  1385. return (unsigned char)s[0];
  1386. for (n = 0; n == 0 && *s; s++) {
  1387. unsigned char uc = (unsigned char)*s;
  1388. if (q == 0) {
  1389. if (((signed char)*s) < 0) {
  1390. switch (uc & 0xf0) {
  1391. case 0xc0: case 0xd0:
  1392. q = 1;
  1393. c = uc & 0x1f;
  1394. break;
  1395. case 0xe0:
  1396. q = 2;
  1397. c = uc & 0xf;
  1398. break;
  1399. case 0xf0:
  1400. if ((uc & 0x8) == 0) {
  1401. q = 3;
  1402. c = uc & 0x7;
  1403. } else
  1404. c = uc;
  1405. break;
  1406. default:
  1407. c = uc;
  1408. break;
  1409. }
  1410. } else
  1411. c = uc;
  1412. p = 0;
  1413. if (q == 0) n++;
  1414. } else if ((uc & 0xc0) == 0x80) {
  1415. /* continuation byte */
  1416. c = c << 6 | (uc & 0x3f);
  1417. if (--q == 0)
  1418. n++;
  1419. else
  1420. p++;
  1421. } else {
  1422. /* malformed char */
  1423. return -1;
  1424. }
  1425. }
  1426. if (n == 1 && *s == 0)
  1427. return c;
  1428. else
  1429. return -1;
  1430. }
  1431. #endif
  1432. static int isvsym(char *s)
  1433. {
  1434. if (!*s)
  1435. return 0;
  1436. else {
  1437. #ifdef HAVE_UNICODE
  1438. long c = u8decode(s);
  1439. if (c < 0) c = (unsigned char)*s;
  1440. return u_isupper(c);
  1441. #else
  1442. return isupper(s[0]);
  1443. #endif
  1444. }
  1445. }
  1446. RETSIGTYPE
  1447. break_handler()
  1448. /* handle SIGINT and SIGTERM */
  1449. {
  1450. /* Since many system functions are unsave to call in a signal
  1451. handler, we simply set a flag here; the corresponding actions
  1452. in response to SIGINT (remove code file, close list file,
  1453. terminate program) will be carried out later in a save
  1454. context. */
  1455. int_sig = 1;
  1456. SIGHANDLER_RETURN(0);
  1457. }
  1458. checkint()
  1459. /* check for pending int_sig */
  1460. {
  1461. if (int_sig) fatal("interrupt");
  1462. }
  1463. newrule()
  1464. /* reinitialize for the next rule */
  1465. {
  1466. clear(); qualtest = 0; checkint();
  1467. }
  1468. newdecl()
  1469. /* reinitialize for the next declaration */
  1470. {
  1471. flags = PRIV; argv = 0; checkint();
  1472. }
  1473. precval(z)
  1474. mpz_t z;
  1475. /* calculate precedence level */
  1476. {
  1477. if (my_mpz_fits_slong_p(z)) {
  1478. long prec = mpz_get_si(z);
  1479. if (prec >= 0 && prec <= 9 && prec != 8)
  1480. return prec;
  1481. }
  1482. yyerror(qcmsg[INVALID_PREC]);
  1483. return NONE;
  1484. }
  1485. priority(z)
  1486. mpz_t z;
  1487. /* set a new priority level */
  1488. {
  1489. if (my_mpz_fits_slong_p(z))
  1490. prio = mpz_get_si(z);
  1491. else
  1492. yyerror(qcmsg[INVALID_PRIO]);
  1493. }
  1494. /* qualifier table */
  1495. int qual_size, qual_alloc, clause_size, clause_alloc;
  1496. static QUAL *qual;
  1497. static CLAUSE *clause;
  1498. static void start_qualifiers(void)
  1499. {
  1500. qual_size = clause_size = 0;
  1501. }
  1502. static void qualifiers(void)
  1503. {
  1504. int i;
  1505. for (i = qual_size-1; i >= 0; i--)
  1506. if (qual[i].x)
  1507. qualifier(qual[i].x);
  1508. else {
  1509. int j;
  1510. for (j = qual[i].start; j < qual[i].end; j++)
  1511. where_clause(clause[j].l, clause[j].r);
  1512. }
  1513. }
  1514. static void add_qualifier(EXPR *x)
  1515. {
  1516. if (!x) return;
  1517. if (qual_size >= qual_alloc)
  1518. if ((qual = arealloc(qual, qual_alloc, 10, sizeof(QUAL))))
  1519. qual_alloc += 10;
  1520. else
  1521. fatal("memory overflow");
  1522. qual[qual_size++].x = x;
  1523. }
  1524. static void start_where_clauses(void)
  1525. {
  1526. if (qual_size >= qual_alloc)
  1527. if ((qual = arealloc(qual, qual_alloc, 10, sizeof(QUAL))))
  1528. qual_alloc += 10;
  1529. else
  1530. fatal("memory overflow");
  1531. qual[qual_size].x = NULL;
  1532. qual[qual_size].start = clause_size;
  1533. }
  1534. static void end_where_clauses(void)
  1535. {
  1536. qual[qual_size++].end = clause_size;
  1537. }
  1538. static void add_where_clause(EXPR *l, EXPR *r)
  1539. {
  1540. if (clause_size >= clause_alloc)
  1541. if ((clause = arealloc(clause, clause_alloc, 10, sizeof(CLAUSE))))
  1542. clause_alloc += 10;
  1543. else
  1544. fatal("memory overflow");
  1545. clause[clause_size].l = l;
  1546. clause[clause_size].r = r;
  1547. clause_size++;
  1548. }
  1549. /* expression lists */
  1550. static xvect_t *exprlist(void)
  1551. {
  1552. xvect_t *v = (xvect_t*)malloc(sizeof(xvect_t));
  1553. if (!v) fatal("memory overflow");
  1554. v->a = v->n = 0; v->m = -1;
  1555. v->xv = NULL;
  1556. return v;
  1557. }
  1558. static xvect_t *addexpr(xvect_t *v, EXPR *x)
  1559. {
  1560. if (v->n >= v->a) {
  1561. v->a += 100;
  1562. if (v->xv)
  1563. v->xv = realloc(v->xv, v->a*sizeof(EXPR*));
  1564. else
  1565. v->xv = malloc(v->a*sizeof(EXPR*));
  1566. if (!v->xv) fatal("memory overflow");
  1567. }
  1568. v->xv[v->n++] = x;
  1569. return v;
  1570. }
  1571. static xvect_t *groupexpr(xvect_t *v)
  1572. {
  1573. EXPR *x, *y;
  1574. int n = v->n, m = v->m;
  1575. if (n <= 0) fatal("internal compiler error");
  1576. if (m < 0) m = 0;
  1577. y = v->xv[--n];
  1578. x = funexpr(VOIDOP);
  1579. while (n > m)
  1580. x = pairexpr(v->xv[--n], x);
  1581. v->xv[n++] = x; m = n;
  1582. v->xv[n++] = y;
  1583. v->n = n; v->m = m;
  1584. return v;
  1585. }
  1586. static EXPR *tupleexpr(xvect_t *v)
  1587. {
  1588. EXPR *x;
  1589. int n;
  1590. if (v->m >= 0) groupexpr(v);
  1591. n = v->n;
  1592. if (n <= 0) fatal("internal compiler error");
  1593. x = v->xv[--n];
  1594. while (n > 0)
  1595. x = pairexpr(v->xv[--n], x);
  1596. free(v->xv);
  1597. free(v);
  1598. return x;
  1599. }
  1600. static EXPR *listexpr(xvect_t *v)
  1601. {
  1602. EXPR *x;
  1603. int n;
  1604. if (v->m >= 0) groupexpr(v);
  1605. n = v->n;
  1606. if (n <= 0) fatal("internal compiler error");
  1607. x = v->xv[--n];
  1608. while (n > 0)
  1609. x = consexpr(v->xv[--n], x);
  1610. free(v->xv);
  1611. free(v);
  1612. return x;
  1613. }
  1614. static EXPR *streamexpr(xvect_t *v)
  1615. {
  1616. EXPR *x;
  1617. int n;
  1618. if (v->m >= 0) groupexpr(v);
  1619. n = v->n;
  1620. if (n <= 0) fatal("internal compiler error");
  1621. x = v->xv[--n];
  1622. while (n > 0)
  1623. x = appexpr(appexpr(funexpr(SCONSOP), v->xv[--n]), x);
  1624. free(v->xv);
  1625. free(v);
  1626. return x;
  1627. }
  1628. static struct option longopts[] = QC_OPTS;
  1629. static struct option all_longopts[] = Q_OPTS;
  1630. static int
  1631. getintarg(char *s, int *i)
  1632. {
  1633. char *t = s;
  1634. while (isspace(*t)) t++;
  1635. s = t;
  1636. while (isdigit(*t)) t++;
  1637. if (t == s) return 0;
  1638. while (isspace(*t)) t++;
  1639. if (*t) return 0;
  1640. *i = atoi(s);
  1641. return 1;
  1642. }
  1643. static void
  1644. parse_opts(argc, argv, pass)
  1645. int argc;
  1646. char **argv;
  1647. int pass; /* 0 denotes source, 1 command line pass */
  1648. {
  1649. int c, longind;
  1650. optind = 0;
  1651. while ((c = getopt_long(argc, argv,
  1652. pass?QC_OPTS1:Q_OPTS1,
  1653. pass?longopts:all_longopts,
  1654. &longind)) != EOF)
  1655. switch (c) {
  1656. case QC_PEDANTIC:
  1657. wflag = 2;
  1658. break;
  1659. case QC_PARANOID:
  1660. wflag = 3;
  1661. break;
  1662. case QC_NO_PRELUDE:
  1663. prelude = NULL;
  1664. break;
  1665. case QC_PRELUDE:
  1666. prelude = optarg?optarg:prelude;
  1667. break;
  1668. case QC_ENCODING: {
  1669. #if defined(HAVE_UNICODE) && defined(HAVE_ICONV)
  1670. if (optarg)
  1671. if (pass) {
  1672. iconv_t ic = iconv_open("UTF-8", optarg);
  1673. if (ic == (iconv_t)-1) {
  1674. char msg[MAXSTRLEN];
  1675. sprintf(msg, "unknown encoding `%s'", optarg);
  1676. fatal(msg);
  1677. } else {
  1678. iconv_close(ic);
  1679. default_codeset = optarg;
  1680. }
  1681. } else /* errors will be caught later by lexer */
  1682. default_codeset = optarg;
  1683. #else
  1684. fprintf(stderr, "%s: warning: --encoding option not supported\n", self);
  1685. #endif
  1686. break;
  1687. }
  1688. case 'd':
  1689. if (pass)
  1690. dflag = 1;
  1691. break;
  1692. case 'h':
  1693. hflag = 1;
  1694. break;
  1695. case 'l':
  1696. list = optarg?optarg:list;
  1697. break;
  1698. case 'n':
  1699. nflag = 1;
  1700. break;
  1701. case 'o':
  1702. code = optarg?optarg:code;
  1703. break;
  1704. case 'p':
  1705. if (optarg) {
  1706. change_qpath(optarg);
  1707. if (!qpath) fatal("memory overflow");
  1708. }
  1709. break;
  1710. case 't': {
  1711. int sz;
  1712. if (optarg && getintarg(optarg, &sz) && sz > 0)
  1713. hashtbsz = sz;
  1714. else {
  1715. char msg[MAXSTRLEN];
  1716. sprintf(msg, "invalid size `%s'", optarg?optarg:"");
  1717. fatal(msg);
  1718. }
  1719. break;
  1720. }
  1721. case 'v':
  1722. vflag = 1;
  1723. break;
  1724. case 'w': {
  1725. int level = 1;
  1726. if (optarg && (!getintarg(optarg, &level) || level < 0 || level > 255)) {
  1727. char msg[MAXSTRLEN];
  1728. sprintf(msg, "invalid warning level `%s'", optarg?optarg:"");
  1729. fatal(msg);
  1730. }
  1731. wflag = level;
  1732. break;
  1733. }
  1734. case 'V':
  1735. Vflag = 1;
  1736. break;
  1737. /* interpreter options (ignored): */
  1738. case Q_GNUCLIENT:
  1739. case Q_DEBUG_OPTIONS:
  1740. case Q_BREAK:
  1741. case Q_PROMPT:
  1742. case Q_DEC:
  1743. case Q_HEX:
  1744. case Q_OCT:
  1745. case Q_STD:
  1746. case Q_SCI:
  1747. case Q_FIX:
  1748. case Q_HISTFILE:
  1749. case Q_HISTSIZE:
  1750. case Q_INITRC:
  1751. case Q_NO_INITRC:
  1752. case Q_EXITRC:
  1753. case Q_NO_EXITRC:
  1754. case Q_NO_EDITING:
  1755. case Q_STACKSIZE:
  1756. case Q_MEMSIZE:
  1757. case 'e':
  1758. case 'i':
  1759. case 'q':
  1760. case 'c':
  1761. case 's':
  1762. break;
  1763. default:
  1764. exit(1);
  1765. }
  1766. }
  1767. static int sargc;
  1768. static char **sargv;
  1769. static void
  1770. get_source_opts(FILE *fp)
  1771. {
  1772. char s[MAXSTRLEN];
  1773. int i;
  1774. sargc = 1;
  1775. sargv = aalloc(1, sizeof(char*));
  1776. *sargv = strdup(self);
  1777. while (!feof(fp) && !ferror(fp) &&
  1778. fgets(s, MAXSTRLEN, fp)) {
  1779. int l = strlen(s);
  1780. if (l > 0 && s[l-1] == '\n') s[l-1] = '\0', l--;
  1781. if (l == 0)
  1782. continue;
  1783. else if (strncmp(s, "#!", 2) == 0)
  1784. if (isspace(s[2])) {
  1785. char *p = s+3;
  1786. while (isspace(*p)) p++;
  1787. sargv = arealloc(sargv, sargc, 1, sizeof(char*));
  1788. sargv[sargc++] = strdup(p);
  1789. } else
  1790. continue;
  1791. else
  1792. break;
  1793. }
  1794. sargv = arealloc(sargv, sargc, 1, sizeof(char*));
  1795. sargv[sargc] = NULL;
  1796. }
  1797. main(argc, argv)
  1798. int argc;
  1799. char **argv;
  1800. {
  1801. int c, longind;
  1802. char *s;
  1803. #if defined(HAVE_UNICODE) && defined(HAVE_LOCALE_H)
  1804. setlocale(LC_ALL, "");
  1805. #endif
  1806. #ifdef _WIN32
  1807. InstallSignalHandler();
  1808. #endif
  1809. /* get program name: */
  1810. self = argv[0];
  1811. /* get environment settings: */
  1812. if ((s = getenv("QPATH")) != NULL)
  1813. init_qpath(s);
  1814. else
  1815. init_qpath(QPATH);
  1816. if (!qpath) fatal("memory overflow");
  1817. if ((s = getenv("QWARN")) != NULL) {
  1818. int level;
  1819. if (getintarg(s, &level) && level >= 0 && level <= 255)
  1820. wflag = level;
  1821. }
  1822. /* scan command line to obtain the first source file name: */
  1823. opterr = 0;
  1824. while ((c = getopt_long(argc, argv, Q_OPTS1,
  1825. longopts, &longind)) != EOF)
  1826. ;
  1827. opterr = 1;
  1828. /* get options from the main script: */
  1829. if (argc-optind >= 1 && strcmp(argv[optind], "-")) {
  1830. char fname[MAXSTRLEN], fname2[MAXSTRLEN];
  1831. FILE *fp;
  1832. if (chkfile(searchlib(fname, argv[optind])) &&
  1833. (fp = fopen(fname, "r")) != NULL ||
  1834. chkfile(searchlib(fname, strcat(strcpy(fname2, argv[optind]),
  1835. ".q"))) &&
  1836. (fp = fopen(fname, "r")) != NULL) {
  1837. get_source_opts(fp);
  1838. fclose(fp);
  1839. parse_opts(sargc, sargv, 0);
  1840. }
  1841. }
  1842. /* get command line options: */
  1843. parse_opts(argc, argv, 1);
  1844. argc -= optind, argv += optind;
  1845. if (Vflag) {
  1846. printf(signon, version, sysinfo, year);
  1847. printf(copying);
  1848. printf(helpmsg, self);
  1849. exit(0);
  1850. }
  1851. if (hflag) {
  1852. printf(usage, self);
  1853. sprintf(opts, QC_OPTMSG, QPATH, HASHTBSZ);
  1854. fputs(opts, stdout);
  1855. exit(0);
  1856. }
  1857. /* install break and term handlers: */
  1858. sigint(break_handler);
  1859. sigterm(break_handler);
  1860. sighup(break_handler);
  1861. /* install gmp memory handlers */
  1862. mp_set_memory_functions(gmp_allocate, gmp_reallocate, gmp_free);
  1863. /* set code file id: */
  1864. sprintf(outid, OUTID, version, sysinfo);
  1865. /* compile: */
  1866. if (*list) {
  1867. FILE *fp;
  1868. if (!(fp = fopen(list, "w"))) {
  1869. fprintf(stderr, "%s: error creating %s\n",
  1870. self, list);
  1871. exit(1);
  1872. } else {
  1873. fclose(fp);
  1874. freopen(list, "w", stderr);
  1875. }
  1876. }
  1877. if (!(codefp = fopen(code, "wb"))) {
  1878. fprintf(stderr, "%s: error creating %s\n",
  1879. self, code);
  1880. exit(1);
  1881. }
  1882. mainno = -1;
  1883. write_header();
  1884. inittables();
  1885. if (!initlex(argc, argv) || yyparse() == 0 && nerrs == 0) {
  1886. /* generate code: */
  1887. write_strsp();
  1888. write_limbsp();
  1889. write_hashtb();
  1890. write_symtb();
  1891. write_TA();
  1892. write_matchtb();
  1893. write_inittb();
  1894. write_modtb();
  1895. fix_header();
  1896. checkint();
  1897. if (nflag) {
  1898. fclose(codefp);
  1899. remove(code);
  1900. } else
  1901. fclose(codefp);
  1902. if (list && !nwarns) {
  1903. fclose(stderr);
  1904. remove(list);
  1905. }
  1906. if (vflag)
  1907. statistics();
  1908. exit(0);
  1909. } else {
  1910. checkint();
  1911. fclose(codefp);
  1912. remove(code);
  1913. if (vflag)
  1914. putchar('\n');
  1915. exit(1);
  1916. }
  1917. }