summaryrefslogtreecommitdiff
path: root/minic
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-06-27 19:52:06 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2018-06-27 19:52:06 +0200
commit142df103f074479d1b732f4e729c9bedf1b20d9b (patch)
tree9ff161a2c0718e745092a57bffa56c1cc45b8709 /minic
parent9cf182c016074f46f01f88de92af2a7c66e0f4c0 (diff)
downloadcompilertests-142df103f074479d1b732f4e729c9bedf1b20d9b.tar.gz
compilertests-142df103f074479d1b732f4e729c9bedf1b20d9b.tar.bz2
can parse test3.c
Diffstat (limited to 'minic')
-rw-r--r--minic/const.h1
-rw-r--r--minic/parse.c28
-rw-r--r--minic/scan.c87
-rw-r--r--minic/scan.h11
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;