diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-09-29 21:29:28 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-09-29 21:29:28 +0200 |
commit | 9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1 (patch) | |
tree | b5529b1d06d797ed31e16a5b3e6558ebc77659e0 /minie | |
parent | 0edac98af9ced6ae42059f2989a5fe4bd4c75d27 (diff) | |
download | compilertests-9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1.tar.gz compilertests-9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1.tar.bz2 |
more work on parameter lists, added string parser
Diffstat (limited to 'minie')
-rw-r--r-- | minie/README | 2 | ||||
-rw-r--r-- | minie/e2c.c | 123 |
2 files changed, 108 insertions, 17 deletions
diff --git a/minie/README b/minie/README index 28cae32..384afaf 100644 --- a/minie/README +++ b/minie/README @@ -6,4 +6,4 @@ gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c ./e2c < test4.e > test4.c && gcc -o test4 test4.c && ./test4 - +./e2c < ec.e diff --git a/minie/e2c.c b/minie/e2c.c index 869c65c..d2274bf 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -2,27 +2,31 @@ #include <string.h> #include <stdlib.h> #include <stdarg.h> +#include <assert.h> enum { MAX_IDENT_LEN = 16, MAX_NUMBER_LEN = 9, - MAX_ERRMSG_LEN = 64 + MAX_ERRMSG_LEN = 64, + MAX_STRING_LEN = 64 }; static int look; static int row; static int col; +static int num; +static char str[MAX_STRING_LEN+1]; static char ident[MAX_IDENT_LEN+1]; static char moduleName[MAX_IDENT_LEN+1]; static char varName[MAX_IDENT_LEN+1]; static char typeName[MAX_IDENT_LEN+1]; static char procName[MAX_IDENT_LEN+1]; -static int num; typedef enum { S_char = 0, S_ident, S_number, + S_string, S_module, S_begin, S_end, @@ -32,6 +36,7 @@ typedef enum { S_if, S_do, S_else, + S_dot, S_comma, S_semicolon, S_colon, @@ -49,6 +54,7 @@ char *symname[S_eof+1] = { "char", "ident", "nunber", + "string", "module", "begin", "end", @@ -58,6 +64,7 @@ char *symname[S_eof+1] = { "if", "do", "else", + ".", ",", ";", ":", @@ -126,6 +133,22 @@ static int isDigit( int c ) return 0; } +static int isCharacter( int c ) +{ + if( isAlpha( c ) ) return 1; + if( isDigit( c ) ) return 1; + switch( c ) { + case ' ': + case '[': + case ']': + /* TODO: allow more characters as we go along */ + return 1; + default: + return 0; + } + return 0; +} + static void skipWhite( void ) { while( isWhite( look ) ) { @@ -133,7 +156,7 @@ static void skipWhite( void ) } } -static void identifier( ) +static void identifier( void ) { int n = 0; if( isAlpha( look ) ) { @@ -147,13 +170,13 @@ static void identifier( ) } ident[n] = '\0'; if( n == MAX_IDENT_LEN ) { - Abort( "Identifier exceeded maximal length" ); + Abort( "Identifier exceeds maximal length" ); } sym = S_ident; } } -static void number( ) +static void number( void ) { int n = 0; if( isDigit( look ) ) { @@ -171,10 +194,34 @@ static void number( ) } } -static Symbol getSym( ) +static void string( void ) +{ + int n = 0; + look = getChar( ); + while( look != '"' && isCharacter( look ) && n < MAX_STRING_LEN ) { + str[n] = look; + n++; + look = getChar( ); + } + str[n] = '\0'; + if( n == MAX_STRING_LEN ) { + Abort( "String constant exceeds maximal length" ); + } + if( look != '"' ) { + Abort( "Unterminated string or illegal character in string" ); + } + sym = S_string; + assert( look == '"' ); + look = getChar( ); +} + + +static Symbol getSym( void ) { skipWhite( ); + num = 0; ident[0] = '\0'; + str[0] = '\0'; switch( look ) { case '0': case '1': @@ -283,6 +330,9 @@ static Symbol getSym( ) case 'Z': identifier( ); return S_ident; + case '"': + string( ); + return S_string; case ':': look = getChar( ); if( look == '=' ) { @@ -293,6 +343,9 @@ static Symbol getSym( ) case ';': look = getChar( ); return S_semicolon; + case '.': + look = getChar( ); + return S_dot; case ',': look = getChar( ); return S_comma; @@ -370,6 +423,26 @@ static void epilogue( void ) emitLn( "}" ); } +static void qualident( void ) +{ + identifier( ); + if( sym == S_ident ) { + strncpy( varName, ident, MAX_IDENT_LEN ); + varName[MAX_IDENT_LEN-1] = '\0'; + } + sym = getSym( ); + if( sym == S_dot ) { + sym = getSym( ); + if( sym == S_ident ) { + strncat( varName, ".", MAX_IDENT_LEN ); + varName[MAX_IDENT_LEN-1] = '\0'; + strncat( varName, ident, MAX_IDENT_LEN ); + varName[MAX_IDENT_LEN-1] = '\0'; + sym = getSym( ); + } + } +} + static void variableName( void ) { identifier( ); @@ -392,6 +465,9 @@ static void factor( void ) if( sym == S_number ) { emit( "%d", num ); sym = getSym( ); + } else if( sym == S_string ) { + emit( "\"%s\"", str ); + sym = getSym( ); } else if( sym == S_ident ) { /* TODO: hacky */ if( strcmp( ident, "true" ) == 0 ) { @@ -437,9 +513,7 @@ static void expression( void ) static void assignment( void ) { - /* qualident is variableName( ) and has been read already */ - variableName( ); - sym = getSym( ); + /* precondition: ident is a variable and already parsed */ Expect( S_assign ); emit( "%s = ", varName ); expression( ); @@ -479,6 +553,23 @@ static void doIf( void ) emitLn( "}" ); } +static void parameterList( void ) +{ + Expect( S_lparen ); + if( sym == S_rparen ) { + return; + } + /* TODO: no VAR parameters, strictly pass-by-value */ + expression( ); + sym = getSym( ); + while( sym == S_comma ) { + sym = getSym( ); + /* TODO: no VAR parameters, strictly pass-by-value */ + expression( ); + } + Expect( S_rparen ); +} + static void statement( void ) { if( sym == S_if ) { @@ -488,17 +579,17 @@ static void statement( void ) } else if( sym == S_end || sym == S_else ) { return; } else if( sym == S_ident ) { - assignment( ); + qualident( ); + if( sym == S_lparen ) { + parameterList( ); + /* TODO: procedure call */ + } else { + assignment( ); + } } else { Abort( "Illegal statement" ); } } -/* -QualifiedIdentifier = Identifier [ "." Identifier ]; -ParameterList = "(" ")" . -ProdecureCall = QualifiedIdentifier ParameterList . -Statement = Assignment | IfStatement | ProcedureCall . -*/ static void statementSequence( void ) { |