BNFC / bnfc

BNF Converter
http://bnfc.digitalgrammars.com/
588 stars 165 forks source link

BNFC generates non-usable Haskell code (TestFoo.hs) #114

Closed dramforever closed 10 years ago

dramforever commented 10 years ago

The following LBNF generates bad haskell code with a few weird p[Expr]s.

comment "//";
comment "/*" "*/";

separator Expr ",";
coercions Expr 3;

ExprAdd.        Expr            ::= Expr  "+" Expr1;
ExprSub.        Expr            ::= Expr  "-" Expr1;
ExprMul.        Expr1           ::= Expr1 "*" Expr2;
ExprDiv.        Expr1           ::= Expr1 "/" Expr2;
ExprPow.        Expr2           ::= Expr3 "^" Expr2;
ExprInt.        Expr3           ::= Integer;
ExprDouble.     Expr3           ::= Double;
ExprVarRef.     Expr3           ::= Ident;
ExprFunCall.    Expr3           ::= Ident "(" [Expr] ")";

separator Statement ";";

StmtExpr.       Statement       ::= Expr;

separator VarMaybeInit ",";

VarInit.        VarMaybeInit    ::= Ident "=" Expr;
VarNoInit.      VarMaybeInit    ::= Ident;

HasGlobals.     Globals         ::= "globals" [VarMaybeInit] ";";
NoGlobals.      Globals         ::= ;

separator Ident ",";

HasExterns.     Externs         ::= "externs" [Ident];
NoExterns.      Externs         ::= ;

separator Function "";

FuncWithLocals. Function        ::=
    "function" Ident "(" [VarMaybeInit] ")"
        "locals" [VarMaybeInit]
    "do"
        [Statement]
    "end";

FuncNoLocals.   Function        ::=
    "function" Ident "(" [VarMaybeInit] ")" "do"
        [Statement]
    "end";

MkMain.         Main            ::=
    "main"
        [Statement]
    "end";

MkProgram.      Program         ::= Globals Externs [Function] Main

main in generated TestFoo.hs

main :: IO ()
main = do args <- getArgs
          case args of
            [] -> hGetContents stdin >>= run 2 p[Expr]
            "-s":fs -> mapM_ (runFile 0 p[Expr]) fs
            fs -> mapM_ (runFile 2 p[Expr]) fs

As you can see, the p[Expr] is breaking the program.

dramforever commented 10 years ago

I'm new to bnfc, so tell me if I'm using it wrong

dramforever commented 10 years ago

I'm beginning to understand it. BNFC is trying to start parsing Foo by calling pFoo. However, the Foo here is [Expr], so it's invalid. I still think this is a bug, nevertheless.

gdetrez commented 10 years ago

Unless told otherwise (using the entrypoints pragma) the test program will try to parse using the first category defined in your grammar (in your case, the first category is [Expr]).

Using a list category as an entry point is not supported in the current version. But I don't really see an immediate reason why that is, so it should probably be fixed.

A quick workaround is to create a dummy category to be the root of your abstract syntax tree. I.e. put this at the top of your grammar:

Foo. Bar ::= [Expr];
dramforever commented 10 years ago

Thanks for that. :smiley_cat:

gdetrez commented 10 years ago

Varsågod!