comm5.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* @(#)comm5.c 1.1 */
  7. #include "comm0.h"
  8. #include "comm1.h"
  9. #include "y.tab.h"
  10. /* Since isascii is not standard, as c89 or C99, privide another method */
  11. #define IsAscii(_c) (((_c) & ~0x7f) == 0)
  12. extern YYSTYPE yylval;
  13. int yylex()
  14. {
  15. int c;
  16. if (pass == PASS_1) {
  17. /* scan the input file */
  18. do
  19. c = nextchar();
  20. while (isspace(c) && c != '\n');
  21. if (ISALPHA(c))
  22. c = inident(c);
  23. else if (isdigit(c))
  24. c = innumber(c);
  25. else switch (c) {
  26. case '=':
  27. case '<':
  28. case '>':
  29. case '|':
  30. case '&':
  31. c = induo(c); break;
  32. case ASC_SQUO:
  33. case ASC_DQUO:
  34. c = instring(c); break;
  35. case ASC_COMM:
  36. do
  37. c = nextchar();
  38. while (c != '\n' && c != '\0');
  39. break;
  40. case CTRL('A'):
  41. c = CODE1; readcode(1); break;
  42. case CTRL('B'):
  43. c = CODE2; readcode(2); break;
  44. case CTRL('C'):
  45. c = CODE4; readcode(4); break;
  46. }
  47. /* produce the intermediate token file */
  48. if (c <= 0)
  49. return(0);
  50. if (c <= 127)
  51. putc(c, tempfile);
  52. else
  53. putval(c);
  54. } else {
  55. /* read from intermediate token file */
  56. c = getc(tempfile);
  57. if (c == EOF)
  58. return(0);
  59. if (c > 127) {
  60. c += 128;
  61. c = getval(c);
  62. }
  63. }
  64. curr_token = c;
  65. return(c);
  66. }
  67. void putval(int c)
  68. {
  69. valu_t v;
  70. int n = 0;
  71. char *p = 0;
  72. assert(c >= 256 && c < 256+128);
  73. switch (c) {
  74. case CODE1:
  75. n = 1; goto putnum;
  76. case CODE2:
  77. n = 2; goto putnum;
  78. case CODE4:
  79. n = 4; goto putnum;
  80. case NUMBER:
  81. v = yylval.y_valu;
  82. for (n = 0; n < sizeof(v); n++) {
  83. if (v == 0)
  84. break;
  85. v >>= 8;
  86. }
  87. c = NUMBER0 + n;
  88. putnum:
  89. putc(c-128, tempfile);
  90. v = yylval.y_valu;
  91. while (--n >= 0)
  92. putc((int) (v >> (n*8)), tempfile);
  93. return;
  94. case IDENT:
  95. case FBSYM:
  96. n = sizeof(item_t *);
  97. p = (char *) &yylval.y_item; break;
  98. #ifdef ASLD
  99. case MODULE:
  100. n = sizeof(char *);
  101. p = (char *) &yylval.y_strp; break;
  102. #endif
  103. case STRING:
  104. v = stringlen;
  105. putc(c-128, tempfile);
  106. for (n = 0; n < sizeof(v); n++) {
  107. if (v == 0)
  108. break;
  109. v >>= 8;
  110. }
  111. c = NUMBER0 + n;
  112. putc(c-128, tempfile);
  113. v = stringlen;
  114. while (--n >= 0)
  115. putc((int) (v >> (n*8)), tempfile);
  116. p = stringbuf;
  117. n = stringlen;
  118. while (--n >= 0)
  119. putc(*p++, tempfile);
  120. return;
  121. case OP_EQ:
  122. case OP_NE:
  123. case OP_LE:
  124. case OP_GE:
  125. case OP_LL:
  126. case OP_RR:
  127. case OP_OO:
  128. case OP_AA:
  129. break;
  130. default:
  131. n = sizeof(word_t);
  132. p = (char *) &yylval.y_word; break;
  133. }
  134. putc(c-128, tempfile);
  135. while (--n >= 0)
  136. putc(*p++, tempfile);
  137. }
  138. int getval(int c)
  139. {
  140. int n = 0;
  141. valu_t v;
  142. char *p = 0;
  143. switch (c) {
  144. case CODE1:
  145. n = 1; goto getnum;
  146. case CODE2:
  147. n = 2; goto getnum;
  148. case CODE4:
  149. n = 4; goto getnum;
  150. case NUMBER0:
  151. c = NUMBER; goto getnum;
  152. case NUMBER1:
  153. n = 1; c = NUMBER; goto getnum;
  154. case NUMBER2:
  155. n = 2; c = NUMBER; goto getnum;
  156. case NUMBER3:
  157. n = 3; c = NUMBER; goto getnum;
  158. case NUMBER:
  159. n = 4;
  160. getnum:
  161. v = 0;
  162. while (--n >= 0) {
  163. v <<= 8;
  164. v |= getc(tempfile);
  165. }
  166. yylval.y_valu = v;
  167. return(c);
  168. case IDENT:
  169. case FBSYM:
  170. n = sizeof(item_t *);
  171. p = (char *) &yylval.y_item; break;
  172. #ifdef ASLD
  173. case MODULE:
  174. n = sizeof(char *);
  175. p = (char *) &yylval.y_strp; break;
  176. #endif
  177. case STRING:
  178. getval(getc(tempfile)+128);
  179. stringlen = n = yylval.y_valu;
  180. p = stringbuf;
  181. p[n] = '\0'; break;
  182. case OP_EQ:
  183. case OP_NE:
  184. case OP_LE:
  185. case OP_GE:
  186. case OP_LL:
  187. case OP_RR:
  188. case OP_OO:
  189. case OP_AA:
  190. break;
  191. default:
  192. n = sizeof(word_t);
  193. p = (char *) &yylval.y_word; break;
  194. }
  195. while (--n >= 0)
  196. *p++ = getc(tempfile);
  197. return(c);
  198. }
  199. /* ---------- lexical scan in pass 1 ---------- */
  200. int nextchar()
  201. {
  202. int c;
  203. if (peekc != -1) {
  204. c = peekc;
  205. peekc = -1;
  206. return(c);
  207. }
  208. #ifdef ASLD
  209. if (archmode && --archsize < 0)
  210. return(0);
  211. #endif
  212. if ((c = getc(input)) == EOF)
  213. return(0);
  214. if (IsAscii(c) == 0)
  215. fatal("non-ascii character");
  216. #ifdef LISTING
  217. if (listflag & 0440)
  218. putc(c, listfile);
  219. #endif
  220. return(c);
  221. }
  222. void readcode(int n)
  223. {
  224. int c;
  225. yylval.y_valu = 0;
  226. do {
  227. if (
  228. #ifdef ASLD
  229. (archmode && --archsize < 0)
  230. ||
  231. #endif
  232. (c = getc(input)) == EOF
  233. )
  234. fatal("unexpected EOF in compact input");
  235. yylval.y_valu <<= 8;
  236. yylval.y_valu |= c;
  237. } while (--n);
  238. }
  239. int induo(int c)
  240. {
  241. static short duo[] = {
  242. ('='<<8) | '=', OP_EQ,
  243. ('<'<<8) | '>', OP_NE,
  244. ('<'<<8) | '=', OP_LE,
  245. ('>'<<8) | '=', OP_GE,
  246. ('<'<<8) | '<', OP_LL,
  247. ('>'<<8) | '>', OP_RR,
  248. ('|'<<8) | '|', OP_OO,
  249. ('&'<<8) | '&', OP_AA,
  250. };
  251. short *p;
  252. c = (c<<8) | nextchar();
  253. for (p = duo; *p; p++)
  254. if (*p++ == c)
  255. return(*p++);
  256. peekc = c & 0377;
  257. return(c>>8);
  258. }
  259. static char name[NAMEMAX+1];
  260. int inident(int c)
  261. {
  262. char *p = name;
  263. item_t *ip;
  264. int n = NAMEMAX;
  265. do {
  266. if (--n >= 0)
  267. *p++ = c;
  268. c = nextchar();
  269. } while (ISALNUM(c));
  270. *p = '\0';
  271. peekc = c;
  272. ip = item_search(name);
  273. if (ip == 0) {
  274. ip = item_alloc(S_UND);
  275. ip->i_name = remember(name);
  276. /* printf("ident %s %o\n", ip->i_name, ip); */
  277. unresolved++;
  278. item_insert(ip, H_LOCAL + (hashindex%H_SIZE));
  279. } else if (hashindex < H_SIZE) {
  280. assert(H_KEY == 0);
  281. yylval.y_word = (word_t) ip->i_valu;
  282. return(ip->i_type);
  283. }
  284. yylval.y_item = ip;
  285. return(IDENT);
  286. }
  287. #ifdef ASLD
  288. char *readident(int c)
  289. {
  290. int n = NAMEMAX;
  291. char *p = name;
  292. do {
  293. if (--n >= 0)
  294. *p++ = c;
  295. c = nextchar();
  296. } while (ISALNUM(c));
  297. *p++ = '\0';
  298. peekc = c;
  299. return(name);
  300. }
  301. #endif
  302. int innumber(int c)
  303. {
  304. char *p;
  305. int radix;
  306. static char num[20+1];
  307. p = num;
  308. radix = 20;
  309. do {
  310. if (--radix < 0)
  311. fatal("number too long");
  312. if (isupper(c))
  313. c += ('a' - 'A');
  314. *p++ = c;
  315. c = nextchar();
  316. } while (isalnum(c));
  317. peekc = c;
  318. *p = '\0';
  319. c = *--p;
  320. p = num;
  321. radix = 10;
  322. if (*p == '0') {
  323. radix = 8;
  324. p++;
  325. if (*p == 'x') {
  326. radix = 16;
  327. p++;
  328. } else if (*p == 'b') {
  329. radix = 2;
  330. p++;
  331. }
  332. }
  333. if (radix != 16 && (c == 'f' || c == 'b'))
  334. return(infbsym(num));
  335. yylval.y_valu = 0;
  336. while ( (c = *p++) ) {
  337. if (c > '9')
  338. c -= ('a' - '9' - 1);
  339. c -= '0';
  340. if ((unsigned)c >= radix)
  341. serror("digit exceeds radix");
  342. yylval.y_valu = yylval.y_valu * radix + c;
  343. }
  344. return(NUMBER);
  345. }
  346. int instring(int termc)
  347. {
  348. char *p;
  349. int c;
  350. static int maxstring = 0;
  351. if (! maxstring) {
  352. maxstring = STRINGMAX;
  353. if ((stringbuf = malloc(maxstring)) == 0) {
  354. fatal("out of memory");
  355. }
  356. }
  357. p = stringbuf;
  358. for (;;) {
  359. c = nextchar();
  360. if (c == '\n' || c == '\0') {
  361. peekc = c;
  362. serror("non-terminated string");
  363. break;
  364. }
  365. if (c == termc)
  366. break;
  367. if (c == '\\')
  368. c = inescape();
  369. if (p >= &stringbuf[maxstring - 1]) {
  370. int cnt = p - stringbuf;
  371. if ((stringbuf = realloc(stringbuf, maxstring += 256)) == 0) {
  372. fatal("out of memory");
  373. }
  374. p = stringbuf + cnt;
  375. }
  376. *p++ = c;
  377. }
  378. stringlen = p - stringbuf;
  379. *p = '\0';
  380. return(STRING);
  381. }
  382. int inescape()
  383. {
  384. int c, j, r;
  385. c = nextchar();
  386. if (c >= '0' && c <= '7') {
  387. r = c - '0';
  388. for (j = 0; j < 2; j++) {
  389. c = nextchar();
  390. if (c < '0' || c > '7') {
  391. peekc = c;
  392. return(r);
  393. }
  394. r <<= 3;
  395. r += (c - '0');
  396. }
  397. return(r);
  398. }
  399. switch (c) {
  400. case 'b': return('\b');
  401. case 'f': return('\f');
  402. case 'n': return('\n');
  403. case 'r': return('\r');
  404. case 't': return('\t');
  405. case '\'': return('\'');
  406. case '"': return('"');
  407. }
  408. return(c);
  409. }
  410. int infbsym(char *p)
  411. {
  412. int lab;
  413. item_t *ip;
  414. lab = *p++ - '0';
  415. if ((unsigned)lab < 10) {
  416. if (*p++ == 'f') {
  417. ip = fb_ptr[FB_FORW+lab];
  418. if (ip == 0) {
  419. ip = fb_alloc(lab);
  420. fb_ptr[FB_FORW+lab] = ip;
  421. }
  422. goto ok;
  423. }
  424. ip = fb_ptr[FB_BACK+lab];
  425. if (ip != 0 && *p == 0)
  426. goto ok;
  427. }
  428. serror("bad numeric label");
  429. ip = fb_alloc(0);
  430. ok:
  431. yylval.y_item = ip;
  432. return(FBSYM);
  433. }
  434. int hash(char *p)
  435. {
  436. unsigned short h;
  437. int c;
  438. h = 0;
  439. while ( (c = *p++) ) {
  440. h <<= 2;
  441. h += c;
  442. }
  443. return(h % H_SIZE);
  444. }
  445. item_t *item_search(char *p)
  446. {
  447. int h;
  448. item_t *ip;
  449. for (h = hash(p); h < H_TOTAL; h += H_SIZE) {
  450. ip = hashtab[h];
  451. while (ip != 0) {
  452. if (strcmp(p, ip->i_name) == 0)
  453. goto done;
  454. ip = ip->i_next;
  455. }
  456. }
  457. done:
  458. hashindex = h;
  459. return(ip);
  460. }
  461. void item_insert(item_t *ip, int h)
  462. {
  463. ip->i_next = hashtab[h];
  464. hashtab[h] = ip;
  465. }
  466. item_t *item_alloc(int typ)
  467. {
  468. item_t *ip;
  469. static nleft = 0;
  470. static item_t *next;
  471. if (--nleft < 0) {
  472. next = (item_t *) malloc(MEMINCR);
  473. if (next == 0)
  474. fatal("out of memory");
  475. nleft += (MEMINCR / sizeof(item_t));
  476. }
  477. ip = next++;
  478. ip->i_next = 0;
  479. ip->i_type = typ;
  480. ip->i_name = 0;
  481. ip->i_valu = 0;
  482. return(ip);
  483. }
  484. item_t *fb_alloc(int lab)
  485. {
  486. item_t *ip, *p;
  487. ip = item_alloc(S_UND);
  488. p = fb_ptr[FB_TAIL+lab];
  489. if (p == 0)
  490. fb_ptr[FB_HEAD+lab] = ip;
  491. else
  492. p->i_next = ip;
  493. fb_ptr[FB_TAIL+lab] = ip;
  494. return(ip);
  495. }
  496. item_t *fb_shift(int lab)
  497. {
  498. item_t *ip;
  499. ip = fb_ptr[FB_FORW+lab];
  500. if (ip == 0)
  501. {
  502. if (pass == PASS_1)
  503. {
  504. ip = fb_alloc(lab);
  505. }
  506. else
  507. {
  508. ip = fb_ptr[FB_HEAD+lab];
  509. }
  510. }
  511. fb_ptr[FB_BACK+lab] = ip;
  512. fb_ptr[FB_FORW+lab] = ip->i_next;
  513. return(ip);
  514. }