scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 69a0a3e07aee3304446942c49527d65ebc5f7c85
parent b390c994ee75e9c45616cfc91bf89d869d228310
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 22 Sep 2017 14:24:03 +0100

[as] Rewrite getargs()

Getargs() has not to do parsing anymore since this task is
done in expr() now.

Diffstat:
Mas/as.h | 2+-
Mas/expr.c | 63++++++++++++++++++++++++++++++++++++++++++++-------------------
Mas/parser.c | 24++++--------------------
3 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -112,7 +112,7 @@ extern int nextline(FILE *fp, struct line *linep); #endif /* expr.c */ -extern Node *expr(char *s); +extern Node *expr(char **s); extern void deltree(Node *np); /* diff --git a/as/expr.c b/as/expr.c @@ -175,8 +175,8 @@ iden(void) int c; char *p; - for (endp = textp+1; isalnum(c = *endp) || c == '_' || c == '.'; ++endp) - /* nothing */; + while (isalnum(c = *endp) || c == '_' || c == '.') + ++endp; tok2str(); yylval.sym = lookup(yytext); @@ -189,8 +189,8 @@ number(void) int c; char *p; - for (endp = textp+1; isxdigit(*endp); ++endp) - /* nothing */; + while (isxdigit(*endp)) + ++endp; tok2str(); yylval.sym = tmpsym(atoi(yytext)); /* TODO: parse the string */ @@ -203,8 +203,8 @@ character(void) int c; char *p; - for (endp = textp+1; *endp != '\''; ++endp) - /* nothing */; + while (*endp != '\'') + ++endp; return NUMBER; } @@ -214,31 +214,51 @@ string(void) int c; char *p; - for (endp = textp+1; *endp != '"'; ++endp) - /* nothing */; + while (*endp != '"') + ++endp; return STRING; } static int +operator(void) +{ + int c; + + ++endp; + if ((c = *textp) == '>') + c = follow('=', '>', LE, SHL, '>'); + else if (c == '<') + c = follow('=', '<', GE, SHR, '>'); + tok2str(); + + return c; +} + +static int next(void) { int c; while (isspace(*textp)) ++textp; - c = *textp; + + endp = textp; + if ((c = *textp) == '\0') { + strcpy(yytext, "EOF"); + yylen = 3; + return EOF; + } + if (isalpha(c) || c == '_' || c == '.') c = iden(); else if (isdigit(c)) c = number(); - else if (c == '>') - c = follow('=', '>', LE, SHL, '>'); - else if (c == '<') - c = follow('=', '<', GE, SHR, '>'); - else if (c == '\'') - c = character(); else if (c == '\"') c = string(); + else if (c == '\'') + c = character(); + else + c = operator(); return yytoken = c; } @@ -398,15 +418,20 @@ or(void) } Node * -expr(char *s) +expr(char **s) { Node *np; - textp = s; + if (*s == '\0') + return NULL; + + textp = *s; next(); np = or(); - if (*textp != '\0') - error("trailing characters in expression '%s'", textp); + if (yytoken != ',' && yytoken != EOF) + error("trailing characters in expression '%s:%s'", *s, textp); + *s = endp; + return np; } diff --git a/as/parser.c b/as/parser.c @@ -35,33 +35,17 @@ error(char *msg, ...) Node ** getargs(char *s) { - char *t; - int ch, len; Node **ap; static Node *args[NARGS]; if (!s) return NULL; - for (ap = args; ; *ap++ = expr(t)) { - while (isspace(*s)) - ++s; - if (*s == '\0') - break; - if (ap == &args[NARGS-1]) - error("too many arguments in one instruction"); - - for (t = s; *s && *s != ','; s++) - /* nothing */; - len = t - s; - if (*s != '\0') - *s++ = '\0'; - if (len == 0) - error("wrong operand '%s'", t); + for (ap = args; ap < &args[NARGS-1]; ++ap) { + if ((*ap = expr(&s)) == NULL) + return args; } - *ap = NULL; - - return args; + error("too many arguments in one instruction"); } static char *