/usr.bin/yacc/lalr.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 701 lines · 534 code · 135 blank · 32 comment · 85 complexity · cce4d6b66ea1af43c6c2ff55659d31a4 MD5 · raw file

  1. /*
  2. * Copyright (c) 1989 The Regents of the University of California.
  3. * All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Robert Paul Corbett.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 4. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. */
  32. #if 0
  33. #ifndef lint
  34. static char sccsid[] = "@(#)lalr.c 5.3 (Berkeley) 6/1/90";
  35. #endif
  36. #endif
  37. #include <sys/cdefs.h>
  38. __FBSDID("$FreeBSD$");
  39. #include <limits.h>
  40. #include <stdlib.h>
  41. #include "defs.h"
  42. typedef
  43. struct shorts
  44. {
  45. struct shorts *next;
  46. short value;
  47. }
  48. shorts;
  49. int tokensetsize;
  50. short *lookaheads;
  51. short *LAruleno;
  52. unsigned *LA;
  53. short *accessing_symbol;
  54. core **state_table;
  55. shifts **shift_table;
  56. reductions **reduction_table;
  57. short *goto_map;
  58. short *from_state;
  59. short *to_state;
  60. static void add_lookback_edge(int, int, int);
  61. static void build_relations(void);
  62. static void compute_FOLLOWS(void);
  63. static void compute_lookaheads(void);
  64. static void digraph(short **);
  65. static void initialize_F(void);
  66. static void initialize_LA(void);
  67. static int map_goto(int, int);
  68. static void set_accessing_symbol(void);
  69. static void set_goto_map(void);
  70. static void set_maxrhs(void);
  71. static void set_reduction_table(void);
  72. static void set_shift_table(void);
  73. static void set_state_table(void);
  74. static short **transpose(short **, int);
  75. static void traverse(int, short **);
  76. static int infinity;
  77. static int maxrhs;
  78. static int ngotos;
  79. static unsigned *F;
  80. static short **includes;
  81. static shorts **lookback;
  82. static short *INDEX;
  83. static short *VERTICES;
  84. static int top;
  85. void
  86. lalr(void)
  87. {
  88. tokensetsize = WORDSIZE(ntokens);
  89. set_state_table();
  90. set_accessing_symbol();
  91. set_shift_table();
  92. set_reduction_table();
  93. set_maxrhs();
  94. initialize_LA();
  95. set_goto_map();
  96. initialize_F();
  97. build_relations();
  98. compute_FOLLOWS();
  99. compute_lookaheads();
  100. }
  101. static void
  102. set_state_table(void)
  103. {
  104. core *sp;
  105. state_table = NEW2(nstates, core *);
  106. for (sp = first_state; sp; sp = sp->next)
  107. state_table[sp->number] = sp;
  108. }
  109. static void
  110. set_accessing_symbol(void)
  111. {
  112. core *sp;
  113. accessing_symbol = NEW2(nstates, short);
  114. for (sp = first_state; sp; sp = sp->next)
  115. accessing_symbol[sp->number] = sp->accessing_symbol;
  116. }
  117. static void
  118. set_shift_table(void)
  119. {
  120. shifts *sp;
  121. shift_table = NEW2(nstates, shifts *);
  122. for (sp = first_shift; sp; sp = sp->next)
  123. shift_table[sp->number] = sp;
  124. }
  125. static void
  126. set_reduction_table(void)
  127. {
  128. reductions *rp;
  129. reduction_table = NEW2(nstates, reductions *);
  130. for (rp = first_reduction; rp; rp = rp->next)
  131. reduction_table[rp->number] = rp;
  132. }
  133. static void
  134. set_maxrhs(void)
  135. {
  136. short *itemp;
  137. short *item_end;
  138. int length;
  139. int max;
  140. length = 0;
  141. max = 0;
  142. item_end = ritem + nitems;
  143. for (itemp = ritem; itemp < item_end; itemp++)
  144. {
  145. if (*itemp >= 0)
  146. {
  147. length++;
  148. }
  149. else
  150. {
  151. if (length > max) max = length;
  152. length = 0;
  153. }
  154. }
  155. maxrhs = max;
  156. }
  157. static void
  158. initialize_LA(void)
  159. {
  160. int i, j, k;
  161. reductions *rp;
  162. lookaheads = NEW2(nstates + 1, short);
  163. k = 0;
  164. for (i = 0; i < nstates; i++)
  165. {
  166. lookaheads[i] = k;
  167. rp = reduction_table[i];
  168. if (rp)
  169. k += rp->nreds;
  170. }
  171. lookaheads[nstates] = k;
  172. LA = NEW2(k * tokensetsize, unsigned);
  173. LAruleno = NEW2(k, short);
  174. lookback = NEW2(k, shorts *);
  175. k = 0;
  176. for (i = 0; i < nstates; i++)
  177. {
  178. rp = reduction_table[i];
  179. if (rp)
  180. {
  181. for (j = 0; j < rp->nreds; j++)
  182. {
  183. LAruleno[k] = rp->rules[j];
  184. k++;
  185. }
  186. }
  187. }
  188. }
  189. static void
  190. set_goto_map(void)
  191. {
  192. shifts *sp;
  193. int i;
  194. int symbol;
  195. int k;
  196. short *temp_map;
  197. int state2;
  198. int state1;
  199. goto_map = NEW2(nvars + 1, short) - ntokens;
  200. temp_map = NEW2(nvars + 1, short) - ntokens;
  201. ngotos = 0;
  202. for (sp = first_shift; sp; sp = sp->next)
  203. {
  204. for (i = sp->nshifts - 1; i >= 0; i--)
  205. {
  206. symbol = accessing_symbol[sp->shift[i]];
  207. if (ISTOKEN(symbol)) break;
  208. if (ngotos == SHRT_MAX)
  209. fatal("too many gotos");
  210. ngotos++;
  211. goto_map[symbol]++;
  212. }
  213. }
  214. k = 0;
  215. for (i = ntokens; i < nsyms; i++)
  216. {
  217. temp_map[i] = k;
  218. k += goto_map[i];
  219. }
  220. for (i = ntokens; i < nsyms; i++)
  221. goto_map[i] = temp_map[i];
  222. goto_map[nsyms] = ngotos;
  223. temp_map[nsyms] = ngotos;
  224. from_state = NEW2(ngotos, short);
  225. to_state = NEW2(ngotos, short);
  226. for (sp = first_shift; sp; sp = sp->next)
  227. {
  228. state1 = sp->number;
  229. for (i = sp->nshifts - 1; i >= 0; i--)
  230. {
  231. state2 = sp->shift[i];
  232. symbol = accessing_symbol[state2];
  233. if (ISTOKEN(symbol)) break;
  234. k = temp_map[symbol]++;
  235. from_state[k] = state1;
  236. to_state[k] = state2;
  237. }
  238. }
  239. free(temp_map + ntokens);
  240. }
  241. /* Map_goto maps a state/symbol pair into its numeric representation. */
  242. static int
  243. map_goto(int state, int symbol)
  244. {
  245. int high;
  246. int low;
  247. int middle;
  248. int s;
  249. low = goto_map[symbol];
  250. high = goto_map[symbol + 1];
  251. for (;;)
  252. {
  253. assert(low <= high);
  254. middle = (low + high) >> 1;
  255. s = from_state[middle];
  256. if (s == state)
  257. return (middle);
  258. else if (s < state)
  259. low = middle + 1;
  260. else
  261. high = middle - 1;
  262. }
  263. }
  264. static void
  265. initialize_F(void)
  266. {
  267. int i;
  268. int j;
  269. int k;
  270. shifts *sp;
  271. short *edge;
  272. unsigned *rowp;
  273. short *rp;
  274. short **reads;
  275. int nedges;
  276. int stateno;
  277. int symbol;
  278. int nwords;
  279. nwords = ngotos * tokensetsize;
  280. F = NEW2(nwords, unsigned);
  281. reads = NEW2(ngotos, short *);
  282. edge = NEW2(ngotos + 1, short);
  283. nedges = 0;
  284. rowp = F;
  285. for (i = 0; i < ngotos; i++)
  286. {
  287. stateno = to_state[i];
  288. sp = shift_table[stateno];
  289. if (sp)
  290. {
  291. k = sp->nshifts;
  292. for (j = 0; j < k; j++)
  293. {
  294. symbol = accessing_symbol[sp->shift[j]];
  295. if (ISVAR(symbol))
  296. break;
  297. SETBIT(rowp, symbol);
  298. }
  299. for (; j < k; j++)
  300. {
  301. symbol = accessing_symbol[sp->shift[j]];
  302. if (nullable[symbol])
  303. edge[nedges++] = map_goto(stateno, symbol);
  304. }
  305. if (nedges)
  306. {
  307. reads[i] = rp = NEW2(nedges + 1, short);
  308. for (j = 0; j < nedges; j++)
  309. rp[j] = edge[j];
  310. rp[nedges] = -1;
  311. nedges = 0;
  312. }
  313. }
  314. rowp += tokensetsize;
  315. }
  316. SETBIT(F, 0);
  317. digraph(reads);
  318. for (i = 0; i < ngotos; i++)
  319. {
  320. if (reads[i])
  321. free(reads[i]);
  322. }
  323. free(reads);
  324. free(edge);
  325. }
  326. static void
  327. build_relations(void)
  328. {
  329. int i;
  330. int j;
  331. int k;
  332. short *rulep;
  333. short *rp;
  334. shifts *sp;
  335. int length;
  336. int nedges;
  337. int done1;
  338. int state1;
  339. int stateno;
  340. int symbol1;
  341. int symbol2;
  342. short *shortp;
  343. short *edge;
  344. short *states;
  345. short **new_includes;
  346. includes = NEW2(ngotos, short *);
  347. edge = NEW2(ngotos + 1, short);
  348. states = NEW2(maxrhs + 1, short);
  349. for (i = 0; i < ngotos; i++)
  350. {
  351. nedges = 0;
  352. state1 = from_state[i];
  353. symbol1 = accessing_symbol[to_state[i]];
  354. for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
  355. {
  356. length = 1;
  357. states[0] = state1;
  358. stateno = state1;
  359. for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
  360. {
  361. symbol2 = *rp;
  362. sp = shift_table[stateno];
  363. k = sp->nshifts;
  364. for (j = 0; j < k; j++)
  365. {
  366. stateno = sp->shift[j];
  367. if (accessing_symbol[stateno] == symbol2) break;
  368. }
  369. states[length++] = stateno;
  370. }
  371. add_lookback_edge(stateno, *rulep, i);
  372. length--;
  373. done1 = 0;
  374. while (!done1)
  375. {
  376. done1 = 1;
  377. rp--;
  378. if (ISVAR(*rp))
  379. {
  380. stateno = states[--length];
  381. edge[nedges++] = map_goto(stateno, *rp);
  382. if (nullable[*rp] && length > 0) done1 = 0;
  383. }
  384. }
  385. }
  386. if (nedges)
  387. {
  388. includes[i] = shortp = NEW2(nedges + 1, short);
  389. for (j = 0; j < nedges; j++)
  390. shortp[j] = edge[j];
  391. shortp[nedges] = -1;
  392. }
  393. }
  394. new_includes = transpose(includes, ngotos);
  395. for (i = 0; i < ngotos; i++)
  396. if (includes[i])
  397. free(includes[i]);
  398. free(includes);
  399. includes = new_includes;
  400. free(edge);
  401. free(states);
  402. }
  403. static void
  404. add_lookback_edge(int stateno, int ruleno, int gotono)
  405. {
  406. int i, k;
  407. int found;
  408. shorts *sp;
  409. i = lookaheads[stateno];
  410. k = lookaheads[stateno + 1];
  411. found = 0;
  412. while (!found && i < k)
  413. {
  414. if (LAruleno[i] == ruleno)
  415. found = 1;
  416. else
  417. ++i;
  418. }
  419. assert(found);
  420. sp = NEW(shorts);
  421. sp->next = lookback[i];
  422. sp->value = gotono;
  423. lookback[i] = sp;
  424. }
  425. static short **
  426. transpose(short **R, int n)
  427. {
  428. short **new_R;
  429. short **temp_R;
  430. short *nedges;
  431. short *sp;
  432. int i;
  433. int k;
  434. nedges = NEW2(n, short);
  435. for (i = 0; i < n; i++)
  436. {
  437. sp = R[i];
  438. if (sp)
  439. {
  440. while (*sp >= 0)
  441. nedges[*sp++]++;
  442. }
  443. }
  444. new_R = NEW2(n, short *);
  445. temp_R = NEW2(n, short *);
  446. for (i = 0; i < n; i++)
  447. {
  448. k = nedges[i];
  449. if (k > 0)
  450. {
  451. sp = NEW2(k + 1, short);
  452. new_R[i] = sp;
  453. temp_R[i] = sp;
  454. sp[k] = -1;
  455. }
  456. }
  457. free(nedges);
  458. for (i = 0; i < n; i++)
  459. {
  460. sp = R[i];
  461. if (sp)
  462. {
  463. while (*sp >= 0)
  464. *temp_R[*sp++]++ = i;
  465. }
  466. }
  467. free(temp_R);
  468. return (new_R);
  469. }
  470. static void
  471. compute_FOLLOWS(void)
  472. {
  473. digraph(includes);
  474. }
  475. static void
  476. compute_lookaheads(void)
  477. {
  478. int i, n;
  479. unsigned *fp1, *fp2, *fp3;
  480. shorts *sp, *next;
  481. unsigned *rowp;
  482. rowp = LA;
  483. n = lookaheads[nstates];
  484. for (i = 0; i < n; i++)
  485. {
  486. fp3 = rowp + tokensetsize;
  487. for (sp = lookback[i]; sp; sp = sp->next)
  488. {
  489. fp1 = rowp;
  490. fp2 = F + tokensetsize * sp->value;
  491. while (fp1 < fp3)
  492. *fp1++ |= *fp2++;
  493. }
  494. rowp = fp3;
  495. }
  496. for (i = 0; i < n; i++)
  497. for (sp = lookback[i]; sp; sp = next)
  498. {
  499. next = sp->next;
  500. free(sp);
  501. }
  502. free(lookback);
  503. free(F);
  504. }
  505. static void
  506. digraph(short **relation)
  507. {
  508. int i;
  509. infinity = ngotos + 2;
  510. INDEX = NEW2(ngotos + 1, short);
  511. VERTICES = NEW2(ngotos + 1, short);
  512. top = 0;
  513. for (i = 0; i < ngotos; i++)
  514. INDEX[i] = 0;
  515. for (i = 0; i < ngotos; i++)
  516. {
  517. if (INDEX[i] == 0 && relation[i])
  518. traverse(i, relation);
  519. }
  520. free(INDEX);
  521. free(VERTICES);
  522. }
  523. static void
  524. traverse(int i, short **R)
  525. {
  526. unsigned *fp1;
  527. unsigned *fp2;
  528. unsigned *fp3;
  529. int j;
  530. short *rp;
  531. int height;
  532. unsigned *base;
  533. VERTICES[++top] = i;
  534. INDEX[i] = height = top;
  535. base = F + i * tokensetsize;
  536. fp3 = base + tokensetsize;
  537. rp = R[i];
  538. if (rp)
  539. {
  540. while ((j = *rp++) >= 0)
  541. {
  542. if (INDEX[j] == 0)
  543. traverse(j, R);
  544. if (INDEX[i] > INDEX[j])
  545. INDEX[i] = INDEX[j];
  546. fp1 = base;
  547. fp2 = F + j * tokensetsize;
  548. while (fp1 < fp3)
  549. *fp1++ |= *fp2++;
  550. }
  551. }
  552. if (INDEX[i] == height)
  553. {
  554. for (;;)
  555. {
  556. j = VERTICES[top--];
  557. INDEX[j] = infinity;
  558. if (i == j)
  559. break;
  560. fp1 = base;
  561. fp2 = F + j * tokensetsize;
  562. while (fp1 < fp3)
  563. *fp2++ = *fp1++;
  564. }
  565. }
  566. }