From 2058cc1dd9fa0ec57fe9191f66ed8b2790b31a25 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 22 Dec 1993 19:15:16 -0200 Subject: [PATCH] analizador lexico de LUA --- lex.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 lex.c diff --git a/lex.c b/lex.c new file mode 100644 index 00000000..81bf9f31 --- /dev/null +++ b/lex.c @@ -0,0 +1,207 @@ +char *rcs_lex = "$Id$"; +/*$Log$*/ + +#include +#include + +#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; + } + } + } +} +