diff options
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 91 |
1 files changed, 50 insertions, 41 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.98 2002/03/08 19:07:01 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.99 2002/03/08 19:25:24 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include "lua.h" | 12 | #include "lua.h" |
13 | 13 | ||
14 | #include "ldo.h" | ||
14 | #include "llex.h" | 15 | #include "llex.h" |
15 | #include "lobject.h" | 16 | #include "lobject.h" |
16 | #include "lparser.h" | 17 | #include "lparser.h" |
@@ -29,9 +30,9 @@ static const char *const token2string [] = { | |||
29 | "and", "break", "do", "else", "elseif", | 30 | "and", "break", "do", "else", "elseif", |
30 | "end", "false", "for", "function", "global", "if", | 31 | "end", "false", "for", "function", "global", "if", |
31 | "in", "local", "nil", "not", "or", "repeat", | 32 | "in", "local", "nil", "not", "or", "repeat", |
32 | "return", "then", "true", "until", "while", "", | 33 | "return", "then", "true", "until", "while", "*name", |
33 | "..", "...", "==", ">=", "<=", "~=", | 34 | "..", "...", "==", ">=", "<=", "~=", |
34 | "", "", "<eof>" | 35 | "*number", "*string", "<eof>" |
35 | }; | 36 | }; |
36 | 37 | ||
37 | 38 | ||
@@ -50,53 +51,57 @@ void luaX_init (lua_State *L) { | |||
50 | 51 | ||
51 | void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { | 52 | void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { |
52 | if (val > limit) { | 53 | if (val > limit) { |
53 | char buff[90]; | 54 | msg = luaO_pushstr(ls->L, "too many %s (limit=%d)", msg, limit); |
54 | sprintf(buff, "too many %.40s (limit=%d)", msg, limit); | 55 | luaX_syntaxerror(ls, msg); |
55 | luaX_error(ls, buff, ls->t.token); | ||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
60 | static void luaX_syntaxerror (LexState *ls, const char *s, | 60 | static void luaX_error (LexState *ls, const char *s, const char *token) { |
61 | const char *token) { | 61 | lua_State *L = ls->L; |
62 | char buff[MAXSRC]; | 62 | char buff[MAXSRC]; |
63 | luaO_chunkid(buff, getstr(ls->source), MAXSRC); | 63 | luaO_chunkid(buff, getstr(ls->source), MAXSRC); |
64 | luaO_verror(ls->L, | 64 | luaO_pushstr(L, "%s;\n last token read: `%s' at line %d in %s", |
65 | "%.99s;\n last token read: `%.30s' at line %d in %.80s", | 65 | s, token, ls->linenumber, buff); |
66 | s, token, ls->linenumber, buff); | 66 | luaD_errorobj(L, L->top - 1, LUA_ERRSYNTAX); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | void luaX_token2str (int token, char *s) { | 70 | void luaX_syntaxerror (LexState *ls, const char *msg) { |
71 | if (token < FIRST_RESERVED) { | 71 | const char *lasttoken; |
72 | lua_assert(token == (char)token); | 72 | switch (ls->t.token) { |
73 | s[0] = (char)token; | 73 | case TK_NAME: |
74 | s[1] = '\0'; | 74 | lasttoken = luaO_pushstr(ls->L, "%s", getstr(ls->t.seminfo.ts)); |
75 | break; | ||
76 | case TK_STRING: | ||
77 | lasttoken = luaO_pushstr(ls->L, "\"%s\"", getstr(ls->t.seminfo.ts)); | ||
78 | break; | ||
79 | case TK_NUMBER: | ||
80 | lasttoken = luaO_pushstr(ls->L, "%f", ls->t.seminfo.r); | ||
81 | break; | ||
82 | default: | ||
83 | lasttoken = luaX_token2str(ls, ls->t.token); | ||
84 | break; | ||
75 | } | 85 | } |
76 | else | 86 | luaX_error(ls, msg, lasttoken); |
77 | strcpy(s, token2string[token-FIRST_RESERVED]); | ||
78 | } | 87 | } |
79 | 88 | ||
80 | 89 | ||
81 | static char *token2str_all (LexState *ls, int token, char *s) { | 90 | const char *luaX_token2str (LexState *ls, int token) { |
82 | luaX_token2str(token, s); | 91 | if (token < FIRST_RESERVED) { |
83 | if (s[0] == '\0') | 92 | lua_assert(token == (char)token); |
84 | return cast(char *, G(ls->L)->Mbuffer); | 93 | return luaO_pushstr(ls->L, "%c", token); |
94 | } | ||
85 | else | 95 | else |
86 | return s; | 96 | return token2string[token-FIRST_RESERVED]; |
87 | } | ||
88 | |||
89 | |||
90 | void luaX_error (LexState *ls, const char *s, int token) { | ||
91 | char buff[TOKEN_LEN]; | ||
92 | luaX_syntaxerror(ls, s, token2str_all(ls, token, buff)); | ||
93 | } | 97 | } |
94 | 98 | ||
95 | 99 | ||
96 | static void luaX_invalidchar (LexState *ls, int c) { | 100 | static void luaX_lexerror (LexState *ls, const char *s, int token) { |
97 | char buff[8]; | 101 | if (token == TK_EOS) |
98 | sprintf(buff, "0x%02X", (unsigned char)c); | 102 | luaX_error(ls, s, luaX_token2str(ls, token)); |
99 | luaX_syntaxerror(ls, "invalid control char", buff); | 103 | else |
104 | luaX_error(ls, s, cast(char *, G(ls->L)->Mbuffer)); | ||
100 | } | 105 | } |
101 | 106 | ||
102 | 107 | ||
@@ -171,7 +176,7 @@ static void read_number (LexState *LS, int comma, SemInfo *seminfo) { | |||
171 | if (LS->current == '.') { | 176 | if (LS->current == '.') { |
172 | save_and_next(L, LS, l); | 177 | save_and_next(L, LS, l); |
173 | save(L, '\0', l); | 178 | save(L, '\0', l); |
174 | luaX_error(LS, | 179 | luaX_lexerror(LS, |
175 | "ambiguous syntax (decimal point x string concatenation)", | 180 | "ambiguous syntax (decimal point x string concatenation)", |
176 | TK_NUMBER); | 181 | TK_NUMBER); |
177 | } | 182 | } |
@@ -191,7 +196,7 @@ static void read_number (LexState *LS, int comma, SemInfo *seminfo) { | |||
191 | } | 196 | } |
192 | save(L, '\0', l); | 197 | save(L, '\0', l); |
193 | if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r)) | 198 | if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r)) |
194 | luaX_error(LS, "malformed number", TK_NUMBER); | 199 | luaX_lexerror(LS, "malformed number", TK_NUMBER); |
195 | } | 200 | } |
196 | 201 | ||
197 | 202 | ||
@@ -209,7 +214,7 @@ static void read_long_string (LexState *LS, SemInfo *seminfo) { | |||
209 | switch (LS->current) { | 214 | switch (LS->current) { |
210 | case EOZ: | 215 | case EOZ: |
211 | save(L, '\0', l); | 216 | save(L, '\0', l); |
212 | luaX_error(LS, (seminfo) ? "unfinished long string" : | 217 | luaX_lexerror(LS, (seminfo) ? "unfinished long string" : |
213 | "unfinished long comment", TK_EOS); | 218 | "unfinished long comment", TK_EOS); |
214 | break; /* to avoid warnings */ | 219 | break; /* to avoid warnings */ |
215 | case '[': | 220 | case '[': |
@@ -251,10 +256,13 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) { | |||
251 | while (LS->current != del) { | 256 | while (LS->current != del) { |
252 | checkbuffer(L, l); | 257 | checkbuffer(L, l); |
253 | switch (LS->current) { | 258 | switch (LS->current) { |
254 | case EOZ: case '\n': | 259 | case EOZ: |
260 | save(L, '\0', l); | ||
261 | luaX_lexerror(LS, "unfinished string", TK_EOS); | ||
262 | break; /* to avoid warnings */ | ||
263 | case '\n': | ||
255 | save(L, '\0', l); | 264 | save(L, '\0', l); |
256 | luaX_error(LS, "unfinished string", | 265 | luaX_lexerror(LS, "unfinished string", TK_STRING); |
257 | (LS->current == EOZ) ? TK_EOS : TK_STRING); | ||
258 | break; /* to avoid warnings */ | 266 | break; /* to avoid warnings */ |
259 | case '\\': | 267 | case '\\': |
260 | next(LS); /* do not save the `\' */ | 268 | next(LS); /* do not save the `\' */ |
@@ -279,7 +287,7 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) { | |||
279 | } while (++i<3 && isdigit(LS->current)); | 287 | } while (++i<3 && isdigit(LS->current)); |
280 | if (c > UCHAR_MAX) { | 288 | if (c > UCHAR_MAX) { |
281 | save(L, '\0', l); | 289 | save(L, '\0', l); |
282 | luaX_error(LS, "escape sequence too large", TK_STRING); | 290 | luaX_lexerror(LS, "escape sequence too large", TK_STRING); |
283 | } | 291 | } |
284 | save(L, c, l); | 292 | save(L, c, l); |
285 | } | 293 | } |
@@ -389,7 +397,8 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { | |||
389 | else { | 397 | else { |
390 | int c = LS->current; | 398 | int c = LS->current; |
391 | if (iscntrl(c)) | 399 | if (iscntrl(c)) |
392 | luaX_invalidchar(LS, c); | 400 | luaX_error(LS, "invalid control char", |
401 | luaO_pushstr(LS->L, "char(%d)", c)); | ||
393 | next(LS); | 402 | next(LS); |
394 | return c; /* single-char tokens (+ - / ...) */ | 403 | return c; /* single-char tokens (+ - / ...) */ |
395 | } | 404 | } |