sub1.c 9.9 KB

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