BNFC / bnfc

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

experimental os x package - bug #107

Closed andrewbutterfield closed 10 years ago

andrewbutterfield commented 10 years ago

I tried the experimental os x package - it installed fine, in /usr/bin

I ran /usr/bin/bnfc -m -p Formal.PML PML.cf I then used ghci to compile the TestPML.hs I get the following error log:

$ ghci TestPML.hs GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. [1 of 7] Compiling Formal.PML.ErrM ( /Users/andrewbutterfield/hlib/Formal/PML/ErrM.hs, interpreted )

/Users/andrewbutterfield/hlib/Formal/PML/ErrM.hs:14:10: Warning: ‘Err’ is an instance of Monad but not Applicative - this will become an error in GHC 7.10, under the Applicative-Monad Proposal.

/Users/andrewbutterfield/hlib/Formal/PML/ErrM.hs:23:10: Warning: ‘Err’ is an instance of MonadPlus but not Alternative - this will become an error in GHC 7.10, under the Applicative-Monad Proposal. [2 of 7] Compiling Formal.PML.AbsPML ( /Users/andrewbutterfield/hlib/Formal/PML/AbsPML.hs, interpreted ) [3 of 7] Compiling Formal.PML.PrintPML ( /Users/andrewbutterfield/hlib/Formal/PML/PrintPML.hs, interpreted ) [4 of 7] Compiling Formal.PML.SkelPML ( /Users/andrewbutterfield/hlib/Formal/PML/SkelPML.hs, interpreted ) [5 of 7] Compiling Formal.PML.LexPML ( /Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs, interpreted )

/Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs:324:29: Couldn't match expected type ‘Bool’ with actual type ‘Int#’ In the first argument of ‘(&&)’, namely ‘(offset >=# 0#)’ In the expression: (offset >=# 0#) && (check ==# ord_c) In the expression: if (offset >=# 0#) && (check ==# ord_c) then alexIndexInt16OffAddr alex_table offset else alexIndexInt16OffAddr alex_deflt s

/Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs:324:48: Couldn't match expected type ‘Bool’ with actual type ‘Int#’ In the second argument of ‘(&&)’, namely ‘(check ==# ord_c)’ In the expression: (offset >=# 0#) && (check ==# ord_c) In the expression: if (offset >=# 0#) && (check ==# ord_c) then alexIndexInt16OffAddr alex_table offset else alexIndexInt16OffAddr alex_deflt s Failed, modules loaded: Formal.PML.SkelPML, Formal.PML.PrintPML, Formal.PML.AbsPML, Formal.PML.ErrM. *Formal.PML.SkelPML>

Contents of PML.cf - rest of this message:

{- ====================================================================== PML Grammar in LBNF format

Andrew Butterfield, 2013

Based on the files scanner.l parser.y from the PML parser by John Noll. ====================================================================== -}

entrypoints PROCESS ;

{- ==== LEXICAL MATTERS ============================================== -}

{- scanner.l ------------------------------------------------------------ integer [0-9]+ fraction .[0-9]+ exponent [eE][+-]?[0-9]+ identifier [a-zA-Z][a-zA-Z0-9] string \"[^"]\"

{string} {intern ( ); return STRING;} {integer}{fraction}?{exponent}? {intern ( ); return NUMBER;} {fraction}{exponent}? {intern ( ); return NUMBER;} {identifier} {intern ( ); return ID;}

In LBNF there are similar: Integer, Double, Ident, String. However LBNF Ident allows "'", and LBNF Double does not allow "E" or "+" in exponents. So, we roll our own.... ---------------------------------------------------------------------- -}

token STRING '"' (char - ["\""])* '"' ;

token ID (letter|'') (letter|digit|'')* ;

token NUMBER ( ((digit+) ('.' (digit+))?) | ('.' (digit+)) ) (('e' | 'E') ('+'|'-')? digit+)? ;

{- scanner.l ------------------------------------------------------------ "action" {return ACTION;} "agent" {return AGENT;} "branch" {return BRANCH;} "executable" {return EXECUTABLE;} "iteration" {return ITERATION;} "manual" {return MANUAL;} "process" {return PROCESS;} "provides" {return PROVIDES;} "requires" {return REQUIRES;} "script" {return SCRIPT;} "selection" {return SELECTION;} "select" {return SELECTION;} /* $jn: added for onr models. / "sequence" {return SEQUENCE;} "task" {return SEQUENCE;} / $jn: added for onr models. */ "tool" {return TOOL;} We don't implement these in LBNF - create spurious Haskell data decls. ---------------------------------------------------------------------- -}

{- scanner.l ------------------------------------------------------------ "&&" {return AND;} "||" {return OR;} "<=" {return LE;} ">=" {return GE;} "==" {return EQ;} "!=" {return NE;} "<" {return LT;} ">" {return GT;} "!" {return NOT;} "." {return DOT;} We don't implement these in LBNF - create spurious Haskell data decls. ---------------------------------------------------------------------- -}

{- scanner.l ------------------------------------------------------------ \n {lineno ++;} [ \t\r]+ {/* ignore /} . {return yytext;} These come out in the wash with LBNF defaults ---------------------------------------------------------------------- -}

{- scanner.l ------------------------------------------------------------ "/" {comment ( );} /***

{- ==== GRAMMATICAL MATTERS ========================================== -}

{- parser.y ------------------------------------------------------------- process : process_header '{' sequential_primitive_list '}' { if ($3 != NULL) GraphInsert ($1, $3); else NodeLink ($1 -> source, $1 -> sink);

    program = $1;
}
;

process_header : PROCESS ID { Node source = NodeCreate ($2, PROCESS, lineno); Node sink = NodeCreate ($2, PROCESS, lineno); $$ = GraphCreate (source, sink); } ; We merge the two. ---------------------------------------------------------------------- -} Process. PROCESS ::= "process" ID "{" [PRIM] "}" ;

{- parser.y ------------------------------------------------------------- concurrent_primitive_list : concurrent_primitive_list primitive { if ($2 != NULL) GraphInsert ($1, $2); }

| /* empty */
{
    $$ = $<graph>-1;
}
;

sequential_primitive_list : sequential_primitive_list primitive { if ($1 == NULL) $$ = $2; else if ($2 != NULL) GraphLink ($1, $2); }

| /* empty */
{
    $$ = NULL;
}
;

As we only generate abstract syntax at parsing stage (and leave semantic analysis for a later phase), we blur this distinction. ---------------------------------------------------------------------- -} []. [PRIM] ::= ; (:). [PRIM] ::= PRIM [PRIM] ;

{- parser.y ------------------------------------------------------------- primitive : branch_primitive | selection_primitive | iteration_primitive | sequence_primitive | action_primitive ; We fuse with the variants below

branch_primitive : branch_header '{' concurrent_primitive_list '}' { if ($3 == NULL) NodeLink ($1 -> source, $1 -> sink); } ; branch_header : BRANCH optional_name { Node source = NodeCreate ($2, BRANCH, lineno); Node sink = NodeCreate ($2, RENDEZVOUS, lineno); $$ = GraphCreate (source, sink); } ; We fuse these. ---------------------------------------------------------------------- -} PrimBr. PRIM ::= "branch" OPTNM "{" [PRIM] "}" ;

{- parser.y ------------------------------------------------------------- selection_primitive : selection_header '{' concurrent_primitive_list '}' { if ($3 == NULL) NodeLink ($1 -> source, $1 -> sink); } ; selection_header : SELECTION optional_name { Node source = NodeCreate ($2, SELECTION, lineno); Node sink = NodeCreate ($2, JOIN, lineno); $$ = GraphCreate (source, sink); } ; "select" is severely deprecated, so we drop it ---------------------------------------------------------------------- -} {- PrimSel. PRIM ::= "select" OPTNM "{" [PRIM] "}" ; -} PrimSeln. PRIM ::= "selection" OPTNM "{" [PRIM] "}" ;

{- parser.y ------------------------------------------------------------- iteration_primitive : ITERATION optional_name '{' sequential_primitive_list '}' { if ($4 != NULL) NodeLink ($4 -> sink, $4 -> source);

    $$ = $4;
}
;

---------------------------------------------------------------------- -} PrimIter. PRIM ::= "iteration" OPTNM "{" [PRIM] "}" ;

{- parser.y ------------------------------------------------------------- sequence_primitive : SEQUENCE optional_name '{' sequential_primitive_list '}' { $$ = $4; } ; ---------------------------------------------------------------------- -} PrimSeq. PRIM ::= "sequence" OPTNM "{" [PRIM] "}" ; PrimTask. PRIM ::= "task" OPTNM "{" [PRIM] "}" ;

{- parser.y ------------------------------------------------------------- action_primitive : action_header '{' specification_list '}' ; action_header : ACTION ID optional_type { Node node = NodeCreate ($2, ACTION, lineno); $$ = GraphCreate (node, node); node -> action_type = $3; } ; We fuse these. ---------------------------------------------------------------------- -} PrimAct. PRIM ::= "action" ID OPTYP "{" [SPEC] "}" ;

{- parser.y ------------------------------------------------------------- optional_name : ID | /* empty */ { $$ = "(anonymous)"; } ; ---------------------------------------------------------------------- -} OpNmNull. OPTNM ::= ; OpNmId. OPTNM ::= ID ;

{- parser.y ------------------------------------------------------------- optional_type : MANUAL { $$ = MANUAL; }

| EXECUTABLE
{
    $$ = EXECUTABLE;
}

| /* empty */
{
    $$ = 0;
}
;

---------------------------------------------------------------------- -} OptNull. OPTYP ::= ; OptMan. OPTYP ::= "manual" ; OptExec. OPTYP ::= "executable" ;

{- parser.y ------------------------------------------------------------- specification_list : specification_list specification | /* empty */ ; ---------------------------------------------------------------------- -} []. [SPEC] ::= ; (:). [SPEC] ::= SPEC [SPEC] ;

{- parser.y ------------------------------------------------------------- specification : PROVIDES '{' expression '}' { and_trees (&($-2 -> source -> provides), $3); }

| REQUIRES '{' expression '}'
{
    and_trees (&($<graph>-2 -> source -> requires), $3);
}

| AGENT '{' expression '}'
{
    and_trees (&($<graph>-2 -> source -> agent), $3);
}

| SCRIPT '{' STRING '}'
{
    $<graph>-2 -> source -> script = $3;
}

| TOOL '{' STRING '}'
{
    $<graph>-2 -> source -> tool = $3;
}
;

---------------------------------------------------------------------- -} SpecProv. SPEC ::= "provides" "{" EXPR "}" ; SpecReqs. SPEC ::= "requires" "{" EXPR "}" ; SpecAgent. SPEC ::= "agent" "{" EXPR "}" ; SpecScript. SPEC ::= "script" "{" STRING "}" ; SpecTool. SPEC ::= "tool" "{" STRING "}" ;

{- parser.y ------------------------------------------------------------- expression : disjunctionexpression ; ---------------------------------------------------------------------- -} . EXPR ::= EXPR2 ;

{- parser.y ------------------------------------------------------------- disjunction_expression : conjunction_expression | disjunction_expression OR conjunctionexpression { $$ = TreeCreate ($1, $3, "||", OR); } ; ---------------------------------------------------------------------- -} . EXPR2 ::= EXPR3 ; DisjExpr. EXPR2 ::= EXPR2 "||" EXPR3 ;

{- parser.y ------------------------------------------------------------- conjunction_expression : relation_expression | conjunction_expression AND relationexpression { $$ = TreeCreate ($1, $3, "&&", AND); } ; ---------------------------------------------------------------------- -} . EXPR3 ::= EXPR4 ; ConjExpr. EXPR3 ::= EXPR3 "&&" EXPR4 ;

{- parser.y ------------------------------------------------------------- relation_expression : string_expression | primary_expression | value_expression EQ value_expression { $$ = TreeCreate ($1, $3, "==", EQ); }

| value_expression NE value_expression
{
    $$ = TreeCreate ($1, $3, "!=", NE);
}

| value_expression LT value_expression
{
    $$ = TreeCreate ($1, $3, "<", LT);
}

| value_expression GT value_expression
{
    $$ = TreeCreate ($1, $3, ">", GT);
}

| value_expression LE value_expression
{
    $$ = TreeCreate ($1, $3, "<=", LE);
}

| value_expression GE value_expression
{
    $$ = TreeCreate ($1, $3, ">=", GE);
}

| variable_expression EQ variable_expression
{
    $$ = TreeCreate ($1, $3, "==", EQ);
}

| variable_expression NE variable_expression
{
    $$ = TreeCreate ($1, $3, "!=", NE);
}
;

---------------------------------------------------------------------- -} Str. EXPR4 ::= STRING ; _. EXPR4 ::= EXPR5 ; RelEq. EXPR4 ::= VALEXPR "==" VALEXPR ; RelNe. EXPR4 ::= VALEXPR "!=" VALEXPR ; RelLt. EXPR4 ::= VALEXPR "<" VALEXPR ; RelGt. EXPR4 ::= VALEXPR ">" VALEXPR ; RelLe. EXPR4 ::= VALEXPR "<=" VALEXPR ; RelGe. EXPR4 ::= VALEXPR ">=" VALEXPR ; RelVeq. EXPR4 ::= VAREXPR "==" VAREXPR ; RelVne. EXPR4 ::= VAREXPR "!=" VAREXPR ;

{- parser.y ------------------------------------------------------------- primary_expression : variable_expression | attribute_expression | NOT primary_expression { $$ = TreeCreate (NULL, $2, "!", NOT); }

| '(' expression ')'
{
    $$ = $2;
}
;

---------------------------------------------------------------------- -} PrimVar. EXPR5 ::= VAREXPR ; PrimAttr. EXPR5 ::= ATTREXPR ; PrimNot. EXPR5 ::= "!" EXPR5 ; _. EXPR5 ::= "(" EXPR ")" ;

{- parser.y ------------------------------------------------------------- variable_expression : identifier | '(' identifier ')' { $$ = $2; }

| '(' identifier ')' variable_expression
{
    $$ = TreeCreate ($2, $4, "(qualifier)", QUALIFIER);
}
;

---------------------------------------------------------------------- -} VarId. VAREXPR ::= ID ; VarPar. VAREXPR ::= "(" ID ")" ; VarMore. VAREXPR ::= "(" ID ")" VAREXPR ;

{- parser.y ------------------------------------------------------------- attribute_expression : variable_expression DOT identifier { $$ = TreeCreate ($1, $3, ".", DOT); } ; ---------------------------------------------------------------------- -} Attr. ATTREXPR ::= VAREXPR "." ID ;

{- parser.y ------------------------------------------------------------- value_expression : attribute_expression | string_expression | NUMBER { $$ = TreeCreate (NULL, NULL, $1, lineno); } ; ---------------------------------------------------------------------- -} ValAttr. VALEXPR ::= ATTREXPR ; ValString. VALEXPR ::= STRING ; ValNum. VALEXPR ::= NUMBER ;

{- parser.y ------------------------------------------------------------- /* we don't need to implement the following */ string_expression : STRING { $$ = TreeCreate (NULL, NULL, $1, lineno); } ;

identifier : ID { $$ = TreeCreate (NULL, NULL, $1, lineno); } ; ---------------------------------------------------------------------- -} {- parser.y ------------------------------------------------------------- ---------------------------------------------------------------------- -}

gdetrez commented 10 years ago

Hi,

Thanks for the feedback. I'm afraid I didn't manage to reproduce this.

If I understood correctly, you did the following:

$ /usr/bin/bnfc -m -p Formal.PML PML.cf
$ ghci TestPML.hs 

With the -p option, TestPML.hs should be generated in Formal/PML. Can you try the following instead:

$ ghci Formal/PML/TestPML.hs

(maybe the file TestPML.hs in your current directory is from an earlier conversion?)

andrewbutterfield commented 10 years ago

Hi Gregoire,

I tried what you asked, but got the same error.

I then decided to move to a new test folder, to avoid picking up anything strange I still get the same problem - could it have anything to do with my using the latest version of GHC?

I’ve attached a zip of that folder

On 29 Aug 2014, at 14:30, Grégoire Détrez notifications@github.com wrote:

Hi,

Thanks for the feedback. I'm afraid I didn't manage to reproduce this.

If I understood correctly, you did the following:

$ /usr/bin/bnfc -m -p Formal.PML PML.cf $ ghci TestPML.hs With the -p option, TestPML.hs should be generated in Formal/PML. Can you try the following instead:

$ ghci Formal/PML/TestPML.hs (maybe the file TestPML.hs in your current directory is from an earlier conversion?)

— Reply to this email directly or view it on GitHub.

Transcript of second attempt - the only file present here before running bnfc was PML.cf/

[~/Desktop/TEST] $ ls PML.cf

[~/Desktop/TEST] $ /usr/bin/bnfc -m -p Formal.PML PML.cf

47 rules accepted

Use Alex 3.0 to compile Formal/PML/LexPML.x. Formal/PML/ParPML.y Tested with Happy 1.15 writing new file Formal/PML/AbsPML.hs writing new file Formal/PML/LexPML.x writing new file Formal/PML/ParPML.y writing new file Formal/PML/TestPML.hs writing new file Formal/PML/DocPML.txt writing new file Formal/PML/SkelPML.hs writing new file Formal/PML/PrintPML.hs writing new file Formal/PML/ErrM.hs writing new file Makefile

[~/Desktop/TEST] $ ghci Formal/PML/TestPML.hs GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. [1 of 7] Compiling Formal.PML.ErrM ( Formal/PML/ErrM.hs, interpreted ) [2 of 7] Compiling Formal.PML.AbsPML ( Formal/PML/AbsPML.hs, interpreted ) [3 of 7] Compiling Formal.PML.PrintPML ( Formal/PML/PrintPML.hs, interpreted ) [4 of 7] Compiling Formal.PML.SkelPML ( Formal/PML/SkelPML.hs, interpreted ) [5 of 7] Compiling Formal.PML.LexPML ( /Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs, interpreted )

/Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs:324:29: Couldn't match expected type ‘Bool’ with actual type ‘Int#’ In the first argument of ‘(&&)’, namely ‘(offset >=# 0#)’ In the expression: (offset >=# 0#) && (check ==# ord_c) In the expression: if (offset >=# 0#) && (check ==# ord_c) then alexIndexInt16OffAddr alex_table offset else alexIndexInt16OffAddr alex_deflt s

/Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs:324:48: Couldn't match expected type ‘Bool’ with actual type ‘Int#’ In the second argument of ‘(&&)’, namely ‘(check ==# ord_c)’ In the expression: (offset >=# 0#) && (check ==# ord_c) In the expression: if (offset >=# 0#) && (check ==# ord_c) then alexIndexInt16OffAddr alex_table offset else alexIndexInt16OffAddr alex_deflt s Failed, modules loaded: Formal.PML.SkelPML, Formal.PML.PrintPML, Formal.PML.AbsPML, Formal.PML.ErrM. *Formal.PML.SkelPML>


Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Lero@TCD, Head of Foundations & Methods Research Group School of Computer Science and Statistics, Room G.39, O'Reilly Institute, Trinity College, University of Dublin

http://www.scss.tcd.ie/Andrew.Butterfield/

gdetrez commented 10 years ago

I don't think it's because of the ghc version as I use the same on my laptop.

It looks like the path for LexPML is wrong here:

/Users/andrewbutterfield/hlib/Formal/PML/LexPML.hs:324:48: Couldn't match expected type ‘Bool’ with actual type ‘Int#’ ...

it seems to be ~/hlib/Formal/PML/LexPML.hs instead of ~/Desktop/TEST/Formal/PML/LexPML.hs. I notice in your transcript that you never call alex and happy, if that's the case I guess that ghc cannot find Formal/PML/LexPML.hs in the current directory so it looks elsewhere for the module (in this case, it looked in ~/hlib/ for some reason).

gdetrez commented 10 years ago

Hej @andrewbutterfield, did you solve your issue?

andrewbutterfield commented 10 years ago

Hi Gregoire - apoligies for not getting back - I had a proposal deadline….

I haven’t check properly yet, but I think the problem was mine - not yours !

As you pointed out my compilation was picking up an old version of code - in a fit of being a “good Haskeller” I went and set up a proper hierarchical library structure for all my stuff, instead of throwing everything into one source directory. Now I have .ghci fled pointing into strange places, like ~/hlib.

However I still don’t fully grok* the consequences

Regards, Andrew

On 14 Sep 2014, at 18:43, Grégoire Détrez notifications@github.com wrote:

Hej @andrewbutterfield, did you solve your issue?

— Reply to this email directly or view it on GitHub.


Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Lero@TCD, Head of Foundations & Methods Research Group School of Computer Science and Statistics, Room G.39, O'Reilly Institute, Trinity College, University of Dublin

http://www.scss.tcd.ie/Andrew.Butterfield/

gdetrez commented 10 years ago

Closing now. Feel free to re-open if the problem is not solved