sub1.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. # include "ldefs.h"
  10. uint8_t *
  11. getl(uint8_t *p) /* return next line of input, throw away trailing '\n' */
  12. /* returns 0 if eof is had immediately */
  13. {
  14. int c;
  15. uint8_t *s, *t;
  16. t = s = p;
  17. while(((c = gch()) != 0) && c != '\n')
  18. *t++ = c;
  19. *t = 0;
  20. if(c == 0 && s == t) return((uint8_t *)0);
  21. prev = '\n';
  22. pres = '\n';
  23. return(s);
  24. }
  25. void
  26. printerr(char *type, char *fmt, va_list argl)
  27. {
  28. char buf[1024];
  29. if(!eof)fprint(errorf,"%s:%d ", yyfile, yyline);
  30. fprint(errorf,"(%s) ", type);
  31. vseprint(buf, buf+sizeof(buf), fmt, argl);
  32. fprint(errorf, "%s\n", buf);
  33. }
  34. void
  35. error(char *s,...)
  36. {
  37. va_list argl;
  38. va_start(argl, s);
  39. printerr("Error", s, argl);
  40. va_end(argl);
  41. # ifdef DEBUG
  42. if(debug && sect != ENDSECTION) {
  43. sect1dump();
  44. sect2dump();
  45. }
  46. # endif
  47. if(
  48. # ifdef DEBUG
  49. debug ||
  50. # endif
  51. report == 1) statistics();
  52. exits("error"); /* error return code */
  53. }
  54. void
  55. warning(char *s,...)
  56. {
  57. va_list argl;
  58. va_start(argl, s);
  59. printerr("Warning", s, argl);
  60. va_end(argl);
  61. Bflush(&fout);
  62. }
  63. void
  64. lgate(void)
  65. {
  66. int fd;
  67. if (lgatflg) return;
  68. lgatflg=1;
  69. if(foutopen == 0){
  70. fd = create("lex.yy.c", OWRITE, 0666);
  71. if(fd < 0)
  72. error("Can't open lex.yy.c: %r");
  73. Binit(&fout, fd, OWRITE);
  74. foutopen = 1;
  75. }
  76. phead1();
  77. }
  78. void
  79. cclinter(int sw)
  80. {
  81. /* sw = 1 ==> ccl */
  82. int i, j, k;
  83. int m;
  84. if(!sw){ /* is NCCL */
  85. for(i=1;i<NCH;i++)
  86. symbol[i] ^= 1; /* reverse value */
  87. }
  88. for(i=1;i<NCH;i++)
  89. if(symbol[i]) break;
  90. if(i >= NCH) return;
  91. i = cindex[i];
  92. /* see if ccl is already in our table */
  93. j = 0;
  94. if(i){
  95. for(j=1;j<NCH;j++){
  96. if((symbol[j] && cindex[j] != i) ||
  97. (!symbol[j] && cindex[j] == i)) break;
  98. }
  99. }
  100. if(j >= NCH) return; /* already in */
  101. m = 0;
  102. k = 0;
  103. for(i=1;i<NCH;i++)
  104. if(symbol[i]){
  105. if(!cindex[i]){
  106. cindex[i] = ccount;
  107. symbol[i] = 0;
  108. m = 1;
  109. } else k = 1;
  110. }
  111. /* m == 1 implies last value of ccount has been used */
  112. if(m)ccount++;
  113. if(k == 0) return; /* is now in as ccount wholly */
  114. /* intersection must be computed */
  115. for(i=1;i<NCH;i++){
  116. if(symbol[i]){
  117. m = 0;
  118. j = cindex[i]; /* will be non-zero */
  119. for(k=1;k<NCH;k++){
  120. if(cindex[k] == j){
  121. if(symbol[k]) symbol[k] = 0;
  122. else {
  123. cindex[k] = ccount;
  124. m = 1;
  125. }
  126. }
  127. }
  128. if(m)ccount++;
  129. }
  130. }
  131. }
  132. int
  133. usescape(int c)
  134. {
  135. int d;
  136. switch(c){
  137. case 'n': c = '\n'; break;
  138. case 'r': c = '\r'; break;
  139. case 't': c = '\t'; break;
  140. case 'b': c = '\b'; break;
  141. case 'f': c = 014; break; /* form feed for ascii */
  142. case '0': case '1': case '2': case '3':
  143. case '4': case '5': case '6': case '7':
  144. c -= '0';
  145. while('0' <= (d=gch()) && d <= '7'){
  146. c = c * 8 + (d-'0');
  147. if(!('0' <= peek && peek <= '7')) break;
  148. }
  149. break;
  150. }
  151. return(c);
  152. }
  153. int
  154. lookup(uint8_t *s, uint8_t **t)
  155. {
  156. int i;
  157. i = 0;
  158. while(*t){
  159. if(strcmp((char *)s, *(char **)t) == 0)
  160. return(i);
  161. i++;
  162. t++;
  163. }
  164. return(-1);
  165. }
  166. int
  167. cpyact(void)
  168. { /* copy C action to the next ; or closing } */
  169. int brac, c, mth;
  170. int savline, sw;
  171. char *savfile;
  172. brac = 0;
  173. sw = TRUE;
  174. savline = 0;
  175. savfile = "?";
  176. while(!eof){
  177. c = gch();
  178. swt:
  179. switch( c ){
  180. case '|': if(brac == 0 && sw == TRUE){
  181. if(peek == '|')gch(); /* eat up an extra '|' */
  182. return(0);
  183. }
  184. break;
  185. case ';':
  186. if( brac == 0 ){
  187. Bputc(&fout, c);
  188. Bputc(&fout, '\n');
  189. return(1);
  190. }
  191. break;
  192. case '{':
  193. brac++;
  194. savline=yyline;
  195. savfile=yyfile;
  196. break;
  197. case '}':
  198. brac--;
  199. if( brac == 0 ){
  200. Bputc(&fout, c);
  201. Bputc(&fout, '\n');
  202. return(1);
  203. }
  204. break;
  205. case '/': /* look for comments */
  206. Bputc(&fout, c);
  207. c = gch();
  208. if( c != '*' ) goto swt;
  209. /* it really is a comment */
  210. Bputc(&fout, c);
  211. savline=yyline;
  212. savfile=yyfile;
  213. while( c=gch() ){
  214. if( c=='*' ){
  215. Bputc(&fout, c);
  216. if( (c=gch()) == '/' ) goto loop;
  217. }
  218. Bputc(&fout, c);
  219. }
  220. yyline=savline;
  221. yyfile=savfile;
  222. error( "EOF inside comment" );
  223. case '\'': /* character constant */
  224. mth = '\'';
  225. goto string;
  226. case '"': /* character string */
  227. mth = '"';
  228. string:
  229. Bputc(&fout, c);
  230. while( c=gch() ){
  231. if( c=='\\' ){
  232. Bputc(&fout, c);
  233. c=gch();
  234. }
  235. else if( c==mth ) goto loop;
  236. Bputc(&fout, c);
  237. if (c == '\n') {
  238. yyline--;
  239. error( "Non-terminated string or character constant");
  240. }
  241. }
  242. error( "EOF in string or character constant" );
  243. case '\0':
  244. yyline = savline;
  245. yyfile = savfile;
  246. error("Action does not terminate");
  247. default:
  248. break; /* usual character */
  249. }
  250. loop:
  251. if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
  252. Bputc(&fout, c);
  253. }
  254. error("Premature EOF");
  255. return(0);
  256. }
  257. int
  258. gch(void){
  259. int c;
  260. prev = pres;
  261. c = pres = peek;
  262. peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
  263. if(peek == Beof && sargc > 1){
  264. Bterm(fin);
  265. yyfile = sargv[fptr++];
  266. fin = Bopen(yyfile,OREAD);
  267. if(fin == 0)
  268. error("%s - cannot open file: %r",yyfile);
  269. peek = Bgetc(fin);
  270. sargc--;
  271. sargv++;
  272. }
  273. if(c == Beof) {
  274. eof = TRUE;
  275. Bterm(fin);
  276. fin = 0;
  277. return(0);
  278. }
  279. if(c == '\n')yyline++;
  280. return(c);
  281. }
  282. int
  283. mn2(int a, int d, uintptr c)
  284. {
  285. name[tptr] = a;
  286. left[tptr] = d;
  287. right[tptr] = c;
  288. parent[tptr] = 0;
  289. nullstr[tptr] = 0;
  290. switch(a){
  291. case RSTR:
  292. parent[d] = tptr;
  293. break;
  294. case BAR:
  295. case RNEWE:
  296. if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
  297. parent[d] = parent[c] = tptr;
  298. break;
  299. case RCAT:
  300. case DIV:
  301. if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
  302. parent[d] = parent[c] = tptr;
  303. break;
  304. case RSCON:
  305. parent[d] = tptr;
  306. nullstr[tptr] = nullstr[d];
  307. break;
  308. # ifdef DEBUG
  309. default:
  310. warning("bad switch mn2 %d %d",a,d);
  311. break;
  312. # endif
  313. }
  314. if(tptr > treesize)
  315. error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
  316. return(tptr++);
  317. }
  318. int
  319. mnp(int a, void *p)
  320. {
  321. name[tptr] = a;
  322. left[tptr] = 0;
  323. parent[tptr] = 0;
  324. nullstr[tptr] = 0;
  325. ptr[tptr] = p;
  326. switch(a){
  327. case RCCL:
  328. case RNCCL:
  329. if(strlen(p) == 0) nullstr[tptr] = TRUE;
  330. break;
  331. default:
  332. error("bad switch mnp %d %P", a, p);
  333. break;
  334. }
  335. if(tptr > treesize)
  336. error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
  337. return(tptr++);
  338. }
  339. int
  340. mn1(int a, int d)
  341. {
  342. name[tptr] = a;
  343. left[tptr] = d;
  344. parent[tptr] = 0;
  345. nullstr[tptr] = 0;
  346. switch(a){
  347. case STAR:
  348. case QUEST:
  349. nullstr[tptr] = TRUE;
  350. parent[d] = tptr;
  351. break;
  352. case PLUS:
  353. case CARAT:
  354. nullstr[tptr] = nullstr[d];
  355. parent[d] = tptr;
  356. break;
  357. case S2FINAL:
  358. nullstr[tptr] = TRUE;
  359. break;
  360. # ifdef DEBUG
  361. case FINAL:
  362. case S1FINAL:
  363. break;
  364. default:
  365. warning("bad switch mn1 %d %d",a,d);
  366. break;
  367. # endif
  368. }
  369. if(tptr > treesize)
  370. error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
  371. return(tptr++);
  372. }
  373. int
  374. mn0(int a)
  375. {
  376. name[tptr] = a;
  377. parent[tptr] = 0;
  378. nullstr[tptr] = 0;
  379. if(a >= NCH) switch(a){
  380. case RNULLS: nullstr[tptr] = TRUE; break;
  381. # ifdef DEBUG
  382. default:
  383. warning("bad switch mn0 %d",a);
  384. break;
  385. # endif
  386. }
  387. if(tptr > treesize)
  388. error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
  389. return(tptr++);
  390. }
  391. void
  392. munputc(int p)
  393. {
  394. *pushptr++ = peek; /* watch out for this */
  395. peek = p;
  396. if(pushptr >= pushc+TOKENSIZE)
  397. error("Too many characters pushed");
  398. }
  399. void
  400. munputs(uint8_t *p)
  401. {
  402. int i,j;
  403. *pushptr++ = peek;
  404. peek = p[0];
  405. i = strlen((char*)p);
  406. for(j = i-1; j>=1; j--)
  407. *pushptr++ = p[j];
  408. if(pushptr >= pushc+TOKENSIZE)
  409. error("Too many characters pushed");
  410. }
  411. int
  412. dupl(int n)
  413. {
  414. /* duplicate the subtree whose root is n, return ptr to it */
  415. int i;
  416. i = name[n];
  417. if(i < NCH) return(mn0(i));
  418. switch(i){
  419. case RNULLS:
  420. return(mn0(i));
  421. case RCCL: case RNCCL:
  422. return(mnp(i,ptr[n]));
  423. case FINAL: case S1FINAL: case S2FINAL:
  424. return(mn1(i,left[n]));
  425. case STAR: case QUEST: case PLUS: case CARAT:
  426. return(mn1(i,dupl(left[n])));
  427. case RSTR: case RSCON:
  428. return(mn2(i,dupl(left[n]),right[n]));
  429. case BAR: case RNEWE: case RCAT: case DIV:
  430. return(mn2(i,dupl(left[n]),dupl(right[n])));
  431. # ifdef DEBUG
  432. default:
  433. warning("bad switch dupl %d",n);
  434. # endif
  435. }
  436. return(0);
  437. }
  438. # ifdef DEBUG
  439. void
  440. allprint(int c)
  441. {
  442. if(c < 0)
  443. c += 256; /* signed char */
  444. switch(c){
  445. case 014:
  446. print("\\f");
  447. charc++;
  448. break;
  449. case '\n':
  450. print("\\n");
  451. charc++;
  452. break;
  453. case '\t':
  454. print("\\t");
  455. charc++;
  456. break;
  457. case '\b':
  458. print("\\b");
  459. charc++;
  460. break;
  461. case ' ':
  462. print("\\\bb");
  463. break;
  464. default:
  465. if(!isprint(c)){
  466. print("\\%-3o",c);
  467. charc += 3;
  468. } else
  469. print("%c", c);
  470. break;
  471. }
  472. charc++;
  473. }
  474. void
  475. strpt(uint8_t *s)
  476. {
  477. charc = 0;
  478. while(*s){
  479. allprint(*s++);
  480. if(charc > LINESIZE){
  481. charc = 0;
  482. print("\n\t");
  483. }
  484. }
  485. }
  486. void
  487. sect1dump(void)
  488. {
  489. int i;
  490. print("Sect 1:\n");
  491. if(def[0]){
  492. print("str trans\n");
  493. i = -1;
  494. while(def[++i])
  495. print("%s\t%s\n",def[i],subs[i]);
  496. }
  497. if(sname[0]){
  498. print("start names\n");
  499. i = -1;
  500. while(sname[++i])
  501. print("%s\n",sname[i]);
  502. }
  503. }
  504. void
  505. sect2dump(void)
  506. {
  507. print("Sect 2:\n");
  508. treedump();
  509. }
  510. void
  511. treedump(void)
  512. {
  513. int t;
  514. uint8_t *p;
  515. print("treedump %d nodes:\n",tptr);
  516. for(t=0;t<tptr;t++){
  517. print("%4d ",t);
  518. parent[t] ? print("p=%4d",parent[t]) : print(" ");
  519. print(" ");
  520. if(name[t] < NCH)
  521. allprint(name[t]);
  522. else switch(name[t]){
  523. case RSTR:
  524. print("%d ",left[t]);
  525. allprint(right[t]);
  526. break;
  527. case RCCL:
  528. print("ccl ");
  529. allprint(ptr[t]);
  530. break;
  531. case RNCCL:
  532. print("nccl ");
  533. allprint(ptr[t]);
  534. break;
  535. case DIV:
  536. print("/ %d %d",left[t],right[t]);
  537. break;
  538. case BAR:
  539. print("| %d %d",left[t],right[t]);
  540. break;
  541. case RCAT:
  542. print("cat %d %d",left[t],right[t]);
  543. break;
  544. case PLUS:
  545. print("+ %d",left[t]);
  546. break;
  547. case STAR:
  548. print("* %d",left[t]);
  549. break;
  550. case CARAT:
  551. print("^ %d",left[t]);
  552. break;
  553. case QUEST:
  554. print("? %d",left[t]);
  555. break;
  556. case RNULLS:
  557. print("nullstring");
  558. break;
  559. case FINAL:
  560. print("final %d",left[t]);
  561. break;
  562. case S1FINAL:
  563. print("s1final %d",left[t]);
  564. break;
  565. case S2FINAL:
  566. print("s2final %d",left[t]);
  567. break;
  568. case RNEWE:
  569. print("new %d %d",left[t],right[t]);
  570. break;
  571. case RSCON:
  572. p = (uint8_t *)right[t];
  573. print("start %s",sname[*p++-1]);
  574. while(*p)
  575. print(", %s",sname[*p++-1]);
  576. print(" %d",left[t]);
  577. break;
  578. default:
  579. print("unknown %d %d %d",name[t],left[t],right[t]);
  580. break;
  581. }
  582. if(nullstr[t])print("\t(null poss.)");
  583. print("\n");
  584. }
  585. }
  586. # endif