In response to popular demand I have created a Spoofax project for LBNF, the grammar formalism of the BNFC project. The project contains an SDF3 definition for LBNF obtained by manually converting the LBNF grammar in LBNF, and a transformation from LBNF to SDF3.

The transformation is fairly straightforward since LBNF and SDF3 productions are similar. In particular, LBNF productions declare a constructor symbol, which is also needed in SDF3. The main distinction is the way that lists are specified. For example, the following LBNF productions

    Rule . Def ::= Label "." Cat "::=" [Item] ;
    []  . [Item] ::= ;
    (:) . [Item] ::= Item [Item] ;

translate to this SDF3 production:

    Def.Rule = [[Label] . [Cat] ::= [{Item " "}*]]

The transformation is probably somewhat rudimentary and ignores advanced features of LBNF. Yet the converter should be fairly robust, since it skips anything that it doesn’t recognize. I have only tested it on the LBNF.cf file itself. More testing is needed. I will be happy to do some more work on the transformation if popular demand so requires.

Using LBNF to SDF3

To use the converter:

  • Check out the GitHub repository (https://github.com/MetaBorgCube/metaborg-lbnf) and import the project into your Eclipse with Spoofax.
  • Build the project.
  • Open a .cf file
  • Hit the ‘Transform to SDF3’ transformation in the ‘Generation’ menu

LBNF in LBNF (fragment)

    MkGrammar . Grammar ::= [Def] ;

    []  . [Def] ::= ;
    (:) . [Def] ::= Def ";" [Def] ;

    []  . [Item] ::= ;
    (:) . [Item] ::= Item [Item] ;

    Rule . Def ::= Label "." Cat "::=" [Item] ;

    Terminal  . Item ::= String ;
    NTerminal . Item ::= Cat ;

    ListCat  . Cat ::= "[" Cat "]" ;

LBNF in SDF3 (same fragment)

    context-free syntax
      Grammar.MkGrammar = {Def ";"}*

      Def.Rule = [[Label] . [Cat] ::= [{Item " "}*]]

      Item.Terminal = STRING

      Item.NTerminal = Cat

      Cat.ListCat = <[ <Cat> ]>