gencode.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360
  1. /* Copyright (c) 1991 by the Vrije Universiteit, Amsterdam, the Netherlands.
  2. * For full copyright and restrictions on use see the file COPYING in the top
  3. * level of the LLgen tree.
  4. */
  5. /*
  6. * L L G E N
  7. *
  8. * An Extended LL(1) Parser Generator
  9. *
  10. * Author : Ceriel J.H. Jacobs
  11. */
  12. /*
  13. * gencode.c
  14. * Defines the routine "gencode", which generates the parser
  15. * we wanted so badly.
  16. * This file is a mess, it should be cleaned up some time.
  17. */
  18. # include "types.h"
  19. # include "io.h"
  20. # include "extern.h"
  21. # include "sets.h"
  22. # include "assert.h"
  23. # include "cclass.h"
  24. # ifndef NORCSID
  25. static string rcsid3 = "$Id$";
  26. #endif /* NORCSID */
  27. /*
  28. * Some codestrings used more than once
  29. */
  30. static string c_arrend = "0 };\n";
  31. static string c_close = "}\n";
  32. static string c_break = "break;\n";
  33. static string c_read = "LLread();\n";
  34. /* Some constants used for reading from the action file */
  35. # define ENDDECL 0400
  36. # define IDENT 0401
  37. static int nlabel; /* count for the generation of labels */
  38. static int firsts; /* are there any? */
  39. static int listcount;
  40. /* In this file the following routines are defined: */
  41. extern gencode();
  42. STATIC opentemp();
  43. STATIC geninclude();
  44. STATIC genrecovery();
  45. #ifdef NON_CORRECTING
  46. STATIC genncrecovery();
  47. #endif
  48. STATIC string genname();
  49. STATIC generate();
  50. STATIC prset();
  51. STATIC macro();
  52. STATIC controlline();
  53. STATIC getparams();
  54. STATIC getansiparams();
  55. STATIC genprototypes();
  56. STATIC gettok();
  57. STATIC rulecode();
  58. STATIC int * dopush();
  59. STATIC int * mk_tokenlist();
  60. STATIC getaction();
  61. STATIC alternation();
  62. STATIC codeforterm();
  63. STATIC genswhead();
  64. STATIC gencases();
  65. STATIC genpush();
  66. STATIC genpop();
  67. STATIC genincrdecr();
  68. STATIC add_cases();
  69. STATIC int analyze_switch();
  70. STATIC out_list();
  71. STATIC genextname();
  72. STATIC correct_prefix();
  73. # define NOPOP -20000
  74. p_mem alloc(), ralloc();
  75. doclose(f)
  76. FILE *f;
  77. {
  78. if (ferror(f) != 0) {
  79. fatal(0,"Write error on temporary");
  80. }
  81. fclose(f);
  82. }
  83. STATIC int *
  84. mk_tokenlist()
  85. {
  86. register int i = ntokens;
  87. register int *p = (int *)alloc((unsigned)(i * sizeof(int))) + i;
  88. while (i--) *--p = -1;
  89. return p;
  90. }
  91. STATIC
  92. genhdr()
  93. {
  94. if (!firsts) fputs("#define LLNOFIRSTS\n", fpars);
  95. if (ansi_c) fputs("#define LL_ANSI_C 1\n", fpars);
  96. else {
  97. fputs("#if __STDC__ || __cplusplus\n#define LL_ANSI_C 1\n#endif\n", fpars);
  98. }
  99. #ifdef NON_CORRECTING
  100. if (non_corr) fputs("#define LL_NON_CORR 1\n", fpars);
  101. #endif
  102. fprintf(fpars, "#define LL_LEXI %s\n", lexical);
  103. copyfile(incl_file);
  104. }
  105. gencode(argc) {
  106. register p_file p = files;
  107. /* Set up for code generation */
  108. if ((fact = fopen(f_temp,"r")) == NULL) {
  109. fatal(0,e_noopen,f_temp);
  110. }
  111. #ifdef NON_CORRECTING
  112. /* The non-correcting error recovery must be generated BEFORE
  113. parser code is generated!!!! In case of conflict resolvers,
  114. the code-generation process will delete conflicting symbols
  115. from first and followsets, making them UNUSABLE for the
  116. non-correcting error recovery code.
  117. */
  118. if (non_corr)
  119. genncrecovery();
  120. #endif
  121. /* For every source file .... */
  122. while (argc--) {
  123. /* Open temporary */
  124. f_input = p->f_name;
  125. opentemp(f_input);
  126. correct_prefix();
  127. /* generate code ... */
  128. generate(p);
  129. getaction(2);
  130. doclose(fpars);
  131. /* And install */
  132. install(genname(p->f_name),p->f_name);
  133. p++;
  134. }
  135. geninclude();
  136. genrecovery();
  137. fclose(fact);
  138. }
  139. STATIC
  140. opentemp(str) string str; {
  141. if ((fpars = fopen(f_pars,"w")) == NULL) {
  142. fatal(0,e_noopen,f_pars);
  143. }
  144. if (!str) str = ".";
  145. fprintf(fpars,LLgenid,str);
  146. }
  147. STATIC
  148. geninclude() {
  149. register p_token p;
  150. int maxno = 0;
  151. opentemp((string) 0);
  152. for (p = tokens; p < maxt; p++) {
  153. if (p->t_tokno > maxno) maxno = p->t_tokno;
  154. if (p->t_tokno >= 0400) {
  155. fprintf(fpars,"#define %s %d\n",
  156. p->t_string,
  157. p->t_tokno);
  158. }
  159. }
  160. fprintf(fpars, "#define %s_MAXTOKNO %d\n", prefix ? prefix : "LL",
  161. maxno);
  162. #ifdef NON_CORRECTING
  163. if (non_corr) {
  164. fprintf(fpars, "#define %sNONCORR\n", prefix ? prefix : "LL");
  165. }
  166. #endif
  167. doclose(fpars);
  168. install(f_include, ".");
  169. }
  170. STATIC
  171. genrecovery() {
  172. register FILE *f;
  173. register p_token t;
  174. register int *q;
  175. register p_nont p;
  176. register p_set *psetl;
  177. int *index;
  178. int i;
  179. register p_start st;
  180. opentemp((string) 0);
  181. f = fpars;
  182. correct_prefix();
  183. genhdr();
  184. for (st = start; st; st = st->ff_next) {
  185. /* Make sure that every set the parser needs is in the list
  186. * before generating a define of the number of them!
  187. */
  188. p = &nonterms[st->ff_nont];
  189. if (g_gettype(p->n_rule) == ALTERNATION) {
  190. findindex(p->n_contains);
  191. }
  192. }
  193. i = maxptr - setptr;
  194. fprintf(f,
  195. "#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n",
  196. nbytes,
  197. i > 0 ? i : 1,
  198. ntokens);
  199. if (onerror) fprintf(f,"#define LL_USERHOOK %s\n", onerror);
  200. #ifdef NON_CORRECTING
  201. if (non_corr) {
  202. fputs("static int nc_done = 0;\n", f);
  203. fputs("static int err_seen = 0;\n", f);
  204. }
  205. #endif
  206. /* Now generate the routines that call the startsymbols */
  207. fputs("#if LL_ANSI_C\n", f);
  208. for (st = start; st; st = st->ff_next) {
  209. p = &nonterms[st->ff_nont];
  210. fputs("void ", f);
  211. genextname(st->ff_nont, p->n_name, f);
  212. fputs("(void);\n", f);
  213. }
  214. fputs("#endif\n", f);
  215. for (st = start; st; st = st->ff_next) {
  216. fprintf(f, "#if LL_ANSI_C\nvoid %s(void)\n#else\n%s()\n#endif\n", st->ff_name, st->ff_name);
  217. p = &nonterms[st->ff_nont];
  218. fputs(" {\n\tunsigned int s[LL_NTERMINALS+LL_NSETS+2];", f);
  219. #ifdef NON_CORRECTING
  220. if (non_corr) {
  221. fputs(" \n\tint oldstartsymb;", f);
  222. fputs(" \n\tint oldncflag;", f);
  223. fputs(" \n\toldstartsymb = LLstartsymb;", f);
  224. fputs(" \n\toldncflag = nc_done;", f);
  225. fputs(" \n\tnc_done = 0;", f);
  226. fprintf(f, "\n\tLLstartsymb = %d;", st->ff_nont + assval);
  227. }
  228. #endif
  229. fputs("\n\tLLnewlevel(s);\n\tLLread();\n", f);
  230. if (g_gettype(p->n_rule) == ALTERNATION) {
  231. genpush(findindex(p->n_contains));
  232. }
  233. genextname(st->ff_nont, p->n_name, f);
  234. fputs("();\n", f);
  235. if (getntout(p) == NOSCANDONE) {
  236. fputs("\tLL_NOSCANDONE(EOFILE);\n",f);
  237. }
  238. else fputs("\tLL_SCANDONE(EOFILE);\n",f);
  239. fputs("\tLLoldlevel(s);\n",f);
  240. #ifdef NON_CORRECTING
  241. if (non_corr) {
  242. fputs("\tLLstartsymb = oldstartsymb;\n", f);
  243. fputs("\tif (nc_done == 1) { \n", f);
  244. fputs("\t\terr_seen = 1;\n", f);
  245. fputs("\tnc_done = oldncflag;\n", f);
  246. fputs("\t}\n", f);
  247. }
  248. #endif
  249. fputs("}\n", f);
  250. }
  251. /* Now generate the sets */
  252. fputs("static char LLsets[] = {\n",f);
  253. for (psetl = setptr; psetl < maxptr; psetl++) prset(*psetl);
  254. fputs(c_arrend, f);
  255. index = (int *) alloc((unsigned) (assval * sizeof(int)));
  256. for (q = index; q < &index[assval];) *q++ = -1;
  257. for (t = tokens; t < maxt; t++) {
  258. index[t->t_tokno] = t - tokens;
  259. }
  260. fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n",f);
  261. for (q = index+1; q < &index[assval]; q++) {
  262. fprintf(f, "%d,\n", *q);
  263. }
  264. fputs(c_arrend, f);
  265. free((p_mem) index);
  266. if (onerror) {
  267. fputs("static short LLtok[] = {\n", f);
  268. for (t = tokens; t < maxt; t++) {
  269. fprintf(f, t->t_tokno<0400 ? "'%s',\n" : "%s,\n",t->t_string);
  270. }
  271. fputs(c_arrend, f);
  272. }
  273. fputs("#define LL_NEWMESS\n", f);
  274. copyfile(rec_file);
  275. doclose(f);
  276. install(f_rec, ".");
  277. }
  278. #ifdef NON_CORRECTING
  279. STATIC
  280. genncrecovery() {
  281. register FILE *f;
  282. register p_token t;
  283. register int *q;
  284. int *index;
  285. /* Generate the non-correcting error recovery file */
  286. opentemp((string) 0);
  287. f = fpars;
  288. genhdr();
  289. correct_prefix();
  290. save_grammar(f);
  291. fprintf(f, "#define LLFIRST_NT %d\n", assval);
  292. fprintf(f, "#define LLSETSIZE %d\n", nbytes);
  293. index = (int *) alloc((unsigned) (assval * sizeof(int)));
  294. for (q = index; q < &index[assval];) *q++ = -1;
  295. for (t = tokens; t < maxt; t++) {
  296. index[t->t_tokno] = t - tokens;
  297. }
  298. fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n",f);
  299. for (q = index+1; q < &index[assval]; q++) {
  300. fprintf(f, "%d,\n", *q);
  301. }
  302. fputs(c_arrend, f);
  303. free((p_mem) index);
  304. copyfile(nc_incl_file);
  305. copyfile(nc_rec_file);
  306. doclose(f);
  307. install(f_nc, ".");
  308. }
  309. #endif
  310. STATIC
  311. generate(f) p_file f; {
  312. /*
  313. * Generates a parsing routine for every nonterminal
  314. */
  315. register int s;
  316. register p_nont p;
  317. int i;
  318. register p_first ff;
  319. int mustpop;
  320. int is_first = 1;
  321. fprintf(fpars, "#define LL_LEXI %s\n", lexical);
  322. listcount = 0;
  323. /* Generate first sets */
  324. for (ff = f->f_firsts; ff; ff = ff->ff_next) {
  325. macro(ff->ff_name,&nonterms[ff->ff_nont]);
  326. }
  327. genhdr();
  328. /* For every nonterminal generate a function */
  329. for (s = f->f_nonterminals; s != -1; s = p->n_next) {
  330. p = &nonterms[s];
  331. /* Generate functions in the order in which the nonterminals
  332. * were defined in the grammar. This is important, because
  333. * of synchronisation with the action file
  334. */
  335. while (p->n_count--) getaction(1);
  336. if (g_gettype(p->n_rule) == EORULE &&
  337. getntparams(p) == 0) {
  338. continue;
  339. }
  340. if (is_first) genprototypes(f);
  341. is_first = 0;
  342. if (p->n_flags & GENSTATIC) fputs("static\n", fpars);
  343. fputs("#if LL_ANSI_C\nvoid\n#endif\n", fpars);
  344. genextname(s, p->n_name, fpars);
  345. if (p->n_flags & PARAMS) {
  346. long off = ftell(fact);
  347. fputs("(\n#if LL_ANSI_C\n", fpars);
  348. controlline();
  349. getansiparams(1);
  350. fseek(fact, off, 0);
  351. fputs("#else\n", fpars);
  352. controlline();
  353. getparams();
  354. fputs("#endif\n{\n", fpars);
  355. }
  356. else fputs("(\n#if LL_ANSI_C\nvoid\n#endif\n) {\n", fpars);
  357. if (p->n_flags & LOCALS) getaction(1);
  358. i = getntsafe(p);
  359. mustpop = NOPOP;
  360. if (g_gettype(p->n_rule) == ALTERNATION &&
  361. i > SAFESCANDONE) {
  362. mustpop = findindex(p->n_contains);
  363. if (i == NOSCANDONE) {
  364. fputs(c_read, fpars);
  365. i = SCANDONE;
  366. }
  367. }
  368. nlabel = 1;
  369. rulecode(p->n_rule,
  370. i,
  371. getntout(p) != NOSCANDONE,
  372. mustpop);
  373. fputs(c_close, fpars);
  374. }
  375. }
  376. STATIC
  377. prset(p) p_set p; {
  378. register int k;
  379. register unsigned i;
  380. int j;
  381. j = nbytes;
  382. for (;;) {
  383. i = (unsigned) *p++;
  384. for (k = 0; k < sizeof(int); k++) {
  385. fprintf(fpars,"'\\%o',",(int)(i & 0377));
  386. i >>= 8;
  387. if (--j == 0) {
  388. fputs("\n",fpars);
  389. return;
  390. }
  391. }
  392. }
  393. /* NOTREACHED */
  394. }
  395. STATIC
  396. macro(s,n) string s; p_nont n; {
  397. int i;
  398. i = findindex(n->n_first);
  399. if (i < 0) {
  400. fprintf(fpars, "#define %s(x) ((x) == %d)\n",
  401. s,
  402. tokens[-(i+1)].t_tokno);
  403. return;
  404. }
  405. firsts = 1;
  406. fprintf(fpars,"#define %s(x) LLfirst((x), %d)\n", s, i);
  407. }
  408. STATIC
  409. controlline() {
  410. /* Copy a compiler control line */
  411. register int l;
  412. register FILE *f1,*f2;
  413. f1 = fact; f2 = fpars;
  414. l = getc(f1);
  415. assert(l == '\0');
  416. do {
  417. l = getc(f1);
  418. if (l == EOF) fatal(0, "temp file mangled");
  419. putc(l,f2);
  420. } while ( l != '\n' ) ;
  421. }
  422. STATIC
  423. getparams() {
  424. /* getparams is called if a nonterminal has parameters. The names
  425. * of the parameters have to be found, and they should be declared
  426. */
  427. long off;
  428. register int l;
  429. long ftell();
  430. char first;
  431. char add_semi = ' ';
  432. first = ' ';
  433. /* save offset in file to be able to copy the declaration later */
  434. off = ftell(fact);
  435. /* First pass through declaration, find the parameter names */
  436. ltext[0] = '\0';
  437. while ((l = gettok()) != ENDDECL) {
  438. if ((l == ';' || l == ',') && ltext[0] != '\0') {
  439. /*
  440. * The last identifier found before a ';' or a ','
  441. * must be a parameter
  442. */
  443. fprintf(fpars,"%c%s", first, ltext);
  444. first = ',';
  445. ltext[0] = '\0';
  446. }
  447. }
  448. if (ltext[0] != '\0') {
  449. fprintf(fpars, "%c%s", first, ltext);
  450. add_semi = ';';
  451. }
  452. fputs(") ",fpars);
  453. /*
  454. * Now copy the declarations
  455. */
  456. l = getc(fact); /* patch: some implementations of fseek
  457. do not work properly after "ungetc"
  458. */
  459. fseek(fact,off,0);
  460. getaction(0);
  461. fprintf(fpars, "%c\n",add_semi);
  462. }
  463. STATIC
  464. genprototypes(f)
  465. register p_file f;
  466. {
  467. /*
  468. * Generate prototypes for all nonterminals
  469. */
  470. register int i;
  471. register p_nont p;
  472. long off = ftell(fact);
  473. fputs("#if LL_ANSI_C\n", fpars);
  474. for (i = 0; i < nnonterms; i++) {
  475. if (! IN(f->f_used, i)) continue;
  476. p = &nonterms[i];
  477. if (g_gettype(p->n_rule) == EORULE &&
  478. getntparams(p) == 0) {
  479. continue;
  480. }
  481. if (p->n_flags & GENSTATIC) fputs("static ", fpars);
  482. fputs("void ", fpars);
  483. genextname(i, p->n_name, fpars);
  484. if (p->n_flags & PARAMS) {
  485. fputs("(\n", fpars);
  486. fseek(fact, p->n_off, 0);
  487. controlline();
  488. getansiparams(0);
  489. }
  490. else fputs("(void);\n", fpars);
  491. }
  492. fseek(fact, off, 0);
  493. fputs("#else\n", fpars);
  494. for (i = 0; i < nnonterms; i++) {
  495. if (! IN(f->f_used, i)) continue;
  496. p = &nonterms[i];
  497. if (!(p->n_flags & GENSTATIC)) continue;
  498. if (g_gettype(p->n_rule) == EORULE &&
  499. getntparams(p) == 0) {
  500. continue;
  501. }
  502. fputs("static ", fpars);
  503. genextname(i, p->n_name, fpars);
  504. fputs("();\n", fpars);
  505. }
  506. fputs("#endif\n", fpars);
  507. }
  508. STATIC
  509. getansiparams(mkdef) {
  510. /* getansiparams is called if a nonterminal has parameters
  511. * and an ANSI C function definition/declaration has to be produced.
  512. * If a definition has to be produced, "mkdef" is set to 1.
  513. */
  514. register int l;
  515. int delayed = 0;
  516. ltext[0] = '\0';
  517. while ((l = gettok()) != ENDDECL) {
  518. if (l > 0177 || c_class[l] != ISSPA) {
  519. if (delayed) {
  520. fputc(',', fpars);
  521. delayed = 0;
  522. }
  523. }
  524. if ((l == ';' || l == ',') && ltext[0] != '\0') {
  525. /*
  526. * The last identifier found before a ';' or a ','
  527. * must be a parameter
  528. */
  529. delayed = 1;
  530. ltext[0] = '\0';
  531. }
  532. else if (l == IDENT) fprintf(fpars, "%s", ltext);
  533. else fputc(l, fpars);
  534. }
  535. fprintf(fpars, ") %c\n", mkdef ? ' ' : ';');
  536. }
  537. STATIC
  538. gettok() {
  539. /* Read from the action file. */
  540. register int ch;
  541. register string c;
  542. register FILE *f;
  543. f = fact;
  544. ch = getc(f);
  545. switch(ch) {
  546. case '\n':
  547. ch = getc(f);
  548. if (ch != EOF) {
  549. ungetc(ch,f);
  550. if (ch != '\0') return '\n';
  551. }
  552. return ENDDECL;
  553. case '\0':
  554. ungetc(ch,f);
  555. /* Fall through */
  556. case EOF :
  557. return ENDDECL;
  558. default :
  559. if (c_class[ch] == ISLET) {
  560. c = ltext;
  561. do {
  562. *c++ = ch;
  563. if (c-ltext >= LTEXTSZ) --c;
  564. ch = getc(f);
  565. } while (c_class[ch] == ISLET || c_class[ch] == ISDIG);
  566. if (ch != EOF) ungetc(ch,f);
  567. *c = '\0';
  568. return IDENT;
  569. }
  570. return ch;
  571. }
  572. }
  573. STATIC
  574. rulecode(p,safety,mustscan,mustpop) register p_gram p; {
  575. /*
  576. * Code for a production rule.
  577. */
  578. register int toplevel = 1;
  579. register FILE *f;
  580. register int *ppu;
  581. int *pushlist;
  582. int *ppushlist;
  583. /*
  584. * First generate code to push the contains sets of this rule
  585. * on a stack
  586. */
  587. ppushlist = dopush(p,safety,1, &pushlist);
  588. if (mustpop != NOPOP) for (ppu = pushlist; ppu < ppushlist; ppu++) {
  589. if (*ppu == mustpop) {
  590. *ppu = mustpop = NOPOP;
  591. break;
  592. }
  593. }
  594. if (g_gettype(p) != ALTERNATION) {
  595. genpop(mustpop);
  596. mustpop = NOPOP;
  597. }
  598. for (ppu = pushlist; ppu < ppushlist; ppu++) genpush(*ppu);
  599. free((p_mem) pushlist);
  600. f = fpars;
  601. for (;;) {
  602. switch (g_gettype(p)) {
  603. case EORULE :
  604. if (mustscan && safety == NOSCANDONE) {
  605. fputs(c_read,f);
  606. }
  607. return;
  608. case LITERAL :
  609. case TERMINAL : {
  610. register p_token t;
  611. string s;
  612. t = &tokens[g_getcont(p)];
  613. if (toplevel == 0) {
  614. fprintf(f,"LLtdecr(%d);\n", g_getcont(p));
  615. }
  616. if (safety == SAFE) {
  617. fputs("LL_SAFE(",f);
  618. }
  619. else if (safety == SAFESCANDONE) {
  620. fputs("LL_SSCANDONE(",f);
  621. }
  622. else if (safety == SCANDONE) {
  623. fputs("LL_SCANDONE(",f);
  624. }
  625. else /* if (safety == NOSCANDONE) */ {
  626. fputs("LL_NOSCANDONE(", f);
  627. }
  628. if (t->t_tokno < 0400) s = "'%s');\n";
  629. else s = "%s);\n";
  630. fprintf(f,s,t->t_string);
  631. if (safety <= SAFESCANDONE && toplevel > 0) {
  632. safety = NOSCANDONE;
  633. toplevel = -1;
  634. p++;
  635. continue;
  636. }
  637. safety = NOSCANDONE;
  638. break; }
  639. case NONTERM : {
  640. register p_nont n = &nonterms[g_getcont(p)];
  641. if (safety == NOSCANDONE &&
  642. getntsafe(n) < NOSCANDONE) {
  643. safety = getntsafe(n);
  644. fputs(c_read, f);
  645. }
  646. if (toplevel == 0 &&
  647. (g_gettype(n->n_rule) != ALTERNATION ||
  648. getntsafe(n) <= SAFESCANDONE)) {
  649. genpop(findindex(n->n_contains));
  650. }
  651. genextname(g_getcont(p), n->n_name, f);
  652. if (g_getnpar(p)) {
  653. fputs("(\n", f);
  654. controlline();
  655. getaction(0);
  656. fputs(");\n",f);
  657. }
  658. else fputs("();\n", f);
  659. safety = getntout(n);
  660. break; }
  661. case TERM :
  662. safety = codeforterm(g_getterm(p),
  663. safety,
  664. toplevel);
  665. break;
  666. case ACTION :
  667. getaction(1);
  668. p++;
  669. continue;
  670. case ALTERNATION :
  671. alternation(p, safety, mustscan, mustpop, 0);
  672. return;
  673. }
  674. p++;
  675. toplevel = 0;
  676. }
  677. }
  678. STATIC
  679. alternation(pp, safety, mustscan, mustpop, lb)
  680. p_gram pp;
  681. {
  682. register p_gram p = pp;
  683. register FILE *f = fpars;
  684. register p_link l;
  685. int hulp, hulp1,hulp2;
  686. int haddefault = 0;
  687. int nsafe;
  688. p_set set;
  689. p_set setalloc();
  690. int *tokenlist = mk_tokenlist();
  691. int casecnt = 0;
  692. int compacted;
  693. int unsafe;
  694. assert(safety < NOSCANDONE);
  695. hulp = nlabel++;
  696. hulp1 = nlabel++;
  697. hulp2 = nlabel++;
  698. if (!lb) lb = hulp1;
  699. unsafe = onerror || safety > SAFESCANDONE;
  700. if (!unsafe) {
  701. genpop(mustpop);
  702. mustpop = NOPOP;
  703. }
  704. if (unsafe && hulp1 == lb) {
  705. fprintf(f,"goto L_%d; /* so that the label is used for certain */\nL_%d: ;\n", hulp1, hulp1);
  706. }
  707. if (safety == SAFE) {
  708. /* check if we can avoid to generate the switch */
  709. for (;;) {
  710. if (g_gettype(p) == EORULE) return;
  711. l = g_getlink(p);
  712. if (l->l_flag & COND) break;
  713. if ((g_gettype(l->l_rule) != TERMINAL &&
  714. g_gettype(l->l_rule) != LITERAL) ||
  715. g_gettype(l->l_rule+1) != EORULE) break;
  716. p++;
  717. }
  718. p = pp;
  719. }
  720. while (g_gettype(p) != EORULE) {
  721. set = 0;
  722. l = g_getlink(p);
  723. if (l->l_flag & COND) {
  724. if (!(l->l_flag & NOCONF)) {
  725. set = setalloc();
  726. setunion(set, l->l_others);
  727. setintersect(set, l->l_symbs);
  728. setminus(l->l_symbs, set);
  729. setminus(l->l_others, set);
  730. add_cases(set, tokenlist, casecnt++);
  731. }
  732. }
  733. if (!unsafe && (l->l_flag & DEF)) {
  734. haddefault = 1;
  735. }
  736. else add_cases(l->l_symbs, tokenlist, casecnt++);
  737. if (l->l_flag & DEF) {
  738. haddefault = 1;
  739. }
  740. if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) {
  741. p++;
  742. if (g_gettype(p+1) == EORULE) {
  743. setminus(g_getlink(p)->l_symbs, set);
  744. free((p_mem) set);
  745. continue;
  746. }
  747. free((p_mem) set);
  748. if (!haddefault) {
  749. }
  750. else {
  751. add_cases(l->l_others, tokenlist, casecnt++);
  752. unsafe = 0;
  753. }
  754. break;
  755. }
  756. p++;
  757. }
  758. unsafe = onerror || safety > SAFESCANDONE;
  759. p = pp;
  760. haddefault = 0;
  761. compacted = analyze_switch(tokenlist);
  762. if (compacted) {
  763. fputs("{", f);
  764. out_list(tokenlist, listcount++, casecnt);
  765. }
  766. else fputs("switch(LLcsymb) {\n", f);
  767. casecnt = 0;
  768. while (g_gettype(p) != EORULE) {
  769. l = g_getlink(p);
  770. if (l->l_flag & COND) {
  771. if (l->l_flag & NOCONF) {
  772. fputs("#ifdef ___NOCONFLICT___\n", f);
  773. }
  774. else gencases(tokenlist, casecnt++, compacted);
  775. controlline();
  776. fputs("if (!",f);
  777. getaction(0);
  778. fprintf(f,") goto L_%d;\n", hulp);
  779. if (l->l_flag & NOCONF) {
  780. fputs("#endif\n", f);
  781. }
  782. }
  783. if (!unsafe && (l->l_flag & DEF)) {
  784. haddefault = 1;
  785. fputs("default:\n", f);
  786. }
  787. else gencases(tokenlist, casecnt++, compacted);
  788. nsafe = SAFE;
  789. if (l->l_flag & DEF) {
  790. if (unsafe) {
  791. fprintf(f,"goto L_%d;\nL_%d: ;\n", hulp2, hulp2);
  792. }
  793. if (safety != SAFE) nsafe = SAFESCANDONE;
  794. }
  795. rulecode(l->l_rule, nsafe, mustscan, mustpop);
  796. fputs(c_break,f);
  797. if (unsafe && (l->l_flag & DEF)) {
  798. haddefault = 1;
  799. fprintf(f,
  800. "default: if (LLskip()) goto L_%d;\ngoto L_%d;\n",
  801. lb, hulp2);
  802. }
  803. if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) {
  804. p++;
  805. fprintf(f,"goto L_%d;\nL_%d : ;\n", hulp, hulp);
  806. if (g_gettype(p+1) == EORULE) {
  807. continue;
  808. }
  809. if (!haddefault) {
  810. fputs("default:\n", f);
  811. }
  812. else {
  813. gencases(tokenlist, casecnt++, compacted);
  814. safety = SAFE;
  815. unsafe = 0;
  816. }
  817. if (! unsafe) {
  818. genpop(mustpop);
  819. mustpop = NOPOP;
  820. }
  821. alternation(p,safety,mustscan,mustpop,lb);
  822. break;
  823. }
  824. p++;
  825. }
  826. if (compacted) fputs(c_close, f);
  827. fputs(c_close, f);
  828. free((p_mem) tokenlist);
  829. }
  830. STATIC int *
  831. dopush(p,safety,toplevel,pp) register p_gram p; int **pp; {
  832. /*
  833. * The safety only matters if toplevel != 0
  834. */
  835. unsigned int i = 100;
  836. register int *ip = (int *) alloc(100 * sizeof(int));
  837. *pp = ip;
  838. for (;;) {
  839. if (ip - *pp >= i) {
  840. *pp = (int *)
  841. ralloc((p_mem) (*pp), (i + 100) * sizeof(int));
  842. ip = *pp + i;
  843. i += 100;
  844. }
  845. switch(g_gettype(p)) {
  846. case EORULE :
  847. case ALTERNATION :
  848. return ip;
  849. case TERM : {
  850. register p_term q;
  851. int rep_kind, rep_count;
  852. q = g_getterm(p);
  853. rep_kind = r_getkind(q);
  854. rep_count = r_getnum(q);
  855. if (!(toplevel > 0 && safety <= SAFESCANDONE &&
  856. (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) {
  857. *ip++ = findindex(q->t_contains);
  858. }
  859. break; }
  860. case LITERAL :
  861. case TERMINAL :
  862. if (toplevel > 0 && safety <= SAFESCANDONE) {
  863. toplevel = -1;
  864. p++;
  865. safety = NOSCANDONE;
  866. continue;
  867. }
  868. if (toplevel == 0) *ip++ = -(g_getcont(p)+1);
  869. break;
  870. case NONTERM : {
  871. register p_nont n;
  872. n = &nonterms[g_getcont(p)];
  873. if (toplevel == 0 ||
  874. (g_gettype(n->n_rule) == ALTERNATION &&
  875. getntsafe(n) > SAFESCANDONE)) {
  876. *ip++ = findindex(n->n_contains);
  877. }
  878. break; }
  879. case ACTION :
  880. p++;
  881. continue;
  882. }
  883. toplevel = 0;
  884. safety = NOSCANDONE;
  885. p++;
  886. }
  887. }
  888. # define max(a,b) ((a) < (b) ? (b) : (a))
  889. STATIC
  890. getaction(flag) {
  891. /* Read an action from the action file.
  892. * flag = 1 if it is an action,
  893. * 0 when reading parameters
  894. */
  895. register int ch;
  896. register FILE *f;
  897. int mark = 0;
  898. if (flag == 1) {
  899. controlline();
  900. }
  901. f = fpars;
  902. for (;;) {
  903. ch = gettok();
  904. switch(ch) {
  905. case ENDDECL:
  906. if (flag != 2) break;
  907. ch = getc(fact);
  908. assert(ch == '\0');
  909. fputs("\n",f);
  910. if (mark) return;
  911. mark = 1;
  912. continue;
  913. case IDENT :
  914. fputs(ltext,f);
  915. continue;
  916. }
  917. mark = 0;
  918. if (ch == ENDDECL) break;
  919. putc(ch,f);
  920. }
  921. if (flag) fputs("\n",f);
  922. }
  923. STATIC
  924. codeforterm(q,safety,toplevel) register p_term q; {
  925. /*
  926. * Generate code for a term
  927. */
  928. register FILE *f = fpars;
  929. register int rep_count = r_getnum(q);
  930. register int rep_kind = r_getkind(q);
  931. int term_is_persistent = (q->t_flags & PERSISTENT);
  932. int ispushed = NOPOP;
  933. if (!(toplevel > 0 &&
  934. (safety == 0 || (!onerror && safety <= SAFESCANDONE)) &&
  935. (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) {
  936. ispushed = findindex(q->t_contains);
  937. }
  938. if (safety == NOSCANDONE && (rep_kind != FIXED || rep_count == 0 ||
  939. gettout(q) != NOSCANDONE)) {
  940. fputs(c_read, f);
  941. safety = SCANDONE;
  942. }
  943. if (rep_kind == PLUS && !term_is_persistent) {
  944. int temp;
  945. temp = findindex(q->t_first);
  946. if (temp != ispushed) {
  947. genpop(ispushed);
  948. ispushed = temp;
  949. genpush(temp);
  950. }
  951. }
  952. if (rep_count) {
  953. /* N > 0, so generate fixed forloop */
  954. fputs("{\nregister LL_i;\n", f);
  955. assert(ispushed != NOPOP);
  956. fprintf(f, "for (LL_i = %d; LL_i >= 0; LL_i--) {\n", rep_count - 1);
  957. if (rep_kind == FIXED) {
  958. fputs("if (!LL_i) ", f);
  959. genpop(ispushed);
  960. genpush(ispushed);
  961. if (safety == NOSCANDONE) {
  962. assert(gettout(q) == NOSCANDONE);
  963. fputs(c_read, f);
  964. }
  965. }
  966. }
  967. else if (rep_kind != OPT && rep_kind != FIXED) {
  968. /* '+' or '*', so generate infinite loop */
  969. fputs("for (;;) {\n",f);
  970. }
  971. else if (rep_kind == OPT &&
  972. (safety == 0 || (!onerror && safety <= SAFESCANDONE))) {
  973. genpop(ispushed);
  974. ispushed = NOPOP;
  975. }
  976. if (rep_kind == STAR || rep_kind == OPT) {
  977. genswhead(q, rep_kind, rep_count, safety, ispushed);
  978. }
  979. rulecode(q->t_rule,
  980. t_safety(rep_kind,rep_count,term_is_persistent,safety),
  981. gettout(q) != NOSCANDONE,
  982. rep_kind == FIXED ? ispushed : NOPOP);
  983. if (gettout(q) == NOSCANDONE && rep_kind != FIXED) {
  984. fputs(c_read, f);
  985. }
  986. /* in the case of '+', the if is after the code for the rule */
  987. if (rep_kind == PLUS) {
  988. if (rep_count) {
  989. fputs("if (!LL_i) break;\n", f);
  990. }
  991. genswhead(q, rep_kind, rep_count, safety, ispushed);
  992. }
  993. if (rep_kind != OPT && rep_kind != FIXED) fputs("continue;\n", f);
  994. if (rep_kind != FIXED) {
  995. fputs(c_close, f); /* Close switch */
  996. fputs(c_close, f);
  997. if (rep_kind != OPT) {
  998. genpop(ispushed);
  999. fputs(c_break, f);
  1000. }
  1001. }
  1002. if (rep_kind != OPT && (rep_kind != FIXED || rep_count > 0)) {
  1003. fputs(c_close, f); /* Close for */
  1004. if (rep_count > 0) {
  1005. fputs(c_close, f);/* Close Register ... */
  1006. }
  1007. }
  1008. return t_after(rep_kind, rep_count, gettout(q));
  1009. }
  1010. STATIC
  1011. genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; {
  1012. /*
  1013. * Generate switch statement for term q
  1014. */
  1015. register FILE *f = fpars;
  1016. p_set p1;
  1017. p_set setalloc();
  1018. int hulp1 = 0, hulp2;
  1019. int safeterm;
  1020. int termissafe = 0;
  1021. int casecnt = 0;
  1022. int *tokenlist = mk_tokenlist();
  1023. int compacted;
  1024. if (rep_kind == PLUS) safeterm = gettout(q);
  1025. else if (rep_kind == OPT) safeterm = safety;
  1026. else /* if (rep_kind == STAR) */ safeterm = max(safety, gettout(q));
  1027. hulp2 = nlabel++;
  1028. fprintf(f, "goto L_%d;\nL_%d : ", hulp2, hulp2);
  1029. if (q->t_flags & RESOLVER) {
  1030. hulp1 = nlabel++;
  1031. if (! (q->t_flags & NOCONF)) {
  1032. p1 = setalloc();
  1033. setunion(p1,q->t_first);
  1034. setintersect(p1,q->t_follow);
  1035. /*
  1036. * p1 now points to a set containing the conflicting
  1037. * symbols
  1038. */
  1039. setminus(q->t_first, p1);
  1040. setminus(q->t_follow, p1);
  1041. setminus(q->t_contains, p1);
  1042. add_cases(p1, tokenlist, casecnt++);
  1043. free((p_mem) p1);
  1044. }
  1045. }
  1046. if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) {
  1047. termissafe = 1;
  1048. }
  1049. else add_cases(q->t_follow, tokenlist, casecnt++);
  1050. if (!onerror && (q->t_flags & PERSISTENT) && safeterm != SAFE) {
  1051. add_cases(q->t_contains, tokenlist, casecnt);
  1052. }
  1053. else add_cases(q->t_first, tokenlist, casecnt);
  1054. compacted = analyze_switch(tokenlist);
  1055. fputs("{", f);
  1056. if (compacted) {
  1057. out_list(tokenlist, listcount++, casecnt);
  1058. }
  1059. else fputs("switch(LLcsymb) {\n", f);
  1060. casecnt = 0;
  1061. if (q->t_flags & RESOLVER) {
  1062. if (q->t_flags & NOCONF) {
  1063. fputs("#ifdef ___NOCONFLICT___\n", f);
  1064. }
  1065. else gencases(tokenlist, casecnt++, compacted);
  1066. controlline();
  1067. fputs("if (", f);
  1068. getaction(0);
  1069. fprintf(f, ") goto L_%d;\n", hulp1);
  1070. if (q->t_flags & NOCONF) {
  1071. fputs("#endif /* ___NOCONFLICT___ */\n", f);
  1072. }
  1073. }
  1074. if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) {
  1075. fputs("default:\n", f);
  1076. }
  1077. else gencases(tokenlist, casecnt++, compacted);
  1078. if (rep_kind == OPT) genpop(ispushed);
  1079. fputs(c_break, f);
  1080. if (! termissafe) {
  1081. int i;
  1082. static int nvar;
  1083. assert(ispushed != NOPOP);
  1084. if (ispushed >= 0) i = -ispushed;
  1085. else i = tokens[-(ispushed+1)].t_tokno;
  1086. ++nvar;
  1087. fprintf(f,"default:{int LL_%d=LLnext(%d);\n;if (!LL_%d) {\n",
  1088. nvar, i, nvar);
  1089. if (rep_kind == OPT) genpop(ispushed);
  1090. fputs(c_break, f);
  1091. fputs(c_close, f);
  1092. fprintf(f,"else if (LL_%d & 1) goto L_%d;}\n",nvar, hulp2);
  1093. }
  1094. gencases(tokenlist, casecnt, compacted);
  1095. if (q->t_flags & RESOLVER) {
  1096. fprintf(f, "goto L_%d;\nL_%d : ;\n", hulp1, hulp1);
  1097. }
  1098. if (rep_kind == OPT) genpop(ispushed);
  1099. if (rep_count > 0) {
  1100. assert(ispushed != NOPOP);
  1101. fputs(rep_kind == STAR ? "if (!LL_i) " : "if (LL_i == 1) ", f);
  1102. genpop(ispushed);
  1103. }
  1104. free((p_mem) tokenlist);
  1105. }
  1106. STATIC
  1107. gencases(tokenlist, caseno, compacted)
  1108. int *tokenlist;
  1109. {
  1110. /*
  1111. * setp points to a bitset indicating which cases must
  1112. * be generated.
  1113. * YECH, the PCC compiler does not accept many cases without
  1114. * statements in between, so after every case label an empty
  1115. * statement is generated.
  1116. * The C-grammar used by PCC is really stupid on this point :
  1117. * it contains the rule
  1118. * statement : label statement
  1119. * which is right-recursive, and as is well known, LALR parsers don't
  1120. * handle these things very well.
  1121. * The grammar should have been written :
  1122. * labeledstatement : labels statement ;
  1123. * labels : labels label | ;
  1124. */
  1125. register p_token p;
  1126. register int i;
  1127. if (compacted) fprintf(fpars, "case %d :\n", caseno);
  1128. for (i = 0, p = tokens; i < ntokens; i++, p++) {
  1129. if (tokenlist[i] == caseno) {
  1130. fprintf(fpars,
  1131. compacted ?
  1132. (p->t_tokno < 0400 ? "/* case '%s' */\n" :
  1133. "/* case %s */\n") :
  1134. p->t_tokno<0400 ? "case /* '%s' */ %d : ;\n"
  1135. : "case /* %s */ %d : ;\n",
  1136. p->t_string, i);
  1137. }
  1138. }
  1139. }
  1140. static char namebuf[20];
  1141. STATIC string
  1142. genname(s) string s; {
  1143. /*
  1144. * Generate a target file name from the
  1145. * source file name s.
  1146. */
  1147. register string c,d;
  1148. c = namebuf;
  1149. while (*s) {
  1150. if (*s == '/') {
  1151. while (*s == '/') s++;
  1152. if (*s) c = namebuf;
  1153. else break;
  1154. }
  1155. *c++ = *s++;
  1156. }
  1157. for (d = c; --d > namebuf;) if (*d == '.') break;
  1158. if (d == namebuf) d = c;
  1159. if (d >= &namebuf[12]) {
  1160. fatal(0,"%s : filename too long",namebuf);
  1161. }
  1162. *d++ = '.';
  1163. *d++ = 'c';
  1164. *d = '\0';
  1165. return namebuf;
  1166. }
  1167. STATIC
  1168. genpush(d) {
  1169. genincrdecr("incr", d);
  1170. }
  1171. STATIC
  1172. genincrdecr(s, d) string s; {
  1173. if (d == NOPOP) return;
  1174. if (d >= 0) {
  1175. fprintf(fpars, "LLs%s(%d);\n", s, d / nbytes);
  1176. return;
  1177. }
  1178. fprintf(fpars, "LLt%s(%d);\n", s, -(d + 1));
  1179. }
  1180. STATIC
  1181. genpop(d) {
  1182. genincrdecr("decr", d);
  1183. }
  1184. STATIC int
  1185. analyze_switch(tokenlist)
  1186. int *tokenlist;
  1187. {
  1188. register int i;
  1189. int ncases = 0;
  1190. int percentage;
  1191. int maxcase = 0, mincase = 0;
  1192. if (! jmptable_option) return 0;
  1193. for (i = 0; i < ntokens; i++) {
  1194. if (tokenlist[i] >= 0) {
  1195. ncases++;
  1196. if (! mincase) mincase = i + 1;
  1197. maxcase = i + 1;
  1198. }
  1199. }
  1200. if (ncases < min_cases_for_jmptable) return 0;
  1201. percentage = ncases * 100 / (maxcase - mincase);
  1202. fprintf(fpars, "/* percentage is %d */\n", percentage);
  1203. return percentage >= low_percentage && percentage <= high_percentage;
  1204. }
  1205. STATIC
  1206. add_cases(s, tokenlist, caseno)
  1207. p_set s;
  1208. int *tokenlist;
  1209. {
  1210. register int i;
  1211. for (i = 0; i < ntokens; i++) {
  1212. if (IN(s, i)) {
  1213. tokenlist[i] = caseno;
  1214. }
  1215. }
  1216. }
  1217. STATIC
  1218. out_list(tokenlist, listno, casecnt)
  1219. int *tokenlist;
  1220. {
  1221. register int i;
  1222. register FILE *f = fpars;
  1223. fprintf(f, "static %s LL%d_tklist[] = {",
  1224. casecnt <= 127 ? "char" : "short",
  1225. listno);
  1226. for (i = 0; i < ntokens; i++) {
  1227. fprintf(f, "%c%d,", i % 10 == 0 ? '\n': ' ', tokenlist[i]);
  1228. }
  1229. fputs(c_arrend, f);
  1230. fprintf(f, "switch(LL%d_tklist[LLcsymb]) {\n", listno);
  1231. }
  1232. STATIC
  1233. genextname(d, s, f)
  1234. char *s;
  1235. FILE *f;
  1236. {
  1237. fprintf(f, "%s%d_%s", prefix ? prefix : "LL", d, s);
  1238. }
  1239. STATIC
  1240. correct_prefix()
  1241. {
  1242. register FILE *f = fpars;
  1243. register char *s = prefix;
  1244. if (s) {
  1245. fprintf(f, "#define LLsymb %ssymb\n", s);
  1246. fprintf(f, "#define LLerror %serror\n", s);
  1247. fprintf(f, "#define LLsafeerror %ssafeerror\n", s);
  1248. fprintf(f, "#ifndef LL_FASTER\n#define LLscan %sscan\n#endif\n", s);
  1249. fprintf(f, "#define LLscnt %sscnt\n", s);
  1250. fprintf(f, "#define LLtcnt %stcnt\n", s);
  1251. fprintf(f, "#define LLcsymb %scsymb\n", s);
  1252. fprintf(f, "#define LLread %sread\n", s);
  1253. fprintf(f, "#define LLskip %sskip\n", s);
  1254. fprintf(f, "#define LLnext %snext\n", s);
  1255. fprintf(f, "#define LLfirst %sfirst\n", s);
  1256. fprintf(f, "#define LLnewlevel %snewlevel\n", s);
  1257. fprintf(f, "#define LLoldlevel %soldlevel\n", s);
  1258. fprintf(f, "#define LLmessage %smessage\n", s);
  1259. #ifdef NON_CORRECTING
  1260. fprintf(f, "#define LLnc_recovery %sncrecovery\n", s);
  1261. fprintf(f, "#define LLstartsymb %sstartsymb\n", s);
  1262. #endif
  1263. }
  1264. fprintf(f, "#include \"%s\"\n", f_include);
  1265. }