soasme / PeppaPEG

PEG Parser in ANSI C
https://soasme.com/PeppaPEG
MIT License
55 stars 7 forks source link

Grammar railroad diagram #146

Open mingodad opened 2 years ago

mingodad commented 2 years ago

With something like this https://github.com/mingodad/PeppaPEG/commit/d8e43ed3a172f628656d136fe8986ef5e119100c and using https://www.bottlecaps.de/convert/ to convert the naked output to be used here https://www.bottlecaps.de/rr/ui to get a railroad diagram for the grammars written to PeppaPEG.

Example:

../cli parse -n -G peppa.peg -e grammar peppa.peg 

grammar =
     ( start_of_input rule+  end_of_input ) ;
start_of_input =
    &. ;
end_of_input =
    !. ;
rule =
     ( decorators name /*~*/ "=" expression ";" ) ;
decorators =
    decorator*  ;
decorator =
     ( "@" /*~*/  ( "squashed" / "scoped" / "spaced" / "lifted" / "tight" / "nonterminal" ) ) ;
/*@squashed*/ 
name =
    reference ;
/*@lifted*/ 
expression =
    left_recursion ;
/*@nonterminal*/ 
left_recursion =
     ( choice  ( "|" /*~*/ reference choice )?  ) ;
/*@nonterminal*/ 
choice =
     ( sequence  ( ! ( "//" / "/*" ) "/" sequence )*  ) ;
/*@nonterminal*/ 
sequence =
    repeat+  ;
/*@nonterminal*/ 
repeat =
     ( primary  ( onceormore / zeroormore / zerooronce / repeatexact / repeatminmax / repeatmin / repeatmax )?  ) ;
onceormore =
    "+" ;
zeroormore =
    "*" ;
zerooronce =
    "?" ;
repeatexact =
     ( "{" number "}" ) ;
repeatminmax =
     ( "{" number "," number "}" ) ;
repeatmin =
     ( "{" number "," "}" ) ;
repeatmax =
     ( "{" "," number "}" ) ;
/*@lifted*/ 
primary =
     ( literal / insensitive / range /  ( reference !"=" ) / back_reference / positive / negative /  ( "(" choice ")" ) / dot / cut ) ;
/*@squashed*/ /*@tight*/ 
literal =
     ( "\"" /*~*/ chars "\"" ) ;
chars =
    char*  ;
/*@squashed*/ /*@tight*/ 
char =
     ( [\x20-\x21] / [\x23-\x5b] / [\x5d-\U0010ffff] /  ( "\\"  ( "\"" / "/" / "\\" / "b" / "f" / "n" / "r" / "t" / "v" /  ( "x" /*~*/ two_hexdigits ) /  ( "u" /*~*/ four_hexdigits ) /  ( "U" /*~*/ eight_hexdigits ) ) ) ) ;
/*@squashed*/ /*@tight*/ 
range_category =
     ( [a-z] / [A-Z] / [0-9] / "_" / " " )+  ;
range =
     ( "["  (  ( char "-" char  ( ".." number )?  ) /  ( "\\p{" range_category "}" ) ) "]" ) ;
/*@tight*/ 
insensitive =
     ( "i"  ( literal / back_reference ) ) ;
/*@squashed*/ /*@tight*/ 
reference =
     (  ( [a-z] / [A-Z] / "_" )  ( [a-z] / [A-Z] / [0-9] / "_" )*  ) ;
/*@tight*/ 
back_reference =
     ( "\\" /*~*/ number ) ;
positive =
     ( "&" /*~*/ primary ) ;
negative =
     ( "!" /*~*/ primary ) ;
dot =
    "." ;
cut =
    "~" ;
hexdigit =
     ( [0-9] / [a-f] / [A-F] ) ;
two_hexdigits =
    hexdigit{2}  ;
four_hexdigits =
    hexdigit{4}  ;
eight_hexdigits =
    hexdigit{8}  ;
/*@squashed*/ /*@tight*/ 
number =
     ( "0" /  ( [1-9] [0-9]*  ) ) ;
/*@lifted*/ /*@spaced*/ 
comment =
     (  (  ( "#" / "//" )  ( !"\n". )*  "\n"?  ) /  ( "/*"  ( !"*/". )*  "*/" ) ) ;
/*@lifted*/ /*@spaced*/ 
whitespace =
     ( " " / "\t" / "\r" / "\n" ) ;

Then coping and pasting the output shown above on https://www.bottlecaps.de/convert/ on the Input grammar: textarea and then clicking the button Convert then the button View Diagram we get a nice railroad diagram (https://en.wikipedia.org/wiki/Syntax_diagram) for the grammar.