diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-06-27 19:52:06 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-06-27 19:52:06 +0200 |
commit | 142df103f074479d1b732f4e729c9bedf1b20d9b (patch) | |
tree | 9ff161a2c0718e745092a57bffa56c1cc45b8709 /minic | |
parent | 9cf182c016074f46f01f88de92af2a7c66e0f4c0 (diff) | |
download | compilertests-142df103f074479d1b732f4e729c9bedf1b20d9b.tar.gz compilertests-142df103f074479d1b732f4e729c9bedf1b20d9b.tar.bz2 |
can parse test3.c
Diffstat (limited to 'minic')
-rw-r--r-- | minic/const.h | 1 | ||||
-rw-r--r-- | minic/parse.c | 28 | ||||
-rw-r--r-- | minic/scan.c | 87 | ||||
-rw-r--r-- | minic/scan.h | 11 |
4 files changed, 120 insertions, 7 deletions
diff --git a/minic/const.h b/minic/const.h index e22075e..f468e36 100644 --- a/minic/const.h +++ b/minic/const.h @@ -2,6 +2,7 @@ enum { MAX_IDENT_LEN = 15, + MAX_NUMBER_LEN = 20, MAX_TMP_LEN = 50 }; diff --git a/minic/parse.c b/minic/parse.c index d1464cd..c23a4a2 100644 --- a/minic/parse.c +++ b/minic/parse.c @@ -2,6 +2,7 @@ #include "io.h" #include "string.h" +#include "stdlib.h" void parser_init( Parser *p, Scanner *s ) { @@ -24,8 +25,10 @@ void parser_debug( Parser *p, int enable ) static void print_symbol( scanner_Symbol sym ) { char s[MAX_TMP_LEN]; + char s2[MAX_TMP_LEN]; s[0] = '\0'; + s2[0] = '\0'; switch( sym.sym ) { case S_eof: @@ -34,6 +37,12 @@ static void print_symbol( scanner_Symbol sym ) case S_INT: print( "PARSER(INT)" ); break; + case S_VOID: + print( "PARSER(VOID)" ); + break; + case S_RETURN: + print( "PARSER(RETURN)" ); + break; case S_DIV: print( "PARSER(DIV)" ); break; @@ -43,9 +52,28 @@ static void print_symbol( scanner_Symbol sym ) strcat_c( s, ')' ); print( s ); break; + case S_INT_CONST: + strcat( s, "PARSER(INT_CONST," ); + itoa( sym.data.i, s2, 10 ); + strcat( s, s2 ); + strcat_c( s, ')' ); + print( s ); + break; + case S_SEMICOLON: + print( "PARSER(SEMICOLON)" ); + break; case S_LPARENT: print( "PARSER(LPARENT)" ); break; + case S_RPARENT: + print( "PARSER(RPARENT)" ); + break; + case S_LCURL: + print( "PARSER(LCURL)" ); + break; + case S_RCURL: + print( "PARSER(RCURL)" ); + break; default: print( "PARSER(<unknown symbol>)" ); } diff --git a/minic/scan.c b/minic/scan.c index 33803a5..d008f4c 100644 --- a/minic/scan.c +++ b/minic/scan.c @@ -137,6 +137,25 @@ static scanner_Symbol parse_ident( Scanner *s ) return sym; } +static scanner_Symbol parse_number( Scanner *s ) +{ + scanner_Symbol sym; + int len = 0; + + sym.sym = S_INT_CONST; + sym.data.i = 0; + + /* TODO: unsigned, signed, overflow handling */ + while( len < MAX_NUMBER_LEN && isdigit( s->peek ) ) { + int digit = s->peek - '0'; + sym.data.i = sym.data.i * 10 + digit; + len++; + get_char( s ); + } + + return sym; +} + scanner_Symbol scanner_scan( Scanner *s ) { scanner_Symbol sym; @@ -175,25 +194,83 @@ scanner_Symbol scanner_scan( Scanner *s ) case 'n': switch( peek_char( s, 2 ) ) { case 't': - skip_char( s, 2 ); - get_char( s ); - get_char( s ); + skip_char( s, 3 ); sym.sym = S_INT; return sym; } - goto id; } - break; + goto id; + + case 'v': + switch( peek_char( s, 1 ) ) { + case 'o': + switch( peek_char( s, 2 ) ) { + case 'i': + switch( peek_char( s, 3 ) ) { + case 'd': + skip_char( s, 4 ); + sym.sym = S_VOID; + return sym; + } + } + } + goto id; + case 'r': + switch( peek_char( s, 1 ) ) { + case 'e': + switch( peek_char( s, 2 ) ) { + case 't': + switch( peek_char( s, 3 ) ) { + case 'u': + switch( peek_char( s, 4 ) ) { + case 'r': + switch( peek_char( s, 5 ) ) { + case 'n': + skip_char( s, 6 ); + sym.sym = S_RETURN; + return sym; + } + } + } + } + } + goto id; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + sym = parse_number( s ); + return sym; + id: case 'm': case 'a': case 'n': sym = parse_ident( s ); return sym; + case ';': + get_char( s ); + sym.sym = S_SEMICOLON; + return sym; + case '(': get_char( s ); sym.sym = S_LPARENT; return sym; + + case ')': + get_char( s ); + sym.sym = S_RPARENT; + return sym; + + case '{': + get_char( s ); + sym.sym = S_LCURL; + return sym; + + case '}': + get_char( s ); + sym.sym = S_RCURL; + return sym; default: unexpected_char( s, s->peek ); diff --git a/minic/scan.h b/minic/scan.h index 1a7cc79..04d0945 100644 --- a/minic/scan.h +++ b/minic/scan.h @@ -7,15 +7,22 @@ typedef enum scanner_Sym { S_eof, S_DIV, S_INT, + S_VOID, + S_RETURN, S_IDENT, - S_LPARENT + S_INT_CONST, + S_SEMICOLON, + S_LPARENT, + S_RPARENT, + S_LCURL, + S_RCURL } scanner_Sym; typedef struct scanner_Symbol { scanner_Sym sym; union { char s[MAX_IDENT_LEN]; - int n; + int i; } data; int tag; } scanner_Symbol; |