I'm pleased to announce BNFC-meta-0.1.0!
<div><br></div><div>BNFC-meta can take a quasi-quoted LBNF grammar (as used by the BNF Converter) representation of a language and generate (using Template Haskell) a number of wonderful tools for dealing with this language, including:</div>
<div><br></div><div>* Abstract syntax types</div><div>* Lexer </div><div>* LALR Parser</div><div>* Pretty-printer</div><div>* Quasi-quoter</div><div><br></div><div>Apart from the quasi-quoter, these are all features of the BNF Converter, but grammars can now be embedded directly into Haskell modules. <br>
<br>Here's an example of a small subset of C:<br><br>\begin{code}<br><font face="verdana, sans-serif"><font face="'courier new', monospace">{-# LANGUAGE QuasiQuotes #-}<br>
module MiniLanguage where<br>import Language.LBNF<br><br>-- 'Compile' is a Template Haskell function, 'cf' is a QuasiQuoter.<br>compile [$cf|<br>antiquote "[" ":" ":]" ;<br>Fun. Prog ::= Typ Ident "(" ")" "{" [Stm] "}" ;<br>
SDecl. Stm ::= Typ Ident ";" ;<br>SAss. Stm ::= Ident "=" Expr ";" ;<br>SIncr. Stm ::= Ident "++" ";" ;<br>SWhile. Stm ::= "while" "(" Expr ")" "{" [Stm] "}" ;<br>
<br>ELt. Expr0 ::= Expr1 "<" Expr1 ;<br>EPlus. Expr1 ::= Expr1 "+" Expr2 ;<br>ETimes. Expr2 ::= Expr2 "*" Expr3 ;<br>EVar. Expr3 ::= Ident ;<br>EInt. Expr3 ::= Integer ;<br>
<br>[]. [Stm] ::= ;<br>(:). [Stm] ::= Stm [Stm] ;<br><br>_. Stm ::= Stm ";" ;<br>_. Expr ::= Expr0 ;<br>_. Expr0 ::= Expr1 ;<br>_. Expr1 ::= Expr2 ;<br>_. Expr2 ::= Expr3 ;<br>
_. Expr3 ::= "(" Expr ")" ;<br><br>TInt. Typ ::= "int" ;<br>comment "/*" "*/" ;<br>comment "//" ;</font><br>|]</font><br><div>\end{code}<br><br><br><br>
And here is a module that uses it:<br><br>\begin{code}</div><div><font face="'courier new', monospace">{-# LANGUAGE QuasiQuotes #-}</font></div><div><font face="'courier new', monospace">import MiniLanguage</font></div>
<div><font face="'courier new', monospace">import Language.LBNF(pp) -- overloaded pretty-printing function</font></div><div><font face="'courier new', monospace">import Prelude hiding (exp)</font></div>
<div><font face="'courier new', monospace"><br></font></div><div><font face="'courier new', monospace">power :: Ident -> Integer -> Prog</font></div>
<div><font face="'courier new', monospace">power var x = [$prog|</font></div><div><font face="'courier new', monospace">// This quoter accepts C-style comments </font></div>
<div><font face="'courier new', monospace">int myPower() {</font></div><div><font face="'courier new', monospace"> int tmp;</font></div><div><font face="'courier new', monospace"> tmp = 0;</font></div>
<div><font face="'courier new', monospace"><br></font></div><div><font face="'courier new', monospace"> // Things in [: :] are anti-quoted Haskell expressions.</font></div>
<div><font face="'courier new', monospace"> [: repeatWhile (Ident "tmp") x mult :]</font></div><div><font face="'courier new', monospace">} |] where </font></div>
<div><font face="'courier new', monospace"> -- [X:haskell:] means the anti-quoted expression represents non-terminal X,</font></div><div><font face="'courier new', monospace"> -- Used to resolve ambiguities (in this case between Ident/Expr/Integer).</font></div>
<div><font face="'courier new', monospace"> mult = [$stm| [:var:] = [Ident:var:] * [Ident:var:] ; |]</font></div><div><font face="'courier new', monospace"><br>
</font></div><div><font face="'courier new', monospace">-- Repeats a statement n times. (at least if variable var is 0... )</font></div><div><font face="'courier new', monospace">repeatWhile var n statement = [$stm|</font></div>
<div><font face="'courier new', monospace"> while ([Ident:var:] < [:n:]) {</font></div><div><font face="'courier new', monospace"> [Stm:statement:]</font></div>
<div><font face="'courier new', monospace"> [:var:] ++ ;</font></div><div><font face="'courier new', monospace"> }|]</font></div><div><font face="'courier new', monospace"><br>
</font></div><div><font face="'courier new', monospace">pr = power (Ident "n") 10</font></div><div><font face="'courier new', monospace">main = putStr $ pp pr</font></div>
</div><div>\end{code}</div><div><div><br></div><div><br>There are a few more examples in the source tarball. More documentation on these features will be supplied eventually :)<br><br></div>Best regards,</div><div>Jonas</div>