scc

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

commit e0b2ed14ceb074d192ef69ef8a8b3104d424f0c1
parent 4e94d4039945fec694b6a74b2bcf03c5ffc71186
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  1 Jun 2012 20:18:14 +0200

Added accept and expected functions

This functions help in order to have a cleaner code. Some internal functions
of decl.c are set as static, because they are not intended for being called
from outside.

Diffstat:
Mdecl.c | 99++++++++++++++++++++++++++++++++++---------------------------------------------
Mlex.c | 17++++++++++++++++-
Mtokens.h | 4+++-
Mtypes.c | 1+
4 files changed, 63 insertions(+), 58 deletions(-)

diff --git a/decl.c b/decl.c @@ -17,20 +17,16 @@ static char symname[TOKSIZ_MAX + 1]; #include <stdio.h> /* TODO: remove this */ -void decl(void); +static void declarator(void); -void dirdcl(void) +static void dirdcl(void) { puts("dirdecl"); - if (yytoken == '(') { - gettok(); - decl(); - if (yytoken != ')') - error("expected ')'"); - gettok(); - } else if (yytoken == IDENTIFIER) { - gettok(); + if (accept('(')) { + declarator(); + expect(')'); + } else if (accept(IDENTIFIER)) { strcpy(symname, yytext); symhash = yyhash; } else { @@ -38,22 +34,22 @@ void dirdcl(void) } for (;;) { - switch (yytoken) { - case '(': + if (accept('(')) { + next(); pushtype(FTN); - if (gettok() == ')') - gettok(); + if (accept(')')) + ; /* TODO: k&r function */ else /* TODO: prototyped function */; continue; - case '[': + } else if (accept('[')) { pushtype(ARY); - if (gettok() == ']') - gettok(); + if (accept(']')) + ; /* TODO: automatic size array */ else /* TODO: specify size of array */; continue; - default: + } else { printf("leaving dirdcl %c\n", yytoken); return; } @@ -68,15 +64,15 @@ void dirdcl(void) * */ -struct type *types[][2] = {{T_VOID, NULL}, - {T_SCHAR, T_UCHAR}, - {T_SHORT, T_USHORT}, - {T_INT, T_UINT}, - {T_LONG, T_ULONG}, - {T_LLONG, T_ULLONG}, - {T_FLOAT, NULL}, - {T_DOUBLE, NULL}, - {T_LDOUBLE, NULL}}; +static struct type *types[][2] = {{T_VOID, NULL}, + {T_SCHAR, T_UCHAR}, + {T_SHORT, T_USHORT}, + {T_INT, T_UINT}, + {T_LONG, T_ULONG}, + {T_LLONG, T_ULLONG}, + {T_FLOAT, NULL}, + {T_DOUBLE, NULL}, + {T_LDOUBLE, NULL}}; #define F_VOID 0 #define F_CHAR 1 @@ -88,7 +84,7 @@ struct type *types[][2] = {{T_VOID, NULL}, #define F_DOUBLE 7 #define F_LDOUBLE 8 -struct type *specifier(void) +static struct type *specifier(void) { static char sign, sclass, tqlf, nt; struct type *t; @@ -96,8 +92,8 @@ struct type *specifier(void) repeat: t = NULL; tqlf = sign = sclass = 0; - for (;;) { - switch (gettok()) { + for (;; next()) { + switch (yytoken) { case TYPEDEF:case EXTERN:case STATIC:case AUTO:case REGISTER: if (sclass != 0) error("Two or more storage specifier"); @@ -187,16 +183,16 @@ incorrect_sign: #undef F_LDOUBLE -void decl(void) +static void declarator(void) { unsigned char qlf[PTRLEVEL_MAX], *bp, *lim; - puts("decl"); + puts("declarator"); lim = qlf + PTRLEVEL_MAX; for (bp = qlf; yytoken == '*' && bp != lim; ++bp) { *bp = 0; repeat_qlf: - switch (gettok()) { + switch (next()) { case CONST: if (!(*bp ^= 1)) goto duplicated; @@ -233,43 +229,34 @@ duplicated: error("duplicated '%s'", yytext); } - - -void declaration(void) +void decl(void) { struct type *t, *spec; - struct symbol *sym; -repeat: spec = specifier(); - - for (; ; gettok()) { - /* TODO: put here savepoint for error recovering */ - decl(); - if (yytoken != ',' && yytoken != ';') - error("unexpected", yytext); + do { + declarator(); t = decl_type(spec); - ptype(t); - - if (yytoken == ',') - continue; - else if (yytoken == ';') - goto repeat; - } + } while (accept(',')); + puts("leaving declaration"); } +void stmt(void) +{ + for (;;) { + decl(); + expect(';'); + } - - -#include <stddef.h> - +} int main(int argc, char *argv[]) { init_lex(); open_file(NULL); - declaration(); + next(); + stmt(); return 0; } diff --git a/lex.c b/lex.c @@ -120,7 +120,7 @@ static unsigned char iden(void) -unsigned char gettok(void) +unsigned char next(void) { static unsigned int c; register unsigned char ch; @@ -178,6 +178,21 @@ return_token: return yytoken = ch; } +char accept(unsigned char tok) +{ + if (yytoken == tok) { + next(); + return 1; + } + return 0; +} + +void expect(unsigned char tok) +{ + if (yytoken != tok) + error("unexpected %s", yytext); + next(); +} void open_file(const char *file) { diff --git a/tokens.h b/tokens.h @@ -47,6 +47,8 @@ extern unsigned char yytoken; extern union yyval yyval; -extern unsigned char gettok(void); extern void init_lex(void); +extern unsigned char next(void); +extern char accept(unsigned char tok); +extern void expect(unsigned char tok); #endif diff --git a/types.c b/types.c @@ -40,6 +40,7 @@ struct type *decl_type(struct type *t) { while (stackp != stack) t = mktype(t, *--stackp); + ptype(t); return t; }