BNFC / bnfc

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

Grammar railroad diagram #489

Open mingodad opened 2 weeks ago

mingodad commented 2 weeks ago

Would be nice if bnfc cold generate an EBNF understood by https://github.com/GuntherRademacher/rr to generate nice navigable railroad diagrams like the one shown bellow that was generated by https://mingodad.github.io/parsertl-playground/playground/ (after I've added bnfc grammar (select BNFC parser from Examples then click Parse to see a parse tree for the content in Input source)).

The tokens were manually added, see instructions at the top bellow to view the railroad diagram.

//
// EBNF to be viewd at
//    (IPV6) https://www.bottlecaps.de/rr/ui
//    (IPV4) https://rr.red-dove.com/ui
//
// Copy and paste this at one of the urls shown above in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//

Grammar::=
      ListDef

ListDef::=
      /*%empty*/
    | ListDef Def ';'

Def::=
      Label '.' Cat "::=" ListItem
    | "comment" String
    | "comment" String String
    | "internal" Label '.' Cat "::=" ListItem
    | "token" Identifier Reg
    | "position" "token" Identifier Reg
    | "entrypoints" ListCat
    | "separator" MinimumSize Cat String
    | "terminator" MinimumSize Cat String
    | "delimiters" Cat String String Separation MinimumSize
    | "coercions" Identifier Integer
    | "rules" Identifier "::=" ListRHS
    | "define" Identifier ListArg '=' Exp
    | "layout" ListString
    | "layout" "stop" ListString
    | "layout" "toplevel"

Item::=
      String
    | Cat

ListItem::=
      /*%empty*/
    | ListItem Item

Cat::=
      '[' Cat ']'
    | Identifier

ListCat::=
      Cat
    | ListCat ',' Cat

Label::=
      Identifier
    | '_'
    | '[' ']'
    | '(' ':' ')'
    | '(' ':' '[' ']' ')'

Arg::=
      Identifier

ListArg::=
      Arg
    | ListArg Arg

Separation::=
      /*%empty*/
    | "terminator" String
    | "separator" String

ListString::=
      String
    | ListString ',' String

Exp::=
      Exp1
    | Exp ':' Exp1

Exp1::=
      Exp2
    | Identifier ListExpr2

Exp2::=
      Identifier
    | Integer
    | Char
    | String
    | Double
    | '[' ListExpr ']'
    | '(' Exp ')'

ListExpr2::=
      Exp2
    | ListExpr2 Exp2

ListExpr::=
      /*%empty*/
    | Exp
    | ListExpr ',' Exp

ListRHS::=
      ListItem
    | ListRHS '|' ListItem

MinimumSize::=
      /*%empty*/
    | "nonempty"

Reg::=
      Reg1
    | Reg '|' Reg1

Reg1::=
      Reg2
    | Reg1 '-' Reg2

Reg2::=
      Reg3
    | Reg2 Reg3

Reg3::=
      Reg3 '*'
    | Reg3 '+'
    | Reg3 '?'
    | "eps"
    | Char
    | '[' String ']'
    | '{' String '}'
    | "digit"
    | "letter"
    | "upper"
    | "lower"
    | "char"
    | '(' Reg ')'

//Tokens

Char ::= "'"("\".|[^'#x13#x10\\])"'"
Double ::= [0-9]+"."[0-9]+
Integer ::= [0-9]+
String ::= '"'("\".|[^"#x13#x10\\])*'"'

Identifier ::= [A-Za-z][A-Za-z0-9_]*