PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/yacc/lr0.c

http://github.com/bmeurer/ocaml-arm
C | 621 lines | 483 code | 121 blank | 17 comment | 66 complexity | 02bf7e4a5065254feb9cfc1df5346d56 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0
  1. /***********************************************************************/
  2. /* */
  3. /* OCaml */
  4. /* */
  5. /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
  6. /* */
  7. /* Copyright 1996 Institut National de Recherche en Informatique et */
  8. /* en Automatique. All rights reserved. This file is distributed */
  9. /* under the terms of the Q Public License version 1.0. */
  10. /* */
  11. /***********************************************************************/
  12. /* Based on public-domain code from Berkeley Yacc */
  13. /* $Id$ */
  14. #include "defs.h"
  15. extern short *itemset;
  16. extern short *itemsetend;
  17. extern unsigned *ruleset;
  18. int nstates;
  19. core *first_state;
  20. shifts *first_shift;
  21. reductions *first_reduction;
  22. int get_state(int symbol);
  23. core *new_state(int symbol);
  24. static core **state_set;
  25. static core *this_state;
  26. static core *last_state;
  27. static shifts *last_shift;
  28. static reductions *last_reduction;
  29. static int nshifts;
  30. static short *shift_symbol;
  31. static short *redset;
  32. static short *shiftset;
  33. static short **kernel_base;
  34. static short **kernel_end;
  35. static short *kernel_items;
  36. void initialize_states (void);
  37. void save_reductions (void);
  38. void new_itemsets (void);
  39. void save_shifts (void);
  40. void print_derives ();
  41. void show_cores (void), show_ritems (void), show_rrhs (void), show_shifts (void);
  42. void allocate_itemsets(void)
  43. {
  44. register short *itemp;
  45. register short *item_end;
  46. register int symbol;
  47. register int i;
  48. register int count;
  49. register int max;
  50. register short *symbol_count;
  51. count = 0;
  52. symbol_count = NEW2(nsyms, short);
  53. item_end = ritem + nitems;
  54. for (itemp = ritem; itemp < item_end; itemp++)
  55. {
  56. symbol = *itemp;
  57. if (symbol >= 0)
  58. {
  59. count++;
  60. symbol_count[symbol]++;
  61. }
  62. }
  63. kernel_base = NEW2(nsyms, short *);
  64. kernel_items = NEW2(count, short);
  65. count = 0;
  66. max = 0;
  67. for (i = 0; i < nsyms; i++)
  68. {
  69. kernel_base[i] = kernel_items + count;
  70. count += symbol_count[i];
  71. if (max < symbol_count[i])
  72. max = symbol_count[i];
  73. }
  74. shift_symbol = symbol_count;
  75. kernel_end = NEW2(nsyms, short *);
  76. }
  77. void allocate_storage(void)
  78. {
  79. allocate_itemsets();
  80. shiftset = NEW2(nsyms, short);
  81. redset = NEW2(nrules + 1, short);
  82. state_set = NEW2(nitems, core *);
  83. }
  84. void append_states(void)
  85. {
  86. register int i;
  87. register int j;
  88. register int symbol;
  89. #ifdef TRACE
  90. fprintf(stderr, "Entering append_states()\n");
  91. #endif
  92. for (i = 1; i < nshifts; i++)
  93. {
  94. symbol = shift_symbol[i];
  95. j = i;
  96. while (j > 0 && shift_symbol[j - 1] > symbol)
  97. {
  98. shift_symbol[j] = shift_symbol[j - 1];
  99. j--;
  100. }
  101. shift_symbol[j] = symbol;
  102. }
  103. for (i = 0; i < nshifts; i++)
  104. {
  105. symbol = shift_symbol[i];
  106. shiftset[i] = get_state(symbol);
  107. }
  108. }
  109. void free_storage(void)
  110. {
  111. FREE(shift_symbol);
  112. FREE(redset);
  113. FREE(shiftset);
  114. FREE(kernel_base);
  115. FREE(kernel_end);
  116. FREE(kernel_items);
  117. FREE(state_set);
  118. }
  119. void generate_states(void)
  120. {
  121. allocate_storage();
  122. itemset = NEW2(nitems, short);
  123. ruleset = NEW2(WORDSIZE(nrules), unsigned);
  124. set_first_derives();
  125. initialize_states();
  126. while (this_state)
  127. {
  128. closure(this_state->items, this_state->nitems);
  129. save_reductions();
  130. new_itemsets();
  131. append_states();
  132. if (nshifts > 0)
  133. save_shifts();
  134. this_state = this_state->next;
  135. }
  136. finalize_closure();
  137. free_storage();
  138. }
  139. int
  140. get_state(int symbol)
  141. {
  142. register int key;
  143. register short *isp1;
  144. register short *isp2;
  145. register short *iend;
  146. register core *sp;
  147. register int found;
  148. register int n;
  149. #ifdef TRACE
  150. fprintf(stderr, "Entering get_state(%d)\n", symbol);
  151. #endif
  152. isp1 = kernel_base[symbol];
  153. iend = kernel_end[symbol];
  154. n = iend - isp1;
  155. key = *isp1;
  156. assert(0 <= key && key < nitems);
  157. sp = state_set[key];
  158. if (sp)
  159. {
  160. found = 0;
  161. while (!found)
  162. {
  163. if (sp->nitems == n)
  164. {
  165. found = 1;
  166. isp1 = kernel_base[symbol];
  167. isp2 = sp->items;
  168. while (found && isp1 < iend)
  169. {
  170. if (*isp1++ != *isp2++)
  171. found = 0;
  172. }
  173. }
  174. if (!found)
  175. {
  176. if (sp->link)
  177. {
  178. sp = sp->link;
  179. }
  180. else
  181. {
  182. sp = sp->link = new_state(symbol);
  183. found = 1;
  184. }
  185. }
  186. }
  187. }
  188. else
  189. {
  190. state_set[key] = sp = new_state(symbol);
  191. }
  192. return (sp->number);
  193. }
  194. void initialize_states(void)
  195. {
  196. register int i;
  197. register short *start_derives;
  198. register core *p;
  199. start_derives = derives[start_symbol];
  200. for (i = 0; start_derives[i] >= 0; ++i)
  201. continue;
  202. p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
  203. if (p == 0) no_space();
  204. p->next = 0;
  205. p->link = 0;
  206. p->number = 0;
  207. p->accessing_symbol = 0;
  208. p->nitems = i;
  209. for (i = 0; start_derives[i] >= 0; ++i)
  210. p->items[i] = rrhs[start_derives[i]];
  211. first_state = last_state = this_state = p;
  212. nstates = 1;
  213. }
  214. void new_itemsets(void)
  215. {
  216. register int i;
  217. register int shiftcount;
  218. register short *isp;
  219. register short *ksp;
  220. register int symbol;
  221. for (i = 0; i < nsyms; i++)
  222. kernel_end[i] = 0;
  223. shiftcount = 0;
  224. isp = itemset;
  225. while (isp < itemsetend)
  226. {
  227. i = *isp++;
  228. symbol = ritem[i];
  229. if (symbol > 0)
  230. {
  231. ksp = kernel_end[symbol];
  232. if (!ksp)
  233. {
  234. shift_symbol[shiftcount++] = symbol;
  235. ksp = kernel_base[symbol];
  236. }
  237. *ksp++ = i + 1;
  238. kernel_end[symbol] = ksp;
  239. }
  240. }
  241. nshifts = shiftcount;
  242. }
  243. core *
  244. new_state(int symbol)
  245. {
  246. register int n;
  247. register core *p;
  248. register short *isp1;
  249. register short *isp2;
  250. register short *iend;
  251. #ifdef TRACE
  252. fprintf(stderr, "Entering new_state(%d)\n", symbol);
  253. #endif
  254. if (nstates >= MAXSHORT)
  255. fatal("too many states");
  256. isp1 = kernel_base[symbol];
  257. iend = kernel_end[symbol];
  258. n = iend - isp1;
  259. p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
  260. p->accessing_symbol = symbol;
  261. p->number = nstates;
  262. p->nitems = n;
  263. isp2 = p->items;
  264. while (isp1 < iend)
  265. *isp2++ = *isp1++;
  266. last_state->next = p;
  267. last_state = p;
  268. nstates++;
  269. return (p);
  270. }
  271. /* show_cores is used for debugging */
  272. void show_cores(void)
  273. {
  274. core *p;
  275. int i, j, k, n;
  276. int itemno;
  277. k = 0;
  278. for (p = first_state; p; ++k, p = p->next)
  279. {
  280. if (k) printf("\n");
  281. printf("state %d, number = %d, accessing symbol = %s\n",
  282. k, p->number, symbol_name[p->accessing_symbol]);
  283. n = p->nitems;
  284. for (i = 0; i < n; ++i)
  285. {
  286. itemno = p->items[i];
  287. printf("%4d ", itemno);
  288. j = itemno;
  289. while (ritem[j] >= 0) ++j;
  290. printf("%s :", symbol_name[rlhs[-ritem[j]]]);
  291. j = rrhs[-ritem[j]];
  292. while (j < itemno)
  293. printf(" %s", symbol_name[ritem[j++]]);
  294. printf(" .");
  295. while (ritem[j] >= 0)
  296. printf(" %s", symbol_name[ritem[j++]]);
  297. printf("\n");
  298. fflush(stdout);
  299. }
  300. }
  301. }
  302. /* show_ritems is used for debugging */
  303. void show_ritems(void)
  304. {
  305. int i;
  306. for (i = 0; i < nitems; ++i)
  307. printf("ritem[%d] = %d\n", i, ritem[i]);
  308. }
  309. /* show_rrhs is used for debugging */
  310. void show_rrhs(void)
  311. {
  312. int i;
  313. for (i = 0; i < nrules; ++i)
  314. printf("rrhs[%d] = %d\n", i, rrhs[i]);
  315. }
  316. /* show_shifts is used for debugging */
  317. void show_shifts(void)
  318. {
  319. shifts *p;
  320. int i, j, k;
  321. k = 0;
  322. for (p = first_shift; p; ++k, p = p->next)
  323. {
  324. if (k) printf("\n");
  325. printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
  326. p->nshifts);
  327. j = p->nshifts;
  328. for (i = 0; i < j; ++i)
  329. printf("\t%d\n", p->shift[i]);
  330. }
  331. }
  332. void save_shifts(void)
  333. {
  334. register shifts *p;
  335. register short *sp1;
  336. register short *sp2;
  337. register short *send;
  338. p = (shifts *) allocate((unsigned) (sizeof(shifts) +
  339. (nshifts - 1) * sizeof(short)));
  340. p->number = this_state->number;
  341. p->nshifts = nshifts;
  342. sp1 = shiftset;
  343. sp2 = p->shift;
  344. send = shiftset + nshifts;
  345. while (sp1 < send)
  346. *sp2++ = *sp1++;
  347. if (last_shift)
  348. {
  349. last_shift->next = p;
  350. last_shift = p;
  351. }
  352. else
  353. {
  354. first_shift = p;
  355. last_shift = p;
  356. }
  357. }
  358. void save_reductions(void)
  359. {
  360. register short *isp;
  361. register short *rp1;
  362. register short *rp2;
  363. register int item;
  364. register int count;
  365. register reductions *p;
  366. register short *rend;
  367. count = 0;
  368. for (isp = itemset; isp < itemsetend; isp++)
  369. {
  370. item = ritem[*isp];
  371. if (item < 0)
  372. {
  373. redset[count++] = -item;
  374. }
  375. }
  376. if (count)
  377. {
  378. p = (reductions *) allocate((unsigned) (sizeof(reductions) +
  379. (count - 1) * sizeof(short)));
  380. p->number = this_state->number;
  381. p->nreds = count;
  382. rp1 = redset;
  383. rp2 = p->rules;
  384. rend = rp1 + count;
  385. while (rp1 < rend)
  386. *rp2++ = *rp1++;
  387. if (last_reduction)
  388. {
  389. last_reduction->next = p;
  390. last_reduction = p;
  391. }
  392. else
  393. {
  394. first_reduction = p;
  395. last_reduction = p;
  396. }
  397. }
  398. }
  399. void set_derives(void)
  400. {
  401. register int i, k;
  402. register int lhs;
  403. register short *rules;
  404. derives = NEW2(nsyms, short *);
  405. rules = NEW2(nvars + nrules, short);
  406. k = 0;
  407. for (lhs = start_symbol; lhs < nsyms; lhs++)
  408. {
  409. derives[lhs] = rules + k;
  410. for (i = 0; i < nrules; i++)
  411. {
  412. if (rlhs[i] == lhs)
  413. {
  414. rules[k] = i;
  415. k++;
  416. }
  417. }
  418. rules[k] = -1;
  419. k++;
  420. }
  421. #ifdef DEBUG
  422. print_derives();
  423. #endif
  424. }
  425. void free_derives(void)
  426. {
  427. FREE(derives[start_symbol]);
  428. FREE(derives);
  429. }
  430. #ifdef DEBUG
  431. void print_derives(void)
  432. {
  433. register int i;
  434. register short *sp;
  435. printf("\nDERIVES\n\n");
  436. for (i = start_symbol; i < nsyms; i++)
  437. {
  438. printf("%s derives ", symbol_name[i]);
  439. for (sp = derives[i]; *sp >= 0; sp++)
  440. {
  441. printf(" %d", *sp);
  442. }
  443. putchar('\n');
  444. }
  445. putchar('\n');
  446. }
  447. #endif
  448. void set_nullable(void)
  449. {
  450. register int i, j;
  451. register int empty;
  452. int done;
  453. nullable = MALLOC(nsyms);
  454. if (nullable == 0) no_space();
  455. for (i = 0; i < nsyms; ++i)
  456. nullable[i] = 0;
  457. done = 0;
  458. while (!done)
  459. {
  460. done = 1;
  461. for (i = 1; i < nitems; i++)
  462. {
  463. empty = 1;
  464. while ((j = ritem[i]) >= 0)
  465. {
  466. if (!nullable[j])
  467. empty = 0;
  468. ++i;
  469. }
  470. if (empty)
  471. {
  472. j = rlhs[-j];
  473. if (!nullable[j])
  474. {
  475. nullable[j] = 1;
  476. done = 0;
  477. }
  478. }
  479. }
  480. }
  481. #ifdef DEBUG
  482. for (i = 0; i < nsyms; i++)
  483. {
  484. if (nullable[i])
  485. printf("%s is nullable\n", symbol_name[i]);
  486. else
  487. printf("%s is not nullable\n", symbol_name[i]);
  488. }
  489. #endif
  490. }
  491. void free_nullable(void)
  492. {
  493. FREE(nullable);
  494. }
  495. void lr0(void)
  496. {
  497. set_derives();
  498. set_nullable();
  499. generate_states();
  500. }