diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2020-02-29 14:10:25 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2020-02-29 14:10:25 +0100 |
commit | 515cb682ddd41a2815af4fa46ac7c17b6edbaa9d (patch) | |
tree | f767f4b17ca5907a562dd1a7b8f1952744d12718 | |
parent | 37303cd173fa0d19474439c011a9ebaefa0d1604 (diff) | |
download | compilertests-515cb682ddd41a2815af4fa46ac7c17b6edbaa9d.tar.gz compilertests-515cb682ddd41a2815af4fa46ac7c17b6edbaa9d.tar.bz2 |
added brakets for expressions
fixed parsing issues around identifier() - do not call it directly, always use getSym -
added support for enumerations of variables in declarations
-rw-r--r-- | ecomp-c/ec.c | 52 | ||||
-rw-r--r-- | ecomp-c/minie.ebnf | 4 | ||||
-rw-r--r-- | ecomp-c/test1.e | 5 | ||||
-rw-r--r-- | ecomp-c/tests/unknown_type.e | 2 | ||||
-rw-r--r-- | ecomp-c/tests/variable_assign_from_expression.e | 4 | ||||
-rw-r--r-- | ecomp-c/tests/variable_assign_from_expression.eout | 4 | ||||
-rw-r--r-- | ecomp-c/tests/variable_assign_from_type.eerr | 2 | ||||
-rw-r--r-- | ecomp-c/tests/variable_assign_from_variable.e | 2 |
8 files changed, 54 insertions, 21 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index c946ab2..af97bb7 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -568,6 +568,9 @@ typedef enum { S_minus, S_star, S_slash, + S_lparen, + S_rparen, + S_comma, S_eof } S_Symbol; @@ -587,6 +590,9 @@ static char *symname[S_eof+1] = { "-", "*", "/", + "(", + ")", + "," "eof" }; @@ -694,6 +700,7 @@ static void skipWhite( void ) static void number( void ) { int n = 0; + if( isDigit( look ) ) { num = look - '0'; look = getChar( ); @@ -712,6 +719,7 @@ static void number( void ) static void identifier( void ) { int n = 0; + if( isAlpha( look ) ) { ident[n] = look; n++; @@ -900,7 +908,19 @@ static S_Symbol getSym( void ) } else { s = S_slash; } - break; + break; + case '(': + look = getChar( ); + s = S_lparen; + break; + case ')': + look = getChar( ); + s = S_rparen; + break; + case ',': + look = getChar( ); + s = S_comma; + break; case EOF: s = S_eof; break; @@ -1076,6 +1096,8 @@ static void traverse_expression_tree( ExpressionNode *node ) } } +static ExpressionNode *parseExpression( void ); + static ExpressionNode *parseFactor( void ) { Symbol *symbol; @@ -1083,7 +1105,6 @@ static ExpressionNode *parseFactor( void ) node = create_expression_node( ); - /* TODO: expression tree */ if( sym == S_number ) { node->type = EXPRESSION_NODE_TYPE_CONST; node->number = num; @@ -1094,7 +1115,7 @@ static ExpressionNode *parseFactor( void ) Abort( "Unknown identifier '%s'", ident ); } if( symbol->class == SYMBOL_CLASS_TYPE ) { - Abort( "'%s' is the name for a type and not a constant as expected", ident ); + Abort( "'%s' is the name for a type and not a constant or variable as expected", ident ); } if( symbol->class == SYMBOL_CLASS_CONSTANT ) { node->type = EXPRESSION_NODE_TYPE_CONST; @@ -1105,8 +1126,12 @@ static ExpressionNode *parseFactor( void ) node->symbol = symbol; } sym = getSym( ); + } else if( sym == S_lparen ) { + sym = getSym( ); + node = parseExpression( ); + Expect( S_rparen ); } else { - Abort( "Expected an expression" ); + Abort( "Expected an literal, a variable or a constant." ); } return node; @@ -1213,14 +1238,12 @@ static void parseConstDeclaration( void ) { Symbol *constant, *type; - identifier( ); if( sym == S_begin || sym == S_var ) { return; } constant = insert_symbol( current_scope, ident, SYMBOL_CLASS_CONSTANT ); sym = getSym( ); Expect( S_colon ); - identifier( ); type = get_symbol( current_scope, ident ); if( type == NULL ) { Abort( "Unknown type '%s'", ident ); @@ -1260,14 +1283,17 @@ static void parseVariableDeclaration( void ) { Symbol *variable, *type; - identifier( ); - if( sym == S_begin ) { - return; - } - variable = insert_symbol( current_scope, ident, SYMBOL_CLASS_VARIABLE ); - sym = getSym( ); + do { + if( sym == S_begin ) { + return; + } else if( sym == S_comma ) { + sym = getSym( ); + } + variable = insert_symbol( current_scope, ident, SYMBOL_CLASS_VARIABLE ); + sym = getSym( ); + } while( sym == S_comma ); + Expect( S_colon ); - identifier( ); type = get_symbol( current_scope, ident ); if( type == NULL ) { Abort( "Unknown type '%s'", ident ); diff --git a/ecomp-c/minie.ebnf b/ecomp-c/minie.ebnf index 7e2c36b..e61f5a2 100644 --- a/ecomp-c/minie.ebnf +++ b/ecomp-c/minie.ebnf @@ -5,7 +5,7 @@ Special = "_" . Identifier = Letter { Letter | Digit | Special } . Number = Digit { Digit } . -Factor = Number | Identifier . +Factor = Number | Identifier | "(" Expression ")" . Term = Factor { ( "*" | "/" ) Factor } . Expression = Term { ( "+" | "-" ) Term } . Assignment = Identifier ":=" Expression . @@ -16,7 +16,7 @@ SimpleType = Identifier . Type = SimpleType . ConstDeclaration = Identifier ":" Type "=" Number . ConstBlock = "const" { ConstDeclaration ";" } . -VariableDeclaration = Identifier ":" Type . +VariableDeclaration = Identifier { "," Identifier } ":" Type . VariableBlock = "var" { VariableDeclaration ";" } . DeclarationBlock = ConstBlock VariableBlock . Module = "module" Identifier ";" DeclarationBlock StatementBlock . diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e index b23e4fc..454794a 100644 --- a/ecomp-c/test1.e +++ b/ecomp-c/test1.e @@ -1,6 +1,7 @@ /* * module trying to show all features of the language */ + module test1; const @@ -14,7 +15,7 @@ var // this is also an integer b : integer; c : integer; // c too - d : integer; + d, e : integer; begin a := 1; @@ -23,4 +24,6 @@ begin a := b; a := a + 1; d := a * c + b; + d := a * ( c + b ); + e := ( ( 7 * a + b ) + 2 * ( b + a + 3 ) ) * 2; end diff --git a/ecomp-c/tests/unknown_type.e b/ecomp-c/tests/unknown_type.e index 240d03e..0aa0fab 100644 --- a/ecomp-c/tests/unknown_type.e +++ b/ecomp-c/tests/unknown_type.e @@ -1,7 +1,7 @@ module unknown_type; var - a : bigint23; // must warn here about a unknown type + a : bigint23; // must warn here about an unknown type begin a := 1; diff --git a/ecomp-c/tests/variable_assign_from_expression.e b/ecomp-c/tests/variable_assign_from_expression.e index e27b1af..5fee023 100644 --- a/ecomp-c/tests/variable_assign_from_expression.e +++ b/ecomp-c/tests/variable_assign_from_expression.e @@ -12,7 +12,7 @@ var a : integer; b : integer; c : integer; - d : integer; + d, e : integer; begin a := N; @@ -22,4 +22,6 @@ begin a := b; a := a + 1; d := a * c + b; + d := a * ( c + b ); + e := ( ( 7 * a + b ) + 2 * ( b + a + 3 ) ) * 2; end diff --git a/ecomp-c/tests/variable_assign_from_expression.eout b/ecomp-c/tests/variable_assign_from_expression.eout index 7a9bf4e..f9b794b 100644 --- a/ecomp-c/tests/variable_assign_from_expression.eout +++ b/ecomp-c/tests/variable_assign_from_expression.eout @@ -2,7 +2,7 @@ CONST N -> integer, 20 DECL a -> integer DECL b -> integer DECL c -> integer -DECL d -> integer +DECL e -> integer LET a <- 20 LET b <- a LET c <- 7 @@ -10,3 +10,5 @@ LET d <- 1 LET a <- b LET a <- a 1 + LET d <- a c * b + +LET d <- a c b + * +LET e <- 7 a * b + 2 b a + 3 + * + 2 * diff --git a/ecomp-c/tests/variable_assign_from_type.eerr b/ecomp-c/tests/variable_assign_from_type.eerr index c06e0df..bc3e86a 100644 --- a/ecomp-c/tests/variable_assign_from_type.eerr +++ b/ecomp-c/tests/variable_assign_from_type.eerr @@ -1,2 +1,2 @@ -Error line 16, pos 15: 'integer' is the name for a type and not a constant as expected +Error line 16, pos 15: 'integer' is the name for a type and not a constant or variable as expected diff --git a/ecomp-c/tests/variable_assign_from_variable.e b/ecomp-c/tests/variable_assign_from_variable.e index 8576b5f..8af061b 100644 --- a/ecomp-c/tests/variable_assign_from_variable.e +++ b/ecomp-c/tests/variable_assign_from_variable.e @@ -9,7 +9,7 @@ const var a : integer; - b : integer + b : integer; begin a := N; // assign initial value to a |