/turing/src/miolexscan.in

https://bitbucket.org/yingted/openturing · Autoconf · 958 lines · 822 code · 133 blank · 3 comment · 164 complexity · 3f7ed039b5984f0797c899ce34d4bbeb MD5 · raw file

  1. /*****************/
  2. /* miolexscan.in */
  3. /*****************/
  4. /***************************************/
  5. /* This file is included by miolexer.c */
  6. /***************************************/
  7. /*******************/
  8. /* System includes */
  9. /*******************/
  10. /*************/
  11. /* Constants */
  12. /*************/
  13. /********************/
  14. /* Static variables */
  15. /********************/
  16. /*********************/
  17. /* Static procedures */
  18. /*********************/
  19. #define IS_MATCH(str1, str2) \
  20. ((str2 [1] == EOS) || strncmp((str1), (str2), strlen(str2)) == 0)
  21. /************************************************************************/
  22. /* MyIsDigitChar */
  23. /************************************************************************/
  24. static BOOL MyIsDigitChar (int pmBase, char pmChar)
  25. {
  26. if (pmBase)
  27. {
  28. UINT myChar = toupper (pmChar);
  29. return (isdigit(pmChar) && ((pmChar - '0') < pmBase)) ||
  30. (('A' <= pmChar) && (myChar < (UINT) ('A' + pmBase - 10)));
  31. }
  32. return isdigit (pmChar);
  33. } // MyIsDigitChar
  34. /************************************************************************/
  35. /* MyHash */
  36. /* */
  37. /* Hash token to hash table slot index */
  38. /************************************************************************/
  39. static UINT MyHash (const char *pmStr)
  40. {
  41. DWORD myIndex = 0;
  42. int myLen = strlen (pmStr);
  43. int cnt;
  44. for (cnt = 0 ; cnt < myLen ; cnt++)
  45. {
  46. myIndex = (myIndex >> 16) | (myIndex << 16) | pmStr [cnt];
  47. }
  48. return (myIndex % NUM_HASH_SLOTS);
  49. } // MyHash
  50. /************************************************************************/
  51. /* MyLookupToken */
  52. /* */
  53. /* Check token against token list. */
  54. /* Return tTokenBase + offset if found, else return 0; */
  55. /************************************************************************/
  56. static int MyLookupToken (LexTable *pmLexTable, const char *pmToken)
  57. {
  58. UINT mySlot = MyHash (pmToken);
  59. for (;;)
  60. {
  61. int myIndex = pmLexTable -> hashTable [mySlot];
  62. if (myIndex == NONE)
  63. {
  64. return 0;
  65. }
  66. if (strcmp (pmToken, pmLexTable -> token [myIndex]) == 0)
  67. {
  68. return tTokenBase + myIndex;
  69. }
  70. mySlot = ((mySlot + 1) % NUM_HASH_SLOTS);
  71. }
  72. } // MyLookupToken
  73. /************************************************************************/
  74. /* MyGetComment */
  75. /* */
  76. /* Copy comment into token record. Return TRUE if more comment remains */
  77. /************************************************************************/
  78. static void MyGetComment (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  79. {
  80. LexTable *myLexTable = pmLexRecord -> table;
  81. char *myToken = pmTokRecord -> token;
  82. UINT myCommentNum = pmLexRecord -> commentNum;
  83. int myEndPos = strlen (myToken);
  84. int myPos = pmLexRecord -> pos + myEndPos;
  85. for (;;)
  86. {
  87. char myChar = pmLexRecord -> line [myPos];
  88. if (myChar == myLexTable -> commentEnd [myCommentNum][0])
  89. {
  90. if (IS_MATCH (pmLexRecord -> line+myPos,
  91. myLexTable -> commentEnd [myCommentNum]))
  92. {
  93. if (myChar != NL)
  94. {
  95. strcpy (myToken + myEndPos,
  96. myLexTable -> commentEnd [myCommentNum]);
  97. }
  98. else
  99. {
  100. myToken [myEndPos] = EOS;
  101. }
  102. pmLexRecord -> pos = myPos +
  103. strlen (myLexTable -> commentEnd [myCommentNum]);
  104. pmLexRecord -> commentNum = NONE;
  105. return;
  106. }
  107. }
  108. if (myChar == NL)
  109. {
  110. pmLexRecord -> pos = myPos;
  111. myToken [myEndPos] = EOS;
  112. return;
  113. }
  114. myToken [myEndPos++] = myChar;
  115. myPos++;
  116. }
  117. } // MyGetComment
  118. /************************************************************************/
  119. /* MyOOTprocess */
  120. /************************************************************************/
  121. static void MyOOTprocess (TOKEN_RECORD *pmTokRecord, const char *pmStr)
  122. {
  123. int mySrc = 0;
  124. int myDest = 0;
  125. while (pmStr [mySrc])
  126. {
  127. switch (pmStr [mySrc])
  128. {
  129. case '\\':
  130. mySrc++;
  131. switch (pmStr [mySrc])
  132. {
  133. case 'b':
  134. case 'B':
  135. pmTokRecord -> stringVal [myDest] = '\b';
  136. break;
  137. case 'd':
  138. case 'D':
  139. pmTokRecord -> stringVal [myDest] = 127;
  140. break;
  141. case 'e':
  142. case 'E':
  143. pmTokRecord -> stringVal [myDest] = 27;
  144. break;
  145. case 'f':
  146. case 'F':
  147. pmTokRecord -> stringVal [myDest] = '\f';
  148. break;
  149. case 'n':
  150. case 'N':
  151. pmTokRecord -> stringVal [myDest] = '\n';
  152. break;
  153. case 'r':
  154. case 'R':
  155. pmTokRecord -> stringVal [myDest] = '\r';
  156. break;
  157. case 't':
  158. case 'T':
  159. pmTokRecord -> stringVal [myDest] = '\t';
  160. break;
  161. case '"':
  162. case '\\':
  163. case '^':
  164. case '\'':
  165. pmTokRecord -> stringVal [myDest] = pmStr [mySrc];
  166. break;
  167. default:
  168. pmTokRecord -> error = TRUE;
  169. return;
  170. } // switch (pmStr [mySrc])
  171. break;
  172. case '^':
  173. mySrc++;
  174. pmTokRecord -> stringVal [myDest] = (pmStr [mySrc] & 0xf);
  175. break;
  176. default:
  177. pmTokRecord -> stringVal [myDest] = pmStr [mySrc];
  178. break;
  179. } // switch (pmStr [mySrc])
  180. mySrc++;
  181. myDest++;
  182. } // while (pmStr [mySrc])
  183. pmTokRecord -> stringVal [myDest] = EOS;
  184. } // MyOOTprocess
  185. /************************************************************************/
  186. /* MyConvertNum */
  187. /************************************************************************/
  188. static char MyConvertNum (const char *pmStr, int *pmPos, int pmBase)
  189. {
  190. int mySrc = *pmPos;
  191. int myDest = 0;
  192. char myNumStr [256];
  193. while (myDest < ((pmBase == 8) ? 3 : 2) && pmStr [mySrc] &&
  194. MyIsDigitChar (pmBase, pmStr [mySrc]))
  195. {
  196. myNumStr [myDest++] = pmStr [mySrc++];
  197. }
  198. *pmPos = mySrc;
  199. myNumStr [myDest] = EOS;
  200. return (char) strtol (myNumStr, NULL, pmBase);
  201. } // MyConvertNum
  202. /************************************************************************/
  203. /* MyCprocess */
  204. /************************************************************************/
  205. static void MyCprocess (TOKEN_RECORD *pmTokRecord, const char *pmStr)
  206. {
  207. int mySrc = 0;
  208. int myDest = 0;
  209. while (pmStr [mySrc])
  210. {
  211. switch (pmStr [mySrc])
  212. {
  213. case '\\':
  214. mySrc++;
  215. switch (pmStr [mySrc])
  216. {
  217. case 'a':
  218. pmTokRecord -> stringVal [myDest] = '\a';
  219. break;
  220. case 'b':
  221. pmTokRecord -> stringVal [myDest] = '\b';
  222. break;
  223. case 'f':
  224. pmTokRecord -> stringVal [myDest] = '\f';
  225. break;
  226. case 'n':
  227. pmTokRecord -> stringVal [myDest] = '\n';
  228. break;
  229. case 'r':
  230. pmTokRecord -> stringVal [myDest] = '\r';
  231. break;
  232. case 't':
  233. pmTokRecord -> stringVal [myDest] = '\t';
  234. break;
  235. case 'v':
  236. pmTokRecord -> stringVal [myDest] = '\v';
  237. break;
  238. case 'x':
  239. {
  240. char myChar;
  241. mySrc++;
  242. myChar = toupper (pmStr [mySrc]);
  243. if (isdigit (pmStr [mySrc]) ||
  244. (('A' <= myChar) && (myChar <= 'F')))
  245. {
  246. pmTokRecord -> stringVal [myDest] =
  247. MyConvertNum (pmStr, &mySrc, 16);
  248. }
  249. else
  250. {
  251. pmTokRecord -> stringVal [myDest] = 'x';
  252. }
  253. }
  254. break;
  255. default:
  256. if (('0' <= pmStr [mySrc]) && (pmStr [mySrc] < '8'))
  257. {
  258. pmTokRecord -> stringVal [myDest] =
  259. MyConvertNum (pmStr, &mySrc, 8);
  260. }
  261. else
  262. {
  263. pmTokRecord -> stringVal [myDest] = pmStr [mySrc];
  264. }
  265. } // switch (pmStr [mySrc])
  266. break;
  267. default:
  268. pmTokRecord -> stringVal [myDest] = pmStr [mySrc];
  269. break;
  270. } // switch (pmStr [mySrc])
  271. mySrc++;
  272. myDest++;
  273. } // while (pmStr [mySrc])
  274. pmTokRecord -> stringVal [myDest] = EOS;
  275. } // MyCprocess
  276. /************************************************************************/
  277. /* MyProcessString */
  278. /************************************************************************/
  279. static void MyProcessString (LexRecord *pmLexRecord,
  280. TOKEN_RECORD *pmTokRecord, char *pmStr)
  281. {
  282. if (pmLexRecord -> flags & FLAG_OOTESCAPE)
  283. {
  284. MyOOTprocess (pmTokRecord, pmStr);
  285. }
  286. else if (pmLexRecord -> flags & FLAG_CESCAPE)
  287. {
  288. MyCprocess (pmTokRecord, pmStr);
  289. }
  290. else
  291. {
  292. strcpy (pmTokRecord -> stringVal, pmStr);
  293. }
  294. } // MyProcessString
  295. /************************************************************************/
  296. /* MyNotEosStartIndex */
  297. /************************************************************************/
  298. static int MyNotEosStartIndex (LexRecord *pmLexRecord, char pmChar)
  299. {
  300. int cnt;
  301. for (cnt = 0 ; cnt < (int) pmLexRecord -> table -> numNotEOS ; cnt++)
  302. {
  303. if (pmChar == pmLexRecord -> table -> notEOS [cnt][0])
  304. {
  305. int myLen = strlen (pmLexRecord -> table -> notEOS [cnt]);
  306. if (strncmp (pmLexRecord -> line + pmLexRecord -> pos,
  307. pmLexRecord -> table -> notEOS [cnt], myLen) == 0)
  308. {
  309. return cnt;
  310. }
  311. }
  312. }
  313. return -1;
  314. }
  315. /************************************************************************/
  316. /* MyGetString */
  317. /* */
  318. /* Copy string into token record. Return TRUE if more string remains */
  319. /************************************************************************/
  320. static BOOL MyGetString (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  321. {
  322. char *myToken = pmTokRecord -> token;
  323. int myPos = 0;
  324. if (myToken [0])
  325. {
  326. myPos++;
  327. pmLexRecord -> pos++;
  328. }
  329. for (;;)
  330. {
  331. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  332. int myIndex;
  333. if (myChar == pmLexRecord -> table -> endStringChar)
  334. {
  335. // Copy string into stringLit here
  336. if (myChar != NL)
  337. {
  338. myToken[myPos++] = myChar;
  339. }
  340. myToken[myPos] = EOS;
  341. pmLexRecord -> pos++;
  342. if (pmLexRecord -> flags & FLAG_EVAL)
  343. {
  344. if (myToken[0] == pmLexRecord -> table -> startStringChar)
  345. {
  346. MyProcessString (pmLexRecord, pmTokRecord, myToken + 1);
  347. }
  348. else
  349. {
  350. MyProcessString (pmLexRecord, pmTokRecord, myToken);
  351. }
  352. if (myChar != NL)
  353. {
  354. int myLen = strlen (pmTokRecord -> stringVal);
  355. pmTokRecord -> stringVal [myLen-1] = EOS;
  356. }
  357. }
  358. return FALSE;
  359. }
  360. // See if we're at a "NOT EOS" string
  361. myIndex = MyNotEosStartIndex (pmLexRecord, myChar);
  362. if (myIndex >= 0)
  363. {
  364. int myLen = strlen (pmLexRecord -> table -> notEOS [myIndex]);
  365. strcpy (myToken + myPos, pmLexRecord -> table -> notEOS [myIndex]);
  366. myPos += myLen;
  367. pmLexRecord -> pos += myLen;
  368. }
  369. else
  370. {
  371. if (myChar == NL)
  372. {
  373. myToken [myPos] = EOS;
  374. if (pmLexRecord -> flags & FLAG_EVAL)
  375. {
  376. if (myToken [0] == pmLexRecord -> table -> startStringChar)
  377. {
  378. MyProcessString (pmLexRecord, pmTokRecord, myToken + 1);
  379. }
  380. else
  381. {
  382. MyProcessString (pmLexRecord, pmTokRecord, myToken);
  383. }
  384. }
  385. return TRUE;
  386. }
  387. pmLexRecord -> pos++;
  388. myToken [myPos++] = myChar;
  389. }
  390. }
  391. } // MyGetString
  392. /************************************************************************/
  393. /* MyGetChar */
  394. /************************************************************************/
  395. static void MyGetChar (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  396. {
  397. char myChrStr[256], *myToken;
  398. int cnt = 0;
  399. pmTokRecord -> token [0] = pmLexRecord -> line [pmLexRecord -> pos++];
  400. myToken = pmTokRecord -> token + 1;
  401. for (;;)
  402. {
  403. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  404. if ((myChar == pmLexRecord -> table->charDelimitter) || (myChar == NL))
  405. {
  406. if (myChar == pmLexRecord -> table->charDelimitter)
  407. {
  408. myToken [cnt] = myChar;
  409. myToken [cnt + 1] = EOS;
  410. pmLexRecord -> pos++;
  411. }
  412. else
  413. {
  414. myToken [cnt] = EOS;
  415. }
  416. myChrStr [cnt] = EOS;
  417. if (pmLexRecord -> flags & FLAG_EVAL)
  418. {
  419. MyProcessString (pmLexRecord, pmTokRecord, myChrStr);
  420. }
  421. return;
  422. }
  423. myToken [cnt] = myChar;
  424. myChrStr [cnt] = myChar;
  425. pmLexRecord -> pos++;
  426. cnt++;
  427. }
  428. } // MyGetChar
  429. /************************************************************************/
  430. /* MyGetIdentifier */
  431. /************************************************************************/
  432. static void MyGetIdentifier (LexRecord *pmLexRecord,
  433. TOKEN_RECORD *pmTokRecord)
  434. {
  435. char *myToken = pmTokRecord -> token;
  436. UINT myPos = 0;
  437. for (;;)
  438. {
  439. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  440. if (isalnum (myChar) ||
  441. strchr (pmLexRecord -> table -> specialIDchars, myChar))
  442. {
  443. myToken [myPos++] = myChar;
  444. pmLexRecord -> pos++;
  445. }
  446. else
  447. {
  448. myToken [myPos] = EOS;
  449. return;
  450. }
  451. }
  452. } // MyGetIdentifier
  453. /************************************************************************/
  454. /* MyGetWhitespace */
  455. /************************************************************************/
  456. static void MyGetWhitespace (LexRecord *pmLexRecord,
  457. TOKEN_RECORD *pmTokRecord)
  458. {
  459. char *myToken = pmTokRecord -> token;
  460. UINT myPos = 0;
  461. for (;;)
  462. {
  463. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  464. if (!isspace(myChar) || (myChar == NL))
  465. {
  466. myToken [myPos] = EOS;
  467. return;
  468. }
  469. myToken [myPos++] = myChar;
  470. pmLexRecord -> pos++;
  471. }
  472. } // MyGetWhitespace
  473. /************************************************************************/
  474. /* MyAnalyzeNum */
  475. /* */
  476. /* Return tIntLit or tRealLit and fill in appropriate token field */
  477. /************************************************************************/
  478. static UINT MyAnalyzeNum (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord,
  479. const char *pmNumStr, BOOL pmIsReal, UINT pmBase)
  480. {
  481. if (pmIsReal)
  482. {
  483. if (pmLexRecord -> flags & FLAG_EVAL)
  484. {
  485. pmTokRecord -> realVal = atof (pmNumStr);
  486. }
  487. return tRealLit;
  488. }
  489. else
  490. {
  491. if (pmLexRecord -> flags & FLAG_EVAL)
  492. {
  493. if (pmBase)
  494. {
  495. pmTokRecord -> intVal = strtol (pmNumStr, NULL, pmBase);
  496. }
  497. else
  498. {
  499. pmTokRecord -> intVal = atol (pmNumStr);
  500. }
  501. }
  502. return tIntLit;
  503. }
  504. } // MyAnalyzeNum
  505. /************************************************************************/
  506. /* MyGetPrefixBase */
  507. /* */
  508. /* See if a prefixed base conversion is being requested */
  509. /************************************************************************/
  510. static UINT MyGetPrefixBase (LexRecord *pmLexRecord,
  511. TOKEN_RECORD *pmTokRecord)
  512. {
  513. UINT cnt;
  514. if (isspace (pmLexRecord -> line [pmLexRecord -> pos + 1]))
  515. {
  516. return 0;
  517. }
  518. for (cnt = 0; cnt < pmLexRecord -> table -> numIntegerPrefix; cnt++)
  519. {
  520. int myLen = strlen (pmLexRecord -> table -> integerPrefix [cnt]);
  521. if (pmLexRecord -> line [pmLexRecord -> pos + myLen] &&
  522. !isspace (pmLexRecord -> line [pmLexRecord -> pos + myLen]) &&
  523. (strncmp (pmLexRecord -> line + pmLexRecord -> pos,
  524. pmLexRecord -> table -> integerPrefix [cnt], myLen) == 0))
  525. {
  526. pmLexRecord -> pos += myLen;
  527. strcpy (pmTokRecord -> token,
  528. pmLexRecord -> table -> integerPrefix [cnt]);
  529. return pmLexRecord -> table -> preBaseConvert[cnt];
  530. }
  531. }
  532. return 0;
  533. } // MyGetPrefixBase
  534. #if 0
  535. static void GetSuffix(lr, tok)
  536. LEX_RECORD *lr;
  537. char *tok;
  538. {
  539. Uint i;
  540. if (pmLexRecord -> line[pmLexRecord -> pos] == EOS || isspace(pmLexRecord -> line[pmLexRecord -> pos]))
  541. return;
  542. for (i=0; i<pmLexRecord -> table->numNumberSuffix; i++) {
  543. Uint len = strlen(pmLexRecord -> table->integerSuffix[i]);
  544. if (pmLexRecord -> line[pmLexRecord -> pos+len] && !isspace(pmLexRecord -> line[pmLexRecord -> pos+len]) &&
  545. strncmp(pmLexRecord -> line+pmLexRecord -> pos, pmLexRecord -> table->integerSuffix[i], len) == 0)
  546. {
  547. pmLexRecord -> pos += len;
  548. strcpy(tok, pmLexRecord -> table->integerSuffix[i]);
  549. return;
  550. }
  551. }
  552. }
  553. #endif
  554. /************************************************************************/
  555. /* MyGetNumber */
  556. /************************************************************************/
  557. static UINT MyGetNumber (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  558. {
  559. char myNumStr [256];
  560. int myBase = MyGetPrefixBase (pmLexRecord, pmTokRecord);
  561. char *myToken = pmTokRecord -> token +
  562. ((myBase) ? strlen (pmTokRecord -> token) : 0);
  563. int myPos = 0;
  564. BOOL mySeenDot = FALSE;
  565. BOOL mySeenExp = FALSE;
  566. BOOL mySeenBaseConv = FALSE;
  567. for (;;)
  568. {
  569. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  570. if (MyIsDigitChar (myBase, myChar))
  571. {
  572. myNumStr [myPos] = myChar;
  573. myToken [myPos++] = myChar;
  574. pmLexRecord -> pos++;
  575. }
  576. else
  577. {
  578. if (myChar == '.')
  579. {
  580. if (mySeenDot || myBase)
  581. {
  582. myNumStr [myPos] = EOS;
  583. myToken [myPos] = EOS;
  584. return MyAnalyzeNum (pmLexRecord, pmTokRecord, myNumStr,
  585. mySeenDot | mySeenExp, myBase);
  586. }
  587. mySeenDot = TRUE;
  588. myNumStr [myPos] = myChar;
  589. myToken [myPos++] = myChar;
  590. pmLexRecord -> pos++;
  591. }
  592. else if (strchr (pmLexRecord -> table -> realExpChars, myChar))
  593. {
  594. if (mySeenExp || myBase)
  595. {
  596. myNumStr [myPos] = EOS;
  597. myToken [myPos] = EOS;
  598. return MyAnalyzeNum (pmLexRecord, pmTokRecord, myNumStr,
  599. mySeenDot | mySeenExp, myBase);
  600. }
  601. mySeenExp = TRUE;
  602. myNumStr [myPos] = 'e'; // Replace with C's character
  603. myToken [myPos++] = myChar;
  604. pmLexRecord -> pos++;
  605. while (pmLexRecord -> line [pmLexRecord -> pos] &&
  606. !isdigit (pmLexRecord -> line [pmLexRecord -> pos]))
  607. {
  608. myChar = pmLexRecord -> line [pmLexRecord -> pos];
  609. myNumStr [myPos] = myChar;
  610. myToken [myPos++] = myChar;
  611. pmLexRecord -> pos++;
  612. }
  613. }
  614. else if ((myChar == pmLexRecord -> table -> baseConvertChar) &&
  615. !mySeenBaseConv)
  616. {
  617. // Prefix is base to convert to
  618. myNumStr [myPos] = EOS;
  619. myToken [myPos++] = myChar;
  620. myBase = atol (myNumStr);
  621. myToken = myToken + myPos; // New zero is current pos
  622. myPos = 0;
  623. pmLexRecord -> pos++;
  624. mySeenBaseConv = TRUE;
  625. }
  626. else
  627. {
  628. myNumStr [myPos] = EOS;
  629. myToken [myPos] = EOS;
  630. // Handle suffixes here
  631. return MyAnalyzeNum (pmLexRecord, pmTokRecord, myNumStr,
  632. mySeenDot | mySeenExp, myBase);
  633. }
  634. }
  635. }
  636. } // MyGetNumber
  637. /************************************************************************/
  638. /* MyGetToken */
  639. /* */
  640. /* Return a general token */
  641. /************************************************************************/
  642. static void MyGetToken (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  643. {
  644. char *myToken = pmTokRecord -> token;
  645. UINT myPos = 0;
  646. for (;;)
  647. {
  648. char myChar = pmLexRecord -> line [pmLexRecord -> pos];
  649. if (isspace (myChar))
  650. {
  651. myToken [myPos] = EOS;
  652. return;
  653. }
  654. myToken [myPos++] = myChar;
  655. pmLexRecord -> pos++;
  656. }
  657. } // MyGetToken
  658. /************************************************************************/
  659. /* MyNextToken */
  660. /************************************************************************/
  661. static void MyNextToken (LexRecord *pmLexRecord, TOKEN_RECORD *pmTokRecord)
  662. {
  663. LexTable *myLexTable = pmLexRecord -> table;
  664. char myChar;
  665. char *myLine;
  666. int cnt;
  667. pmTokRecord -> lineNo = pmLexRecord -> lineNo;
  668. pmTokRecord -> linePos = pmLexRecord -> pos;
  669. pmTokRecord -> error = FALSE;
  670. if (pmLexRecord -> seenEOF)
  671. {
  672. pmTokRecord -> tokNum = tEOF;
  673. pmTokRecord -> token [0] = EOS;
  674. return;
  675. }
  676. if (pmLexRecord -> pos == NONE)
  677. {
  678. pmLexRecord -> pos = 0;
  679. pmTokRecord -> linePos = 0;
  680. pmLexRecord -> lineNo++;
  681. pmTokRecord -> lineNo++;
  682. myLine = MDIO_DiskFile_ReadLine (pmLexRecord -> line,
  683. sizeof (pmLexRecord -> line),
  684. pmLexRecord -> fp);
  685. if (myLine == NULL)
  686. {
  687. pmLexRecord -> seenEOF = TRUE;
  688. pmTokRecord -> tokNum = tEOF;
  689. pmTokRecord -> token[0] = EOS;
  690. return;
  691. }
  692. }
  693. myChar = pmLexRecord -> line [pmLexRecord -> pos];
  694. if (myChar == NL)
  695. {
  696. pmLexRecord -> pos = NONE;
  697. pmTokRecord -> tokNum = tNewLine;
  698. pmTokRecord -> token[0] = EOS;
  699. return;
  700. }
  701. if (pmLexRecord -> commentNum != NONE)
  702. {
  703. pmTokRecord -> token[0] = EOS;
  704. MyGetComment (pmLexRecord, pmTokRecord);
  705. pmTokRecord -> tokNum = tComment;
  706. return;
  707. }
  708. if (pmLexRecord -> inString)
  709. {
  710. pmTokRecord -> token[0] = EOS;
  711. pmLexRecord -> inString = MyGetString (pmLexRecord, pmTokRecord);
  712. pmTokRecord -> tokNum = tStringLit;
  713. return;
  714. }
  715. if (isalpha (myChar) ||
  716. (strchr (pmLexRecord -> table -> beginIDchars, myChar)))
  717. {
  718. MyGetIdentifier (pmLexRecord, pmTokRecord);
  719. pmTokRecord -> tokNum = MyLookupToken (myLexTable,
  720. pmTokRecord -> token);
  721. if (pmTokRecord -> tokNum == 0)
  722. {
  723. pmTokRecord -> tokNum = tIdentifier;
  724. }
  725. return;
  726. }
  727. if (isspace (myChar))
  728. {
  729. MyGetWhitespace (pmLexRecord, pmTokRecord);
  730. pmTokRecord -> tokNum = tWhitespace;
  731. return;
  732. }
  733. if (isdigit (myChar) ||
  734. ((myChar == '.') &&
  735. isdigit (pmLexRecord -> line [pmLexRecord -> pos + 1])))
  736. {
  737. pmTokRecord -> tokNum = MyGetNumber (pmLexRecord, pmTokRecord);
  738. return;
  739. }
  740. if (myChar == myLexTable -> startStringChar)
  741. {
  742. pmTokRecord -> token [0] = myLexTable -> startStringChar;
  743. pmLexRecord -> inString = MyGetString (pmLexRecord, pmTokRecord);
  744. pmTokRecord -> tokNum = tStringLit;
  745. return;
  746. }
  747. if (myChar == myLexTable -> charDelimitter)
  748. {
  749. MyGetChar (pmLexRecord, pmTokRecord);
  750. pmTokRecord -> tokNum = tCharLit;
  751. return;
  752. }
  753. // See if we're at beginning of a comment
  754. for (cnt = 0; cnt < (int) myLexTable -> numComments; cnt++)
  755. {
  756. if (myChar == myLexTable -> commentStart [cnt][0])
  757. {
  758. if (IS_MATCH (pmLexRecord -> line + pmLexRecord -> pos,
  759. myLexTable -> commentStart[cnt]))
  760. {
  761. pmLexRecord -> commentNum = cnt;
  762. strcpy (pmTokRecord -> token, myLexTable -> commentStart [cnt]);
  763. MyGetComment (pmLexRecord, pmTokRecord);
  764. pmTokRecord -> tokNum = tComment;
  765. return;
  766. }
  767. }
  768. }
  769. // Get a general (whitespace delimitted) token
  770. MyGetToken (pmLexRecord, pmTokRecord);
  771. // Check if entire token is in token list
  772. pmTokRecord -> tokNum = MyLookupToken (myLexTable, pmTokRecord -> token);
  773. if (pmTokRecord -> tokNum)
  774. {
  775. return;
  776. }
  777. //
  778. // Isolate prefix of token for testing
  779. //
  780. {
  781. char myStr [256];
  782. cnt = 0;
  783. while (pmTokRecord -> token[cnt] &&
  784. !isalnum (pmTokRecord -> token [cnt]))
  785. {
  786. myStr [cnt] = pmTokRecord -> token [cnt];
  787. cnt++;
  788. }
  789. // For each prefix, check for returned tokNum
  790. while (cnt > 0)
  791. {
  792. myStr [cnt] = EOS;
  793. pmTokRecord -> tokNum = MyLookupToken (myLexTable, myStr);
  794. if (pmTokRecord -> tokNum)
  795. {
  796. // Reset the position
  797. pmLexRecord -> pos -= (strlen (pmTokRecord -> token) - cnt);
  798. pmTokRecord -> token [cnt] = EOS;
  799. return;
  800. }
  801. cnt--;
  802. }
  803. pmTokRecord -> tokNum = tOther;
  804. }
  805. } // MyNextToken
  806. /*
  807. static Uint ConvertBase(str, base)
  808. CONST char *str;
  809. Uint base;
  810. {
  811. Uint val = 0;
  812. Uint mult = 1;
  813. int len = strlen(str);
  814. int i;
  815. for (i=len-1; i >= 0; i--) {
  816. char dig = str[i];
  817. if (isdigit(dig))
  818. val += (mult * (dig - '0'));
  819. else
  820. val += (mult * (toupper(dig) - 'A' + 10));
  821. mult *= base;
  822. }
  823. return val;
  824. }
  825. */