2
0
Roberto Ierusalimschy 32 жил өмнө
parent
commit
2058cc1dd9
1 өөрчлөгдсөн 207 нэмэгдсэн , 0 устгасан
  1. 207 0
      lex.c

+ 207 - 0
lex.c

@@ -0,0 +1,207 @@
+char *rcs_lex = "$Id$";
+/*$Log$*/
+
+#include <ctype.h>
+#include <math.h>
+
+#include "opcode.h"
+#include "hash.h"
+#include "inout.h"
+#include "table.h"
+#include "y.tab.h"
+
+#define next() { current = input(); }
+#define save(x) { *yytextLast++ = (x); }
+#define save_and_next()  { save(current); next(); }
+
+static int current;
+static char yytext[256];
+static char *yytextLast;
+
+static Input input;
+
+void lua_setinput (Input fn)
+{
+  current = ' ';
+  input = fn;
+}
+
+char *lua_lasttext (void)
+{
+  *yytextLast = 0;
+  return yytext;
+}
+
+
+static struct 
+  {
+    char *name;
+    int token;
+  } reserved [] = {
+      {"and", AND},
+      {"do", DO},
+      {"else", ELSE},
+      {"elseif", ELSEIF},
+      {"end", END},
+      {"function", FUNCTION},
+      {"if", IF},
+      {"local", LOCAL},
+      {"nil", NIL},
+      {"not", NOT},
+      {"or", OR},
+      {"repeat", REPEAT},
+      {"return", RETURN},
+      {"then", THEN},
+      {"until", UNTIL},
+      {"while", WHILE} };
+
+#define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0]))
+
+
+int findReserved (char *name)
+{
+  int l = 0;
+  int h = RESERVEDSIZE - 1;
+  while (l <= h)
+  {
+    int m = (l+h)/2;
+    int comp = strcmp(name, reserved[m].name);
+    if (comp < 0)
+      h = m-1;
+    else if (comp == 0)
+      return reserved[m].token;
+    else
+      l = m+1;
+  }
+  return 0;
+}
+
+
+int yylex ()
+{
+  while (1)
+  {
+    yytextLast = yytext;
+    switch (current)
+    {
+      case 0: return 0;
+      case '\n': lua_linenumber++;
+      case ' ':
+      case '\t':
+        save_and_next();
+        continue;
+  
+      case '-':
+        save_and_next();
+        if (current != '-') return '-';
+        do { save_and_next(); } while (current != '\n' && current != 0);
+        continue;
+  
+      case '<':
+        save_and_next();
+        if (current != '=') return '<';
+        else { save_and_next(); return LE; }
+  
+      case '>':
+        save_and_next();
+        if (current != '=') return '>';
+        else { save_and_next(); return GE; }
+  
+      case '~':
+        save_and_next();
+        if (current != '=') return '~';
+        else { save_and_next(); return NE; }
+
+      case '"':
+      case '\'':
+      {
+        int del = current;
+        next();  /* skip the delimiter */
+        while (current != del) 
+        {
+          switch (current)
+          {
+            case 0: 
+            case '\n': 
+              return WRONGTOKEN;
+            case '\\':
+              next();  /* do not save the '\' */
+              switch (current)
+              {
+                case 'n': save('\n'); next(); break;
+                case 't': save('\t'); next(); break;
+                case 'r': save('\r'); next(); break;
+                default : save('\\'); break;
+              }
+              break;
+            default: 
+              save_and_next();
+          }
+        }
+        next();  /* skip the delimiter */
+        *yytextLast = 0;
+        yylval.vWord = lua_findconstant (yytext);
+        return STRING;
+      }
+
+      case 'a': case 'b': case 'c': case 'd': case 'e':
+      case 'f': case 'g': case 'h': case 'i': case 'j':
+      case 'k': case 'l': case 'm': case 'n': case 'o':
+      case 'p': case 'q': case 'r': case 's': case 't':
+      case 'u': case 'v': case 'w': case 'x': case 'y':
+      case 'z':
+      case 'A': case 'B': case 'C': case 'D': case 'E':
+      case 'F': case 'G': case 'H': case 'I': case 'J':
+      case 'K': case 'L': case 'M': case 'N': case 'O':
+      case 'P': case 'Q': case 'R': case 'S': case 'T':
+      case 'U': case 'V': case 'W': case 'X': case 'Y':
+      case 'Z':
+      case '_':
+      {
+        int res;
+        do { save_and_next(); } while (isalnum(current) || current == '_');
+        *yytextLast = 0;
+        res = findReserved(yytext);
+        if (res) return res;
+        yylval.vWord = lua_findsymbol(yytext);
+        return NAME;
+      }
+   
+      case '.':
+        save_and_next();
+        if (current == '.') 
+        { 
+          save_and_next(); 
+          return CONC;
+        }
+        else if (!isdigit(current)) return '.';
+        /* current is a digit: goes through to number */
+        goto fraction;
+
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+      
+        do { save_and_next(); } while (isdigit(current));
+        if (current == '.') save_and_next();
+fraction: while (isdigit(current)) save_and_next();
+        if (current == 'e' || current == 'E')
+        {
+          save_and_next();
+          if (current == '+' || current == '-') save_and_next();
+          if (!isdigit(current)) return WRONGTOKEN;
+          do { save_and_next(); } while (isdigit(current));
+        }
+        *yytextLast = 0;
+        yylval.vFloat = atof(yytext);
+        return NUMBER;
+
+      default: 
+      {
+        int temp = current;
+        save_and_next();
+        return temp;      
+      }
+    }
+  }
+}
+