llex.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:10k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*
  2. ** $Id: llex.c,v 1.72 2000/10/20 16:39:03 roberto Exp $
  3. ** Lexical Analyzer
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "lua.h"
  10. #include "llex.h"
  11. #include "lmem.h"
  12. #include "lobject.h"
  13. #include "lparser.h"
  14. #include "lstate.h"
  15. #include "lstring.h"
  16. #include "ltable.h"
  17. #include "luadebug.h"
  18. #include "lzio.h"
  19. #define next(LS) (LS->current = zgetc(LS->z))
  20. /* ORDER RESERVED */
  21. static const char *const token2string [] = {
  22.     "and", "break", "do", "else", "elseif", "end", "for",
  23.     "function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
  24.     "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"};
  25. void luaX_init (lua_State *L) {
  26.   int i;
  27.   for (i=0; i<NUM_RESERVED; i++) {
  28.     TString *ts = luaS_new(L, token2string[i]);
  29.     ts->marked = (unsigned char)(RESERVEDMARK+i);  /* reserved word */
  30.   }
  31. }
  32. #define MAXSRC          80
  33. void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
  34.   if (val > limit) {
  35.     char buff[100];
  36.     sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
  37.     luaX_error(ls, buff, ls->t.token);
  38.   }
  39. }
  40. void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
  41.   char buff[MAXSRC];
  42.   luaO_chunkid(buff, ls->source->str, sizeof(buff));
  43.   luaO_verror(ls->L, "%.99s;n  last token read: `%.30s' at line %d in %.80s",
  44.               s, token, ls->linenumber, buff);
  45. }
  46. void luaX_error (LexState *ls, const char *s, int token) {
  47.   char buff[TOKEN_LEN];
  48.   luaX_token2str(token, buff);
  49.   if (buff[0] == '')
  50.     luaX_syntaxerror(ls, s, ls->L->Mbuffer);
  51.   else
  52.     luaX_syntaxerror(ls, s, buff);
  53. }
  54. void luaX_token2str (int token, char *s) {
  55.   if (token < 256) {
  56.     s[0] = (char)token;
  57.     s[1] = '';
  58.   }
  59.   else
  60.     strcpy(s, token2string[token-FIRST_RESERVED]);
  61. }
  62. static void luaX_invalidchar (LexState *ls, int c) {
  63.   char buff[8];
  64.   sprintf(buff, "0x%02X", c);
  65.   luaX_syntaxerror(ls, "invalid control char", buff);
  66. }
  67. static void inclinenumber (LexState *LS) {
  68.   next(LS);  /* skip 'n' */
  69.   ++LS->linenumber;
  70.   luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
  71. }
  72. void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
  73.   LS->L = L;
  74.   LS->lookahead.token = TK_EOS;  /* no look-ahead token */
  75.   LS->z = z;
  76.   LS->fs = NULL;
  77.   LS->linenumber = 1;
  78.   LS->lastline = 1;
  79.   LS->source = source;
  80.   next(LS);  /* read first char */
  81.   if (LS->current == '#') {
  82.     do {  /* skip first line */
  83.       next(LS);
  84.     } while (LS->current != 'n' && LS->current != EOZ);
  85.   }
  86. }
  87. /*
  88. ** =======================================================
  89. ** LEXICAL ANALYZER
  90. ** =======================================================
  91. */
  92. /* use Mbuffer to store names, literal strings and numbers */
  93. #define EXTRABUFF 128
  94. #define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) 
  95.                                   luaO_openspace(L, (len)+(n)+EXTRABUFF)
  96. #define save(L, c, l) (L->Mbuffer[l++] = (char)c)
  97. #define save_and_next(L, LS, l)  (save(L, LS->current, l), next(LS))
  98. static const char *readname (LexState *LS) {
  99.   lua_State *L = LS->L;
  100.   size_t l = 0;
  101.   checkbuffer(L, 10, l);
  102.   do {
  103.     checkbuffer(L, 10, l);
  104.     save_and_next(L, LS, l);
  105.   } while (isalnum(LS->current) || LS->current == '_');
  106.   save(L, '', l);
  107.   return L->Mbuffer;
  108. }
  109. /* LUA_NUMBER */
  110. static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
  111.   lua_State *L = LS->L;
  112.   size_t l = 0;
  113.   checkbuffer(L, 10, l);
  114.   if (comma) save(L, '.', l);
  115.   while (isdigit(LS->current)) {
  116.     checkbuffer(L, 10, l);
  117.     save_and_next(L, LS, l);
  118.   }
  119.   if (LS->current == '.') {
  120.     save_and_next(L, LS, l);
  121.     if (LS->current == '.') {
  122.       save_and_next(L, LS, l);
  123.       save(L, '', l);
  124.       luaX_error(LS, "ambiguous syntax"
  125.            " (decimal point x string concatenation)", TK_NUMBER);
  126.     }
  127.   }
  128.   while (isdigit(LS->current)) {
  129.     checkbuffer(L, 10, l);
  130.     save_and_next(L, LS, l);
  131.   }
  132.   if (LS->current == 'e' || LS->current == 'E') {
  133.     save_and_next(L, LS, l);  /* read 'E' */
  134.     if (LS->current == '+' || LS->current == '-')
  135.       save_and_next(L, LS, l);  /* optional exponent sign */
  136.     while (isdigit(LS->current)) {
  137.       checkbuffer(L, 10, l);
  138.       save_and_next(L, LS, l);
  139.     }
  140.   }
  141.   save(L, '', l);
  142.   if (!luaO_str2d(L->Mbuffer, &seminfo->r))
  143.     luaX_error(LS, "malformed number", TK_NUMBER);
  144. }
  145. static void read_long_string (LexState *LS, SemInfo *seminfo) {
  146.   lua_State *L = LS->L;
  147.   int cont = 0;
  148.   size_t l = 0;
  149.   checkbuffer(L, 10, l);
  150.   save(L, '[', l);  /* save first '[' */
  151.   save_and_next(L, LS, l);  /* pass the second '[' */
  152.   for (;;) {
  153.     checkbuffer(L, 10, l);
  154.     switch (LS->current) {
  155.       case EOZ:
  156.         save(L, '', l);
  157.         luaX_error(LS, "unfinished long string", TK_STRING);
  158.         break;  /* to avoid warnings */
  159.       case '[':
  160.         save_and_next(L, LS, l);
  161.         if (LS->current == '[') {
  162.           cont++;
  163.           save_and_next(L, LS, l);
  164.         }
  165.         continue;
  166.       case ']':
  167.         save_and_next(L, LS, l);
  168.         if (LS->current == ']') {
  169.           if (cont == 0) goto endloop;
  170.           cont--;
  171.           save_and_next(L, LS, l);
  172.         }
  173.         continue;
  174.       case 'n':
  175.         save(L, 'n', l);
  176.         inclinenumber(LS);
  177.         continue;
  178.       default:
  179.         save_and_next(L, LS, l);
  180.     }
  181.   } endloop:
  182.   save_and_next(L, LS, l);  /* skip the second ']' */
  183.   save(L, '', l);
  184.   seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
  185. }
  186. static void read_string (LexState *LS, int del, SemInfo *seminfo) {
  187.   lua_State *L = LS->L;
  188.   size_t l = 0;
  189.   checkbuffer(L, 10, l);
  190.   save_and_next(L, LS, l);
  191.   while (LS->current != del) {
  192.     checkbuffer(L, 10, l);
  193.     switch (LS->current) {
  194.       case EOZ:  case 'n':
  195.         save(L, '', l);
  196.         luaX_error(LS, "unfinished string", TK_STRING);
  197.         break;  /* to avoid warnings */
  198.       case '\':
  199.         next(LS);  /* do not save the '' */
  200.         switch (LS->current) {
  201.           case 'a': save(L, 'a', l); next(LS); break;
  202.           case 'b': save(L, 'b', l); next(LS); break;
  203.           case 'f': save(L, 'f', l); next(LS); break;
  204.           case 'n': save(L, 'n', l); next(LS); break;
  205.           case 'r': save(L, 'r', l); next(LS); break;
  206.           case 't': save(L, 't', l); next(LS); break;
  207.           case 'v': save(L, 'v', l); next(LS); break;
  208.           case 'n': save(L, 'n', l); inclinenumber(LS); break;
  209.           case '0': case '1': case '2': case '3': case '4':
  210.           case '5': case '6': case '7': case '8': case '9': {
  211.             int c = 0;
  212.             int i = 0;
  213.             do {
  214.               c = 10*c + (LS->current-'0');
  215.               next(LS);
  216.             } while (++i<3 && isdigit(LS->current));
  217.             if (c != (unsigned char)c) {
  218.               save(L, '', l);
  219.               luaX_error(LS, "escape sequence too large", TK_STRING);
  220.             }
  221.             save(L, c, l);
  222.             break;
  223.           }
  224.           default:  /* handles \, ", ', and ? */
  225.             save_and_next(L, LS, l);
  226.         }
  227.         break;
  228.       default:
  229.         save_and_next(L, LS, l);
  230.     }
  231.   }
  232.   save_and_next(L, LS, l);  /* skip delimiter */
  233.   save(L, '', l);
  234.   seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
  235. }
  236. int luaX_lex (LexState *LS, SemInfo *seminfo) {
  237.   for (;;) {
  238.     switch (LS->current) {
  239.       case ' ': case 't': case 'r':  /* `r' to avoid problems with DOS */
  240.         next(LS);
  241.         continue;
  242.       case 'n':
  243.         inclinenumber(LS);
  244.         continue;
  245.       case '$':
  246.         luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
  247.         break;
  248.       case '-':
  249.         next(LS);
  250.         if (LS->current != '-') return '-';
  251.         do { next(LS); } while (LS->current != 'n' && LS->current != EOZ);
  252.         continue;
  253.       case '[':
  254.         next(LS);
  255.         if (LS->current != '[') return '[';
  256.         else {
  257.           read_long_string(LS, seminfo);
  258.           return TK_STRING;
  259.         }
  260.       case '=':
  261.         next(LS);
  262.         if (LS->current != '=') return '=';
  263.         else { next(LS); return TK_EQ; }
  264.       case '<':
  265.         next(LS);
  266.         if (LS->current != '=') return '<';
  267.         else { next(LS); return TK_LE; }
  268.       case '>':
  269.         next(LS);
  270.         if (LS->current != '=') return '>';
  271.         else { next(LS); return TK_GE; }
  272.       case '~':
  273.         next(LS);
  274.         if (LS->current != '=') return '~';
  275.         else { next(LS); return TK_NE; }
  276.       case '"':
  277.       case ''':
  278.         read_string(LS, LS->current, seminfo);
  279.         return TK_STRING;
  280.       case '.':
  281.         next(LS);
  282.         if (LS->current == '.') {
  283.           next(LS);
  284.           if (LS->current == '.') {
  285.             next(LS);
  286.             return TK_DOTS;   /* ... */
  287.           }
  288.           else return TK_CONCAT;   /* .. */
  289.         }
  290.         else if (!isdigit(LS->current)) return '.';
  291.         else {
  292.           read_number(LS, 1, seminfo);
  293.           return TK_NUMBER;
  294.         }
  295.       case '0': case '1': case '2': case '3': case '4':
  296.       case '5': case '6': case '7': case '8': case '9':
  297.         read_number(LS, 0, seminfo);
  298.         return TK_NUMBER;
  299.       case EOZ:
  300.         return TK_EOS;
  301.       case '_': goto tname;
  302.       default:
  303.         if (!isalpha(LS->current)) {
  304.           int c = LS->current;
  305.           if (iscntrl(c))
  306.             luaX_invalidchar(LS, c);
  307.           next(LS);
  308.           return c;
  309.         }
  310.         tname: {  /* identifier or reserved word */
  311.           TString *ts = luaS_new(LS->L, readname(LS));
  312.           if (ts->marked >= RESERVEDMARK)  /* reserved word? */
  313.             return ts->marked-RESERVEDMARK+FIRST_RESERVED;
  314.           seminfo->ts = ts;
  315.           return TK_NAME;
  316.         }
  317.     }
  318.   }
  319. }