From 75b7f9b97d9fc1186f7864f46c5e5d383432cfb7 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 25 Sep 2019 19:41:36 -0400 Subject: Fix dangling else --- pc.y | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pc.y b/pc.y index a264286..8363428 100644 --- a/pc.y +++ b/pc.y @@ -81,6 +81,10 @@ extern scope *cur_scope; %type opt_statements %type proc_statement +%type ifelse +%nonassoc THEN +%nonassoc ELSE + %type var %type type %type standard_type @@ -292,9 +296,9 @@ statement { $$ = $1; } - |IF expr THEN statement ELSE statement + |ifelse { - $$ = mktree(IF, $2, mktree(THEN, $4, $6)); + $$ = $1; } |WHILE expr DO statement { @@ -321,6 +325,16 @@ statement $$ = $1; } ; +ifelse + :IF expr THEN statement + { + $$ = mktree(IF, $2, mktree(THEN, $4, NULL)); + } + |IF expr THEN statement ELSE statement + { + $$ = mktree(IF, $2, mktree(THEN, $4, $6)); + } +; TD :TO -- cgit v1.1 From 4f66397e285f7742bdf5bfd9f723e10104486ce2 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 25 Sep 2019 19:49:47 -0400 Subject: Squashed commit of the following: commit 5feabbc13a2edc8c5088f8a6163c729921f4119b Author: Tucker Evans Date: Wed Sep 25 19:48:52 2019 -0400 Update Semantic Check List after initial testing w/ Tino's tests commit d86de7957451e485c90e2354042e7e6bfb04a13f Author: Tucker Evans Date: Wed Sep 25 19:48:27 2019 -0400 Add variations to Tino's tests commit df5b9a51ce309b76e046aecfedd0960e7fa9984f Author: Tucker Evans Date: Wed Sep 25 19:12:50 2019 -0400 Add Tino's test files Files correspond to semantic check list entries --- SemanticCheckList.txt | 38 +++++++++++----------- Testing/Semantic/t1-1a.p | 7 ++++ Testing/Semantic/t1-1b.p | 16 +++++++++ Testing/Semantic/t1-2.p | 12 +++++++ Testing/Semantic/t1-2a.p | 12 +++++++ Testing/Semantic/t1-2b.p | 12 +++++++ Testing/Semantic/t1-3.p | 11 +++++++ Testing/Semantic/t1-4.p | 13 ++++++++ Testing/Semantic/t1-5.p | 11 +++++++ Testing/Semantic/t2-1.p | 10 ++++++ Testing/Semantic/t2-2.p | 6 ++++ Testing/Semantic/t2-3.p | 9 ++++++ Testing/Semantic/t3-2.p | 8 +++++ Testing/Semantic/t3-3.p | 13 ++++++++ Testing/Semantic/t3-3a.p | 13 ++++++++ Testing/Semantic/t3-4.p | 9 ++++++ Testing/Semantic/t4-1.p | 8 +++++ Testing/Semantic/t5-2.p | 8 +++++ Testing/Semantic/t5-3.p | 18 +++++++++++ Testing/Semantic/t5-4.p | 14 ++++++++ Testing/Semantic/t6-1.p | 11 +++++++ Testing/Semantic/t6-2.p | 13 ++++++++ Testing/Semantic/test-semantic.p | 70 ++++++++++++++++++++++++++++++++++++++++ 23 files changed, 324 insertions(+), 18 deletions(-) create mode 100644 Testing/Semantic/t1-1a.p create mode 100644 Testing/Semantic/t1-1b.p create mode 100644 Testing/Semantic/t1-2.p create mode 100644 Testing/Semantic/t1-2a.p create mode 100644 Testing/Semantic/t1-2b.p create mode 100644 Testing/Semantic/t1-3.p create mode 100644 Testing/Semantic/t1-4.p create mode 100644 Testing/Semantic/t1-5.p create mode 100644 Testing/Semantic/t2-1.p create mode 100644 Testing/Semantic/t2-2.p create mode 100644 Testing/Semantic/t2-3.p create mode 100644 Testing/Semantic/t3-2.p create mode 100644 Testing/Semantic/t3-3.p create mode 100644 Testing/Semantic/t3-3a.p create mode 100644 Testing/Semantic/t3-4.p create mode 100644 Testing/Semantic/t4-1.p create mode 100644 Testing/Semantic/t5-2.p create mode 100644 Testing/Semantic/t5-3.p create mode 100644 Testing/Semantic/t5-4.p create mode 100644 Testing/Semantic/t6-1.p create mode 100644 Testing/Semantic/t6-2.p create mode 100644 Testing/Semantic/test-semantic.p diff --git a/SemanticCheckList.txt b/SemanticCheckList.txt index f7fb1c7..446a442 100644 --- a/SemanticCheckList.txt +++ b/SemanticCheckList.txt @@ -4,38 +4,40 @@ DRAGON Semantic Checklist [X] 1. Semantic rules for Scoping [X] 1.1. Local objects cannot be declared more than once [X] 1.2. Local objects hide non-local objects with the same name -[X] 1.3. Non-local objects should be visible from inner scopes (unless a local object of the same name exists) -[X] 1.4. Function and procedure names exist in the scope they are defined (and not in their own scopes) +[X] 1.3. Non-local objects should be visible from inner scopes + (unless a local object of the same name exists) +[X] 1.4. Function and procedure names exist in the scope they are + defined (and not in their own scopes) [X] 1.5. Local objects cease to exist once their scopes cease to exist [X] 2. Semantic rules for Expressions [X] 2.1. Expressions return typed-values [X] 2.2. Objects must be declared before they used in expressions -[X] 2.3. Objects of different types cannot appear in the same expression (no type promotions) +[X] 2.3. Objects of different types cannot appear in the same + expression (no type promotions) [ ] 3. Semantic rules for Statements [ ] 3.1. Statements do not return values - TODO: Add check for return type on statements, parsing - statement_list? -[X] 3.2. The test expression for IF-THEN, IF-THEN-ELSE, WHILE-DO must be Boolean-valued; -[X] note that the Boolean type must be implicitly defined -[X] 3.3. The ELSE clause always binds to the closest IF (resolution of the dangling ELSE problem) -[ ] 3.4. The variable type in FOR-DO must match the types of lower bound and upper bound expressions +[ ] 3.2. The test expression for IF-THEN, IF-THEN-ELSE, WHILE-DO + must be Boolean-valued; + note that the Boolean type must be implicitly defined +[X] 3.3. The ELSE clause always binds to the closest IF (resolution + of the dangling ELSE problem) +[X] 3.4. The variable type in FOR-DO must match the types of lower bound and upper bound expressions -[ ] 4. Semantic rules for Arrays +[X] 4. Semantic rules for Arrays [X] 4.1. Non-integer valued expressions cannot be used for indexing arrays [ ] 5. Semantic rules for Functions -[X] 5.1. Function calls return values of type Integer or Real +[ ] 5.1. Function calls return values of type Integer or Real [ ] 5.2. Function must contain a "return" statement within its own body; this is of the form: := -[ ] 5.3. Functions must accept exactly the same number of arguments as is +[X] 5.3. Functions must accept exactly the same number of arguments as is declared in its header, with the correct sequence of types - TODO: Fix array types. -[X] 5.4. Functions are not allowed to update the value of nonlocal objects (via assignment statements) +[X] 5.4. Functions are not allowed to update the value of nonlocal + objects (via assignment statements) -[ ] 6. Semantic rules for Procedures -[ ] 6.1. Procedure calls do not return values -[ ] 6.2. Procedures must accept exactly the same number of arguments as is +[X] 6. Semantic rules for Procedures +[X] 6.1. Procedure calls do not return values +[X] 6.2. Procedures must accept exactly the same number of arguments as is declared in its header, with the correct sequence of types - TODO: Fix array types. diff --git a/Testing/Semantic/t1-1a.p b/Testing/Semantic/t1-1a.p new file mode 100644 index 0000000..5a6e773 --- /dev/null +++ b/Testing/Semantic/t1-1a.p @@ -0,0 +1,7 @@ +(* ERROR: variable redeclared *) +program main( input, output ); + var a,b,c: integer; + var x,y,c: real; +begin +end. + diff --git a/Testing/Semantic/t1-1b.p b/Testing/Semantic/t1-1b.p new file mode 100644 index 0000000..5a16e62 --- /dev/null +++ b/Testing/Semantic/t1-1b.p @@ -0,0 +1,16 @@ +(* ERROR: variable redeclared *) +program main( input, output ); + var a: integer; + + procedure boo; + begin + end; + + function boo(b:integer):integer; + begin + boo := 1 + end; + +begin +end. + diff --git a/Testing/Semantic/t1-2.p b/Testing/Semantic/t1-2.p new file mode 100644 index 0000000..62f2d94 --- /dev/null +++ b/Testing/Semantic/t1-2.p @@ -0,0 +1,12 @@ +(* LEGAL: local names should hide non-local names *) +program main( input, output ); + var a,b: integer; + procedure boo(a: integer); + var b: real; + begin + b := 1.23 + end; +begin + boo(b) +end. + diff --git a/Testing/Semantic/t1-2a.p b/Testing/Semantic/t1-2a.p new file mode 100644 index 0000000..62f2d94 --- /dev/null +++ b/Testing/Semantic/t1-2a.p @@ -0,0 +1,12 @@ +(* LEGAL: local names should hide non-local names *) +program main( input, output ); + var a,b: integer; + procedure boo(a: integer); + var b: real; + begin + b := 1.23 + end; +begin + boo(b) +end. + diff --git a/Testing/Semantic/t1-2b.p b/Testing/Semantic/t1-2b.p new file mode 100644 index 0000000..fd32c49 --- /dev/null +++ b/Testing/Semantic/t1-2b.p @@ -0,0 +1,12 @@ +(* LEGAL: local names should hide non-local names *) +program main( input, output ); + var a,b: integer; + procedure boo(a: integer); + var b: real; + begin + b := 1 + end; +begin + boo(b) +end. + diff --git a/Testing/Semantic/t1-3.p b/Testing/Semantic/t1-3.p new file mode 100644 index 0000000..a224b22 --- /dev/null +++ b/Testing/Semantic/t1-3.p @@ -0,0 +1,11 @@ +(* LEGAL: non-local names visible from inner scopes *) +program main( input, output ); + var a: integer; + procedure boo(x: integer); + begin + a := x + end; +begin + boo(a) +end. + diff --git a/Testing/Semantic/t1-4.p b/Testing/Semantic/t1-4.p new file mode 100644 index 0000000..420bdcb --- /dev/null +++ b/Testing/Semantic/t1-4.p @@ -0,0 +1,13 @@ +(* LEGAL: scope of the name of subprograms *) +program main( input, output ); + procedure boo; + procedure foo; + begin + end; + begin + foo + end; +begin + boo +end. + diff --git a/Testing/Semantic/t1-5.p b/Testing/Semantic/t1-5.p new file mode 100644 index 0000000..d2341d7 --- /dev/null +++ b/Testing/Semantic/t1-5.p @@ -0,0 +1,11 @@ +(* ERROR: local objects not defined outside their scopes *) +program main( input, output ); + var a: integer; + procedure boo(a: integer); + var x: integer; + begin + end; +begin + a := x +end. + diff --git a/Testing/Semantic/t2-1.p b/Testing/Semantic/t2-1.p new file mode 100644 index 0000000..295fe4b --- /dev/null +++ b/Testing/Semantic/t2-1.p @@ -0,0 +1,10 @@ +(* expression must return a typed-value *) +program main(input,output); + var a,b,c: integer; + var x,y,z: real; +begin + a := b + c; + x := y + z; + a := x +end. + diff --git a/Testing/Semantic/t2-2.p b/Testing/Semantic/t2-2.p new file mode 100644 index 0000000..efb455b --- /dev/null +++ b/Testing/Semantic/t2-2.p @@ -0,0 +1,6 @@ +(* ERROR: objects must be declared before used in expressions *) +program main( input, output ); +begin + a := 1 +end. + diff --git a/Testing/Semantic/t2-3.p b/Testing/Semantic/t2-3.p new file mode 100644 index 0000000..806c575 --- /dev/null +++ b/Testing/Semantic/t2-3.p @@ -0,0 +1,9 @@ +(* ERROR: objects of different types appear in the same expression *) +program main( input, output ); + var a: integer; + var x: real; +begin + a := a + 1.23; + x := x + 123 +end. + diff --git a/Testing/Semantic/t3-2.p b/Testing/Semantic/t3-2.p new file mode 100644 index 0000000..22f9b47 --- /dev/null +++ b/Testing/Semantic/t3-2.p @@ -0,0 +1,8 @@ +(* ERROR: test expressions in IF/WHILE statements must be Boolean *) +program main( input, output ); + var a: integer; +begin + while a + 123 do + a := a + 1 +end. + diff --git a/Testing/Semantic/t3-3.p b/Testing/Semantic/t3-3.p new file mode 100644 index 0000000..32b5e59 --- /dev/null +++ b/Testing/Semantic/t3-3.p @@ -0,0 +1,13 @@ +(* dangling ELSE binds to closest IF *) +program main( input, output ); + var a: integer; +begin + read(a); + if ( a < 10 ) then + if ( a >= 10 ) then + a := 1 + else + a := 0; + write(a) +end. + diff --git a/Testing/Semantic/t3-3a.p b/Testing/Semantic/t3-3a.p new file mode 100644 index 0000000..45d92f1 --- /dev/null +++ b/Testing/Semantic/t3-3a.p @@ -0,0 +1,13 @@ +(* dangling ELSE binds to closest IF *) +program main( input, output ); + var a: integer; +begin + a := 5; + if ( a < 10 ) then + if ( a >= 10 ) then + a := 1 + else + a := 0; +a:=2 +end. + diff --git a/Testing/Semantic/t3-4.p b/Testing/Semantic/t3-4.p new file mode 100644 index 0000000..73dc520 --- /dev/null +++ b/Testing/Semantic/t3-4.p @@ -0,0 +1,9 @@ +(* ERROR: mismatched type for index variable in FOR loops *) +program main( input, output ); + var a: integer; + var x: real; +begin + for x := 1 to 5 do + a := a + 1 +end. + diff --git a/Testing/Semantic/t4-1.p b/Testing/Semantic/t4-1.p new file mode 100644 index 0000000..2f24e8c --- /dev/null +++ b/Testing/Semantic/t4-1.p @@ -0,0 +1,8 @@ +(* ERROR: non-integer type for array index *) +program main( input, output ); + var a: array[3 .. 7] of real; + var x: real; +begin + a[x] := 1.23 +end. + diff --git a/Testing/Semantic/t5-2.p b/Testing/Semantic/t5-2.p new file mode 100644 index 0000000..2b9cde3 --- /dev/null +++ b/Testing/Semantic/t5-2.p @@ -0,0 +1,8 @@ +(* ERROR: function missing return statement *) +program main( input, output ); + function foo(a: integer): integer; + begin + end; +begin +end. + diff --git a/Testing/Semantic/t5-3.p b/Testing/Semantic/t5-3.p new file mode 100644 index 0000000..6494ae0 --- /dev/null +++ b/Testing/Semantic/t5-3.p @@ -0,0 +1,18 @@ +(* ERROR: function passed wrong number/type of arguments *) +program main( input, output ); + var b: integer; + var y: real; + var a: array[1 .. 13] of integer; + var z: array[1 .. 13] of real; + + function foo(a: integer; x: real): integer; + begin + foo := a + end; +begin + b := foo(y,b) + foo(b,y,10) +end. + + + + diff --git a/Testing/Semantic/t5-4.p b/Testing/Semantic/t5-4.p new file mode 100644 index 0000000..840625a --- /dev/null +++ b/Testing/Semantic/t5-4.p @@ -0,0 +1,14 @@ +(* ERROR: function updating non-local variable *) +program main( input, output ); + var a: integer; + + function foo(b: integer): integer; + begin + foo := a; + a := b + end; + +begin + +end. + diff --git a/Testing/Semantic/t6-1.p b/Testing/Semantic/t6-1.p new file mode 100644 index 0000000..9669168 --- /dev/null +++ b/Testing/Semantic/t6-1.p @@ -0,0 +1,11 @@ +(* ERROR: procedures don't return values *) +program main( input, output ); + var a: integer; + procedure boo(b: integer); + begin + a := 1 + end; +begin + a := boo(a) +end. + diff --git a/Testing/Semantic/t6-2.p b/Testing/Semantic/t6-2.p new file mode 100644 index 0000000..3eabfac --- /dev/null +++ b/Testing/Semantic/t6-2.p @@ -0,0 +1,13 @@ +(* ERROR: procedure passed wrong number/type of arguments *) +program main( input, output ); + var b: integer; + var y: real; + + procedure boo(a: integer; x: real); + begin + end; +begin + boo(y,10); + boo(b,y,b) +end. + diff --git a/Testing/Semantic/test-semantic.p b/Testing/Semantic/test-semantic.p new file mode 100644 index 0000000..2cb9b8a --- /dev/null +++ b/Testing/Semantic/test-semantic.p @@ -0,0 +1,70 @@ + +program main( input, output ); + + (* local variables *) + var x, y: integer; + var a, b: real; + var c: array[ 1..10 ] of integer; + var d: array[ 11..20 ] of real; + + (* local function: mixed argument types *) + function foo( a: integer; x: real; z: integer ): integer; + procedure boo( a: real ); + begin + (* scope check on boo's a, main's b, d[] and y; and foo's z*) + boo( a * b + d[y + z] ) + end; + begin + (* boo is visible; so is main's b *) + boo( b ); + + (* function return statement; scope and type check on foo's a and main's y *) + foo := a + y + end; + + (* local procedure *) + procedure bar( c: integer ); + begin + (* nonlocal update *) + d[ c[foo(x,a,y)] ] := b + end; + + (* location function: recursive *) + function moo( d: integer ): integer; + begin + if ( d = 0 ) then + moo := 1 + else + moo := d * moo( d - 1 ) + end; + +begin + + (* FUNCTION call check: recursive and correct arguments *) + y := foo( x + foo( y, 0.001, a ) * 1, 2.3, b ); + + (* ARRAY access check: recursive, correct arguments *) + y := c[ x + c[y] * 45 ]; + + (* FUNCTION call and ARRAY access *) + y := foo( x + c[y + foo(c[1], d[2], a)] * 1, 2.3 + d[c[foo(c[3],b,d[y])]] ); + + (* IF-THEN check *) + if ( c[x] * 6 < 7 + moo( y ) and a > d[c[x]] ) then + begin + c[moo(foo(8,9.10,11.0)) + c[12]] := moo( c[y - 1] ) + end; + + (* PROCEDURE call: correct arguments, not used as expression *) + bar( c[x] ); + + (* FOR check *) + b := 10.0; + for a := 1.0 to 2.0 * b do + begin + bar( c[x + moo( c[x + moo( c[x + moo(1)] )] )] ); + a := a + 0.0000001 + end + +end. + -- cgit v1.1