usethesource / rascal

The implementation of the Rascal meta-programming language (including interpreter, type checker, parser generator, compiler and JVM based run-time system)
http://www.rascal-mpl.org
Other
397 stars 79 forks source link

Insufficient diagnostics for syntax errors #845

Open HubertGaravel opened 8 years ago

HubertGaravel commented 8 years ago

Hi,

The two Rascal programs below do not compile but the error messages given are insufficient to detect the reason of the errors. In particular, the number of the lines on which the errors occur are not given.

*\ For example 1 (hanoi.rsc) Version: 0.7.2.201506052258 Static Error: Could not import module hanoi: Parse error Advice org.rascalmpl.interpreter.staticErrors.ModuleImport: Could not import module hanoi: Parse error Advice at .?(/:1) at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:326) at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:238) at org.rascalmpl.interpreter.Evaluator.doImport(Evaluator.java:1192) at org.rascalmpl.shell.RascalShell.runModule(RascalShell.java:282) at org.rascalmpl.shell.RascalShell.main(RascalShell.java:199)

*\ For example 2 (sieve.rsc)

Version: 0.7.2.201506052258 Static Error: Could not import module sieve: Parse error Advice org.rascalmpl.interpreter.staticErrors.ModuleImport: Could not import module sieve: Parse error Advice at .?(/:1) at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:326) at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:238) at org.rascalmpl.interpreter.Evaluator.doImport(Evaluator.java:1192) at org.rascalmpl.shell.RascalShell.runModule(RascalShell.java:282) at org.rascalmpl.shell.RascalShell.main(RascalShell.java:199)

Two questions: a) Is there a means to have more informative error messages? b) What is the reason of the errors and how to correct the code to make it valid?


module hanoi import IO;

data Disk = D0() | D1() | D2() | D3() | D4() | D5() | D6() | D7() | D8() | D9() | D10() | D11() | D12() | D13() | D14() | D15() | D16();

data Tower = A() | B() | C();

data Move = Movedisk (Disk x1, Tower x2, Tower x3);

data List = Nil() | Cons (Move x1, List x2);

Disk dec (D16()) { return D15(); } Disk dec (D15()) { return D14(); } Disk dec (D14()) { return D13(); } Disk dec (D13()) { return D12(); } Disk dec (D12()) { return D11(); } Disk dec (D11()) { return D10(); } Disk dec (D10()) { return D9(); } Disk dec (D9()) { return D8(); } Disk dec (D8()) { return D7(); } Disk dec (D7()) { return D6(); } Disk dec (D6()) { return D5(); } Disk dec (D5()) { return D4(); } Disk dec (D4()) { return D3(); } Disk dec (D3()) { return D2(); } Disk dec (D2()) { return D1(); } Disk dec (D1()) { return D0(); }

Tower other (A(), B()) { return C(); } Tower other (B(), A()) { return C(); } Tower other (A(), C()) { return B(); } Tower other (C(), A()) { return B(); } Tower other (B(), C()) { return A(); } Tower other (C(), B()) { return A(); }

List conc (Nil(), List l) { return l; } List conc (List l, Nil()) { return l; } List conc (Cons (Move h, List t), List l) { return Cons (h, conc (t, l)); }

List solve (Tower oRG, Tower dEST, D0()) { return Nil(); } List solve (Tower oRG, Tower dEST, Disk d) { if (d != D0()) return conc (solve (oRG, other (oRG, dEST), dec (d)), Cons (Movedisk (d, oRG, dEST), solve (other (oRG, dEST), dEST, dec (d)))); else fail; }

void main([]) { println (solve (A(), B(), D4())); }


module sieve import IO;

data Bool = True() | False();

data Nat = S (Nat x1) | Z();

data Digit = D0() | D1() | D2() | D3() | D4() | D5() | D6() | D7() | D8() | D9();

data List = Nil() | D (Digit x1) | Dl (Digit x1, List x2) | L (Nat x1, List x2) | Ll (List x1, List x2);

List ifList (True(), List l1, List l2) { return l1; } List ifList (False(), List l1, List l2) { return l2; }

Nat ifNat (True(), Nat n, Nat m) { return n; } Nat ifNat (False(), Nat n, Nat m) { return m; }

List conv (Nat x) { return ifList (lt (x, ten()), Dl (digit (x), Nil()), ap (conv (div (x, ten())), conv (rem (x, ten())))); }

Nat rem (Nat x, Nat y) { return ifNat (lt (x, y), x, rem (sub (x, y), y)); }

Nat div (Nat x, Nat y) { return ifNat (lt (x, y), Z(), S (div (sub (x, y), y))); }

Nat ten() { return S (S (S (S (S (S (S (S (S (S (Z())))))))))); }

Bool lt (Z(), S (Nat x)) { return True(); } Bool lt (Nat x, Z()) { return False(); } Bool lt (S (Nat x), S (Nat y)) { return lt (x, y); }

Nat sub (Z(), Nat x) { return Z(); } Nat sub (Nat x, Z()) { return x; } Nat sub (S (Nat x), S (Nat y)) { return sub (x, y); }

Digit digit (Nat x) { return find (digitList(), x); }

List digitList() { return Dl (D0(), Dl (D1(), Dl (D2(), Dl (D3(), Dl (D4(), Dl (D5(), Dl (D6(), Dl (D7(), Dl (D8(), Dl (D9(), Nil())))))))))); }

Digit find (Dl (Digit dig, List l1), Z()) { return dig; } Digit find (Dl (Digit dig, List l1), S (Nat x)) { return find (l1, x); }

List ap (Nil(), List l1) { return l1; } List ap (Dl (Digit dig, List l1), List l2) { return Dl (dig, ap (l1, l2)); }

Nat add (Z(), Nat y) { return y; } Nat add (S (Nat x), Nat y) { return S (add (x, y)); }

Nat mult (Z(), Nat y) { return Z(); } Nat mult (S (Nat x), Nat y) { return add (y, mult (x, y)); }

Nat fact (Z()) { return S (Z()); } Nat fact (S (Nat x)) { return mult (S (x), fact (x)); }

Bool divides (Nat n, Nat m) { return auxdiv (n, m, m); }

Bool auxdiv (Z(), Z(), Nat m) { return True(); } Bool auxdiv (Z(), S (Nat x), Nat m) { return False(); } Bool auxdiv (S (Nat x), S (Nat y), Nat m) { return auxdiv (x, y, m); } Bool auxdiv (S (Nat x), Z(), Nat m) { return auxdiv (S (x), m, m); }

List intsFrom (Nat n) { return L (n, intsFrom (S (n))); }

List sieve (L (Nat n, List l1)) { return L (n, sieve (filter (l1, n))); }

List filter (L (Nat n, List l1), Nat m) { return ifList (divides (n, m), filter (l1, m), L (n, filter (l1, m))); }

List force (List l1, Z()) { return Nil(); } List force (L (Nat n, List l1), S (Nat m)) { return e (n, force (l1, m)); }

List e (Nat n, List l1) { return Ll (conv (n), l1); }

void main([]) { println (force (sieve (intsFrom (S (S (Z())))), S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (Z())))))))))))))))))))))); println (force (sieve (intsFrom (S (S (Z())))), mult (ten(), ten()))); println (force (sieve (intsFrom (S (S (Z())))), mult (ten(), mult (ten(), ten())))); }

jurgenvinju commented 8 years ago

answer 0: yes, agreed. We need to quickly fix the error message!

a) use the Eclipse editor which will put the squiqly at the first error message b) the "solve" identifier is reserved for the solve statement, you might use another name or escape this one as in \solve

jurgenvinju commented 8 years ago

BTW this code looks like its from a term rewriting competition :-) how refreshing.

jurgenvinju commented 8 years ago

The b answer for sieve is that the "filter" identifier is a keyword to in Rascal.

jurgenvinju commented 8 years ago

PS you could write Bool lt (Z(), S (Nat x)) = True(); instead of Bool lt (Z(), S (Nat x)) { return True(); }

HubertGaravel commented 8 years ago

Hi Jurgen, Thanks for the quick answers. This is some feedback.

Best, Hubert

PaulKlint commented 8 years ago

Hi Hubert, interesting project. We are definitely interested in using your generated Rascal code for benchmarking the compiler!