commit 60d4c2eb9824194b7c1b4a4dda537080f6e6ad25
parent 8dc3257f1cd68efd60176c8d7a51dec9cbae1e40
Author: sin <sin@2f30.org>
Date: Fri, 9 May 2014 20:52:07 +0100
Use internal state variable to track the lexer's state
Diffstat:
M | lexer.c | | | 49 | ++++++++++++++++++++++++++----------------------- |
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/lexer.c b/lexer.c
@@ -58,7 +58,6 @@ struct tok
gettok(struct lexerctx *ctx, const char *buf, size_t len)
{
struct tok tok;
- enum state state = State_Se;
char *tmp;
if (ctx->ready == 0) {
@@ -66,36 +65,36 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
ctx->e = buf;
ctx->ready = 1;
}
-
+ ctx->state = State_Se;
while (ctx->e < &buf[len]) {
- switch (state) {
+ switch (ctx->state) {
case State_Se:
if (*ctx->e == ' ' || *ctx->e == '\t' ||
*ctx->e == '\n')
break;
if (isalpha(*ctx->e) != 0)
- state = State_Identifier;
+ ctx->state = State_Identifier;
else if (*ctx->e == '#')
- state = State_Probable_Boolean;
+ ctx->state = State_Probable_Boolean;
else if (isdigit(*ctx->e) != 0)
- state = State_Number;
+ ctx->state = State_Number;
else if (*ctx->e == '-' || *ctx->e == '+')
- state = State_Signed_Number;
+ ctx->state = State_Signed_Number;
else if (*ctx->e == '"')
- state = State_Probable_String;
+ ctx->state = State_Probable_String;
else if (*ctx->e == '(')
- state = State_Lparen;
+ ctx->state = State_Lparen;
else if (*ctx->e == ')')
- state = State_Rparen;
+ ctx->state = State_Rparen;
else if (*ctx->e == '\'')
- state = State_Quote;
+ ctx->state = State_Quote;
else if (*ctx->e == '.')
- state = State_Dot;
+ ctx->state = State_Dot;
else if (*ctx->e == ';')
- state = State_Comment;
+ ctx->state = State_Comment;
else
- state = State_Illegal_Input;
- if (state != State_Se)
+ ctx->state = State_Illegal_Input;
+ if (ctx->state != State_Se)
ctx->s = ctx->e;
break;
case State_Identifier:
@@ -114,9 +113,9 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
break;
case State_Probable_Boolean:
if (*ctx->e == 'f' || *ctx->e == 't')
- state = State_Boolean;
+ ctx->state = State_Boolean;
else if (*ctx->e == '\\')
- state = State_Probable_Character;
+ ctx->state = State_Probable_Character;
else {
tok.type = Error;
tok.s = "not a boolean or a character";
@@ -156,11 +155,11 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
tok.e = NULL;
return tok;
}
- state = State_Number;
+ ctx->state = State_Number;
break;
case State_Probable_Character:
if (isalpha(*ctx->e) != 0) {
- state = State_Character;
+ ctx->state = State_Character;
} else {
tok.type = Error;
tok.s = "expected character constant";
@@ -182,7 +181,7 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
break;
case State_Probable_String:
if (*ctx->e == '"')
- state = String;
+ ctx->state = String;
break;
case State_String:
tok.type = String;
@@ -212,7 +211,7 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
case State_Comment:
tmp = strchr(ctx->s, '\n');
if (tmp) {
- state = State_Se;
+ ctx->state = State_Se;
ctx->s = tmp;
}
break;
@@ -229,7 +228,6 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len)
}
ctx->e++;
}
-
tok.type = Eof;
tok.s = "reached the end-of-file";
tok.e = NULL;
@@ -241,9 +239,13 @@ initlexer(void)
{
struct lexerctx *ctx;
- ctx = calloc(1, sizeof(*ctx));
+ ctx = malloc(sizeof(*ctx));
if (!ctx)
return NULL;
+ ctx->state = State_Se;
+ ctx->ready = 0;
+ ctx->s = NULL;
+ ctx->e = NULL;
return ctx;
}
@@ -251,4 +253,5 @@ void
resetlexer(struct lexerctx *ctx)
{
ctx->ready = 0;
+ ctx->state = State_Se;
}