BNFC / bnfc

BNF Converter
http://bnfc.digitalgrammars.com/
578 stars 163 forks source link

labels with same letters but different cases break the compilation on the c backend #479

Closed praduca closed 2 months ago

praduca commented 2 months ago

If you have labels with the same letters (like Eexp and EExp), bnfc will check and not accuse an error, but the compilation will fail with an error stating that duplicate members exist.

for instance, the following generate code and compile ok in cpp and haskell, but not in C (didn't test with others):

CalcList . CalcL ::= [Calc] ;
terminator Calc ";"         ;
Cal   .    Calc ::= Exp     ; 

EAdd  .  Exp  ::= Exp  "+"  Exp1 ;
ESub  .  Exp  ::= Exp  "-"  Exp1 ;
EMul  .  Exp1 ::= Exp1 "*"  Exp2 ;
EDiv  .  Exp1 ::= Exp1 "/"  Exp2 ;
Eexp  .  Exp2 ::= Exp2 "^"  Exp3 ;
EExp  .  Exp2 ::= Exp2 "**" Exp3 ;
EFact .  Exp3 ::= Exp4 "!"       ;
EInt  .  Exp4 ::= Integer        ;
coercions Exp 4 ;
comment "#";

Apparently the name is forced to be lowercase on the c code, but have the case preserved on the CPP backend.

andreasabel commented 2 months ago

This is also a problem in the java backends:

test/Absyn/Eexp.java:5: error: class EExp is public, should be declared in a file named EExp.java
public class EExp  extends Exp {
       ^
test/Absyn/Exp.java:12: error: cannot access Eexp
    public R visit(test.Absyn.Eexp p, A arg);
                             ^
  bad source file: ./test/Absyn/Eexp.java
    file does not contain class test.Absyn.Eexp
    Please remove or make sure it appears in the correct subdirectory of the sourcepath.
test/Absyn/Exp.java:8: error: name clash: interface Visitor has two methods with the same erasure, yet neither overrides the other
    public R visit(test.Absyn.EAdd p, A arg);
             ^
  first method:  visit(Eexp,A) in Visitor
  second method: visit(EDiv,A) in Visitor

Related:

andreasabel commented 2 months ago

I suppose we want a warning for labels that clash in case-insensitive mode, and an error for the C and Java backends. Or maybe for C we could preserve the case in field names instead.