haskell / happy

The Happy parser generator for Haskell
Other
291 stars 84 forks source link

Idea: Backend for generating railroad diagrams #244

Open sgraf812 opened 1 year ago

sgraf812 commented 1 year ago

https://gitlab.haskell.org/ghc/ghc/-/issues/21342 manually postprocessed GHC's Parser.y file to generate a railroad diagram. Perhaps that would be a cool use case for a happy backend if when the modularisation is finally published.

mingodad commented 8 months ago

I've just added happy grammar to https://mingodad.github.io/parsertl-playground/playground/ an Yacc/Lex compatible online editor/tester (select Happy parser from Examples then click Parse to see a parse tree for the content in Input source).

And here is the EBNF to generate a railroad diagram for the Happy grammar:

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

parser::=
      optCode core_parser optCode

core_parser::=
      tokInfos "%%" rules

rules::=
      rules rule
    | rule

rule::=
      id params "::" code ':' prods
    | id params "::" code id ':' prods
    | id params ':' prods

params::=
      '(' comma_ids ')'
    | /*%empty*/

comma_ids::=
      id
    | comma_ids ',' id

prods::=
      prods '|' prod
    | prod

prod::=
      terms prec code ';'
    | terms prec code

term::=
      id
    | id '(' comma_terms ')'

terms::=
      terms_rev
    | /*%empty*/

terms_rev::=
      term
    | terms_rev term

comma_terms::=
      term
    | comma_terms ',' term

prec::=
      spec_prec id
    | spec_shift
    | /*%empty*/

tokInfos::=
      tokInfos tokInfo
    | tokInfo

tokInfo::=
      spec_tokentype code
    | spec_token tokenSpecs
    | spec_name id optStart
    | spec_partial id optStart
    | spec_imported_identity
    | spec_lexer code code
    | spec_monad code
    | spec_monad code code
    | spec_monad code code code
    | spec_monad code code code code
    | spec_nonassoc ids
    | spec_right ids
    | spec_left ids
    | spec_expect int
    | spec_error code
    | spec_errorhandlertype id
    | spec_attributetype code
    | spec_attribute id code

optStart::=
      id
    | /*%empty*/

tokenSpecs::=
      tokenSpecs tokenSpec
    | tokenSpec

tokenSpec::=
      id code

ids::=
      ids id
    | /*%empty*/

optCode::=
      code
    | /*%empty*/

//Tokens

spec_attribute ::= "%attribute"
spec_attributetype ::= "%attributetype"
spec_error ::= "%error"
spec_errorhandlertype ::= "%errorhandlertype"
spec_expect ::= "%expect"
spec_imported_identity ::= "%imported_identity"
spec_left ::= "%left"
spec_lexer ::= "%lexer"
spec_monad ::= "%monad"
spec_name ::= "%name"
spec_nonassoc ::= "%nonassoc"
spec_partial ::= "%partial"
spec_prec ::= "%prec"
spec_right ::= "%right"
spec_shift ::= "%shift"
spec_token ::= "%token"
spec_tokentype ::= "%tokentype"
sgraf812 commented 8 months ago

That's cool, but this issue is about generating railroad diagrams for input grammars from happy, not generating a railroad diagram of the grammar of happy's .y files.

mingodad commented 8 months ago

I know that and it's here because it's an already related existing issue and it's an example of how it could be designed see also what I did for bison/byacc/lemon here https://github.com/mingodad/lalr-parser-test where I've added the EBNF output for railroad diagram generation.