llex.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:12k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /*
  2. ** $Id: llex.c,v 2.19 2006/02/06 18:28:16 roberto Exp $
  3. ** Lexical Analyzer
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <locale.h>
  8. #include <string.h>
  9. #define llex_c
  10. #define LUA_CORE
  11. #include "lua.h"
  12. #include "ldo.h"
  13. #include "llex.h"
  14. #include "lobject.h"
  15. #include "lparser.h"
  16. #include "lstate.h"
  17. #include "lstring.h"
  18. #include "lzio.h"
  19. #define next(ls) (ls->current = zgetc(ls->z))
  20. #define currIsNewline(ls) (ls->current == 'n' || ls->current == 'r')
  21. /* ORDER RESERVED */
  22. const char *const luaX_tokens [] = {
  23.     "and", "break", "do", "else", "elseif",
  24.     "end", "false", "for", "function", "if",
  25.     "in", "local", "nil", "not", "or", "repeat",
  26.     "return", "then", "true", "until", "while",
  27.     "..", "...", "==", ">=", "<=", "~=",
  28.     "<number>", "<name>", "<string>", "<eof>",
  29.     NULL
  30. };
  31. #define save_and_next(ls) (save(ls, ls->current), next(ls))
  32. static void save (LexState *ls, int c) {
  33.   Mbuffer *b = ls->buff;
  34.   if (b->n + 1 > b->buffsize) {
  35.     size_t newsize;
  36.     if (b->buffsize >= MAX_SIZET/2)
  37.       luaX_lexerror(ls, "lexical element too long", 0);
  38.     newsize = b->buffsize * 2;
  39.     luaZ_resizebuffer(ls->L, b, newsize);
  40.   }
  41.   b->buffer[b->n++] = cast(char, c);
  42. }
  43. void luaX_init (lua_State *L) {
  44.   int i;
  45.   for (i=0; i<NUM_RESERVED; i++) {
  46.     TString *ts = luaS_new(L, luaX_tokens[i]);
  47.     luaS_fix(ts);  /* reserved words are never collected */
  48.     lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
  49.     ts->tsv.reserved = cast_byte(i+1);  /* reserved word */
  50.   }
  51. }
  52. #define MAXSRC          80
  53. const char *luaX_token2str (LexState *ls, int token) {
  54.   if (token < FIRST_RESERVED) {
  55.     lua_assert(token == cast(unsigned char, token));
  56.     return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
  57.                               luaO_pushfstring(ls->L, "%c", token);
  58.   }
  59.   else
  60.     return luaX_tokens[token-FIRST_RESERVED];
  61. }
  62. static const char *txtToken (LexState *ls, int token) {
  63.   switch (token) {
  64.     case TK_NAME:
  65.     case TK_STRING:
  66.     case TK_NUMBER:
  67.       save(ls, '');
  68.       return luaZ_buffer(ls->buff);
  69.     default:
  70.       return luaX_token2str(ls, token);
  71.   }
  72. }
  73. void luaX_lexerror (LexState *ls, const char *msg, int token) {
  74.   char buff[MAXSRC];
  75.   luaO_chunkid(buff, getstr(ls->source), MAXSRC);
  76.   msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
  77.   if (token)
  78.     luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
  79.   luaD_throw(ls->L, LUA_ERRSYNTAX);
  80. }
  81. void luaX_syntaxerror (LexState *ls, const char *msg) {
  82.   luaX_lexerror(ls, msg, ls->t.token);
  83. }
  84. TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
  85.   lua_State *L = ls->L;
  86.   TString *ts = luaS_newlstr(L, str, l);
  87.   TValue *o = luaH_setstr(L, ls->fs->h, ts);  /* entry for `str' */
  88.   if (ttisnil(o))
  89.     setbvalue(o, 1);  /* make sure `str' will not be collected */
  90.   return ts;
  91. }
  92. static void inclinenumber (LexState *ls) {
  93.   int old = ls->current;
  94.   lua_assert(currIsNewline(ls));
  95.   next(ls);  /* skip `n' or `r' */
  96.   if (currIsNewline(ls) && ls->current != old)
  97.     next(ls);  /* skip `nr' or `rn' */
  98.   if (++ls->linenumber >= MAX_INT)
  99.     luaX_syntaxerror(ls, "chunk has too many lines");
  100. }
  101. void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
  102.   ls->decpoint = '.';
  103.   ls->L = L;
  104.   ls->lookahead.token = TK_EOS;  /* no look-ahead token */
  105.   ls->z = z;
  106.   ls->fs = NULL;
  107.   ls->linenumber = 1;
  108.   ls->lastline = 1;
  109.   ls->source = source;
  110.   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
  111.   next(ls);  /* read first char */
  112. }
  113. /*
  114. ** =======================================================
  115. ** LEXICAL ANALYZER
  116. ** =======================================================
  117. */
  118. static int check_next (LexState *ls, const char *set) {
  119.   if (!strchr(set, ls->current))
  120.     return 0;
  121.   save_and_next(ls);
  122.   return 1;
  123. }
  124. static void buffreplace (LexState *ls, char from, char to) {
  125.   size_t n = luaZ_bufflen(ls->buff);
  126.   char *p = luaZ_buffer(ls->buff);
  127.   while (n--)
  128.     if (p[n] == from) p[n] = to;
  129. }
  130. static void trydecpoint (LexState *ls, SemInfo *seminfo) {
  131.   /* format error: try to update decimal point separator */
  132.   struct lconv *cv = localeconv();
  133.   char old = ls->decpoint;
  134.   ls->decpoint = (cv ? cv->decimal_point[0] : '.');
  135.   buffreplace(ls, old, ls->decpoint);  /* try updated decimal separator */
  136.   if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
  137.     /* format error with correct decimal point: no more options */
  138.     buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
  139.     luaX_lexerror(ls, "malformed number", TK_NUMBER);
  140.   }
  141. }
  142. /* LUA_NUMBER */
  143. static void read_numeral (LexState *ls, SemInfo *seminfo) {
  144.   lua_assert(isdigit(ls->current));
  145.   do {
  146.     save_and_next(ls);
  147.   } while (isdigit(ls->current) || ls->current == '.');
  148.   if (check_next(ls, "Ee"))  /* `E'? */
  149.     check_next(ls, "+-");  /* optional exponent sign */
  150.   while (isalnum(ls->current) || ls->current == '_')
  151.     save_and_next(ls);
  152.   save(ls, '');
  153.   buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
  154.   if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r))  /* format error? */
  155.     trydecpoint(ls, seminfo); /* try to update decimal point separator */
  156. }
  157. static int skip_sep (LexState *ls) {
  158.   int count = 0;
  159.   int s = ls->current;
  160.   lua_assert(s == '[' || s == ']');
  161.   save_and_next(ls);
  162.   while (ls->current == '=') {
  163.     save_and_next(ls);
  164.     count++;
  165.   }
  166.   return (ls->current == s) ? count : (-count) - 1;
  167. }
  168. static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
  169.   int cont = 0;
  170.   (void)(cont);  /* avoid warnings when `cont' is not used */
  171.   save_and_next(ls);  /* skip 2nd `[' */
  172.   if (currIsNewline(ls))  /* string starts with a newline? */
  173.     inclinenumber(ls);  /* skip it */
  174.   for (;;) {
  175.     switch (ls->current) {
  176.       case EOZ:
  177.         luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
  178.                                    "unfinished long comment", TK_EOS);
  179.         break;  /* to avoid warnings */
  180. #if defined(LUA_COMPAT_LSTR)
  181.       case '[': {
  182.         if (skip_sep(ls) == sep) {
  183.           save_and_next(ls);  /* skip 2nd `[' */
  184.           cont++;
  185. #if LUA_COMPAT_LSTR == 1
  186.           if (sep == 0)
  187.             luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
  188. #endif
  189.         }
  190.         break;
  191.       }
  192. #endif
  193.       case ']': {
  194.         if (skip_sep(ls) == sep) {
  195.           save_and_next(ls);  /* skip 2nd `]' */
  196. #if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
  197.           cont--;
  198.           if (sep == 0 && cont >= 0) break;
  199. #endif
  200.           goto endloop;
  201.         }
  202.         break;
  203.       }
  204.       case 'n':
  205.       case 'r': {
  206.         save(ls, 'n');
  207.         inclinenumber(ls);
  208.         if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
  209.         break;
  210.       }
  211.       default: {
  212.         if (seminfo) save_and_next(ls);
  213.         else next(ls);
  214.       }
  215.     }
  216.   } endloop:
  217.   if (seminfo)
  218.     seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
  219.                                      luaZ_bufflen(ls->buff) - 2*(2 + sep));
  220. }
  221. static void read_string (LexState *ls, int del, SemInfo *seminfo) {
  222.   save_and_next(ls);
  223.   while (ls->current != del) {
  224.     switch (ls->current) {
  225.       case EOZ:
  226.         luaX_lexerror(ls, "unfinished string", TK_EOS);
  227.         continue;  /* to avoid warnings */
  228.       case 'n':
  229.       case 'r':
  230.         luaX_lexerror(ls, "unfinished string", TK_STRING);
  231.         continue;  /* to avoid warnings */
  232.       case '\': {
  233.         int c;
  234.         next(ls);  /* do not save the `' */
  235.         switch (ls->current) {
  236.           case 'a': c = 'a'; break;
  237.           case 'b': c = 'b'; break;
  238.           case 'f': c = 'f'; break;
  239.           case 'n': c = 'n'; break;
  240.           case 'r': c = 'r'; break;
  241.           case 't': c = 't'; break;
  242.           case 'v': c = 'v'; break;
  243.           case 'n':  /* go through */
  244.           case 'r': save(ls, 'n'); inclinenumber(ls); continue;
  245.           case EOZ: continue;  /* will raise an error next loop */
  246.           default: {
  247.             if (!isdigit(ls->current))
  248.               save_and_next(ls);  /* handles \, ", ', and ? */
  249.             else {  /* xxx */
  250.               int i = 0;
  251.               c = 0;
  252.               do {
  253.                 c = 10*c + (ls->current-'0');
  254.                 next(ls);
  255.               } while (++i<3 && isdigit(ls->current));
  256.               if (c > UCHAR_MAX)
  257.                 luaX_lexerror(ls, "escape sequence too large", TK_STRING);
  258.               save(ls, c);
  259.             }
  260.             continue;
  261.           }
  262.         }
  263.         save(ls, c);
  264.         next(ls);
  265.         continue;
  266.       }
  267.       default:
  268.         save_and_next(ls);
  269.     }
  270.   }
  271.   save_and_next(ls);  /* skip delimiter */
  272.   seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
  273.                                    luaZ_bufflen(ls->buff) - 2);
  274. }
  275. static int llex (LexState *ls, SemInfo *seminfo) {
  276.   luaZ_resetbuffer(ls->buff);
  277.   for (;;) {
  278.     switch (ls->current) {
  279.       case 'n':
  280.       case 'r': {
  281.         inclinenumber(ls);
  282.         continue;
  283.       }
  284.       case '-': {
  285.         next(ls);
  286.         if (ls->current != '-') return '-';
  287.         /* else is a comment */
  288.         next(ls);
  289.         if (ls->current == '[') {
  290.           int sep = skip_sep(ls);
  291.           luaZ_resetbuffer(ls->buff);  /* `skip_sep' may dirty the buffer */
  292.           if (sep >= 0) {
  293.             read_long_string(ls, NULL, sep);  /* long comment */
  294.             luaZ_resetbuffer(ls->buff);
  295.             continue;
  296.           }
  297.         }
  298.         /* else short comment */
  299.         while (!currIsNewline(ls) && ls->current != EOZ)
  300.           next(ls);
  301.         continue;
  302.       }
  303.       case '[': {
  304.         int sep = skip_sep(ls);
  305.         if (sep >= 0) {
  306.           read_long_string(ls, seminfo, sep);
  307.           return TK_STRING;
  308.         }
  309.         else if (sep == -1) return '[';
  310.         else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
  311.       }
  312.       case '=': {
  313.         next(ls);
  314.         if (ls->current != '=') return '=';
  315.         else { next(ls); return TK_EQ; }
  316.       }
  317.       case '<': {
  318.         next(ls);
  319.         if (ls->current != '=') return '<';
  320.         else { next(ls); return TK_LE; }
  321.       }
  322.       case '>': {
  323.         next(ls);
  324.         if (ls->current != '=') return '>';
  325.         else { next(ls); return TK_GE; }
  326.       }
  327.       case '~': {
  328.         next(ls);
  329.         if (ls->current != '=') return '~';
  330.         else { next(ls); return TK_NE; }
  331.       }
  332.       case '"':
  333.       case ''': {
  334.         read_string(ls, ls->current, seminfo);
  335.         return TK_STRING;
  336.       }
  337.       case '.': {
  338.         save_and_next(ls);
  339.         if (check_next(ls, ".")) {
  340.           if (check_next(ls, "."))
  341.             return TK_DOTS;   /* ... */
  342.           else return TK_CONCAT;   /* .. */
  343.         }
  344.         else if (!isdigit(ls->current)) return '.';
  345.         else {
  346.           read_numeral(ls, seminfo);
  347.           return TK_NUMBER;
  348.         }
  349.       }
  350.       case EOZ: {
  351.         return TK_EOS;
  352.       }
  353.       default: {
  354.         if (isspace(ls->current)) {
  355.           lua_assert(!currIsNewline(ls));
  356.           next(ls);
  357.           continue;
  358.         }
  359.         else if (isdigit(ls->current)) {
  360.           read_numeral(ls, seminfo);
  361.           return TK_NUMBER;
  362.         }
  363.         else if (isalpha(ls->current) || ls->current == '_') {
  364.           /* identifier or reserved word */
  365.           TString *ts;
  366.           do {
  367.             save_and_next(ls);
  368.           } while (isalnum(ls->current) || ls->current == '_');
  369.           ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
  370.                                   luaZ_bufflen(ls->buff));
  371.           if (ts->tsv.reserved > 0)  /* reserved word? */
  372.             return ts->tsv.reserved - 1 + FIRST_RESERVED;
  373.           else {
  374.             seminfo->ts = ts;
  375.             return TK_NAME;
  376.           }
  377.         }
  378.         else {
  379.           int c = ls->current;
  380.           next(ls);
  381.           return c;  /* single-char tokens (+ - / ...) */
  382.         }
  383.       }
  384.     }
  385.   }
  386. }
  387. void luaX_next (LexState *ls) {
  388.   ls->lastline = ls->linenumber;
  389.   if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
  390.     ls->t = ls->lookahead;  /* use this one */
  391.     ls->lookahead.token = TK_EOS;  /* and discharge it */
  392.   }
  393.   else
  394.     ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
  395. }
  396. void luaX_lookahead (LexState *ls) {
  397.   lua_assert(ls->lookahead.token == TK_EOS);
  398.   ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
  399. }