ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

Grammar railroad diagram

Open mingodad opened this issue 7 months ago • 4 comments

Using this tools https://github.com/GuntherRademacher/ebnf-convert and https://github.com/GuntherRademacher/rr we can have a nice navigable railroad diagram from pony.g (see bellow with instructions at the top).

I hope it can help document/develop this project 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 one of the urls shown above in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//
/* converted on Tue Mar 4, 2025, 13:41 (UTC+01) by antlr_3-to-w3c v0.69 which is Copyright (c) 2011-2025 by Gunther Rademacher <[email protected]> */

module   ::= STRING? use* class_def*
use      ::= 'use' ( ID '=' )? ( STRING | use_ffi ) ( 'if' infix )?
use_ffi  ::= '@' ( ID | STRING ) typeargs ( '(' | LPAREN_NEW ) params? ')' '?'?
class_def
         ::= ( 'type' | 'interface' | 'trait' | 'primitive' | 'struct' | 'class' | 'actor' ) ( '\' ID ( ',' ID )* '\' )? '@'? cap? ID typeparams? ( 'is' type )? STRING? members
members  ::= field* method*
field    ::= ( 'var' | 'let' | 'embed' ) ID ':' type ( '=' infix )? STRING?
method   ::= ( 'fun' | 'be' | 'new' ) ( '\' ID ( ',' ID )* '\' )? ( cap | '@' )? ID typeparams? ( '(' | LPAREN_NEW ) params? ')' ( ':' type )? '?'? STRING? ( '=>' rawseq )?
annotatedrawseq
         ::= ( '\' ID ( ',' ID )* '\' )? ( exprseq | jump )
rawseq   ::= exprseq
           | jump
exprseq  ::= assignment ( semiexpr | nosemi )?
nextexprseq
         ::= nextassignment ( semiexpr | nosemi )?
nosemi   ::= nextexprseq
           | jump
semiexpr ::= ';' ( exprseq | jump )
jump     ::= ( 'return' | 'break' | 'continue' | 'error' | 'compile_intrinsic' | 'compile_error' ) rawseq?
nextassignment
         ::= nextinfix ( '=' assignment )?
assignment
         ::= infix ( '=' infix )*
nextinfix
         ::= nextterm antlr_0*
infix    ::= term antlr_1*
isop     ::= ( 'is' | 'isnt' ) term
binop    ::= ( 'and' | 'or' | 'xor' | '+' | '-' | '*' | '/' | '%' | '%%' | '+~' | '-~' | '*~' | '/~' | '%~' | '%%~' | '<<' | '>>' | '<<~' | '>>~' | '==' | '!=' | '<' | '<=' | '>=' | '>' | '==~' | '!=~' | '<~' | '<=~' | '>=~' | '>~' ) '?'? term
nextterm ::= ( 'if' ( '\' ID ( ',' ID )* '\' )? rawseq 'then' rawseq ( elseif | 'else' annotatedrawseq )? | 'ifdef' ( '\' ID ( ',' ID )* '\' )? infix 'then' rawseq ( elseifdef | 'else' annotatedrawseq )? | 'iftype' ( '\' ID ( ',' ID )* '\' )? iftype ( elseiftype | 'else' annotatedrawseq )? | ( 'match' ( '\' ID ( ',' ID )* '\' )? rawseq caseexpr* | ( 'while' ( '\' ID ( ',' ID )* '\' )? | 'for' ( '\' ID ( ',' ID )* '\' )? idseq 'in' ) rawseq 'do' rawseq | 'repeat' ( '\' ID ( ',' ID )* '\' )? rawseq 'until' annotatedrawseq ) ( 'else' annotatedrawseq )? | ( 'with' ( '\' ID ( ',' ID )* '\' )? withelem ( ',' withelem )* 'do' | 'recover' ( '\' ID ( ',' ID )* '\' )? cap? ) rawseq | 'try' ( '\' ID ( ',' ID )* '\' )? rawseq ( 'else' annotatedrawseq )? ( 'then' annotatedrawseq )? ) 'end'
           | 'consume' cap? term
           | nextpattern
           | '#' postfix
term     ::= ( 'consume' cap? )* ( ( 'if' ( '\' ID ( ',' ID )* '\' )? rawseq 'then' rawseq ( elseif | 'else' annotatedrawseq )? | 'ifdef' ( '\' ID ( ',' ID )* '\' )? infix 'then' rawseq ( elseifdef | 'else' annotatedrawseq )? | 'iftype' ( '\' ID ( ',' ID )* '\' )? iftype ( elseiftype | 'else' annotatedrawseq )? | ( 'match' ( '\' ID ( ',' ID )* '\' )? rawseq caseexpr* | ( 'while' ( '\' ID ( ',' ID )* '\' )? | 'for' ( '\' ID ( ',' ID )* '\' )? idseq 'in' ) rawseq 'do' rawseq | 'repeat' ( '\' ID ( ',' ID )* '\' )? rawseq 'until' annotatedrawseq ) ( 'else' annotatedrawseq )? | ( 'with' ( '\' ID ( ',' ID )* '\' )? withelem ( ',' withelem )* 'do' | 'recover' ( '\' ID ( ',' ID )* '\' )? cap? ) rawseq | 'try' ( '\' ID ( ',' ID )* '\' )? rawseq ( 'else' annotatedrawseq )? ( 'then' annotatedrawseq )? ) 'end' | pattern | '#' postfix )
withelem ::= idseq '=' rawseq
caseexpr ::= '|' ( '\' ID ( ',' ID )* '\' )? casepattern? ( 'if' rawseq )? ( '=>' rawseq )?
elseiftype
         ::= ( 'elseif' ( '\' ID ( ',' ID )* '\' )? iftype )+ ( 'else' annotatedrawseq )?
iftype   ::= type '<:' type 'then' rawseq
elseifdef
         ::= ( 'elseif' ( '\' ID ( ',' ID )* '\' )? infix 'then' rawseq )+ ( 'else' annotatedrawseq )?
elseif   ::= ( 'elseif' ( '\' ID ( ',' ID )* '\' )? rawseq 'then' rawseq )+ ( 'else' annotatedrawseq )?
idseq    ::= ID
           | ( '(' | LPAREN_NEW ) idseq_in_seq ( ',' idseq_in_seq )* ')'
idseq_in_seq
         ::= ID
           | ( '(' | LPAREN_NEW ) idseq_in_seq ( ',' idseq_in_seq )* ')'
nextpattern
         ::= ( 'var' | 'let' | 'embed' ) ID ( ':' type )?
           | nextparampattern
casepattern
         ::= ( 'var' | 'let' | 'embed' ) ID ( ':' type )?
           | ( 'not' | 'addressof' | '-' | '-~' | MINUS_NEW | MINUS_TILDE_NEW | 'digestof' )* casepostfix
pattern  ::= ( 'var' | 'let' | 'embed' ) ID ( ':' type )?
           | parampattern
nextparampattern
         ::= ( 'not' | 'addressof' | MINUS_NEW | MINUS_TILDE_NEW | 'digestof' ) parampattern
           | nextpostfix
parampattern
         ::= ( 'not' | 'addressof' | '-' | '-~' | MINUS_NEW | MINUS_TILDE_NEW | 'digestof' )* postfix
nextpostfix
         ::= nextatom antlr_2*
casepostfix
         ::= caseatom antlr_3*
postfix  ::= atom antlr_4*
call     ::= '(' positional? named? ')' '?'?
chain    ::= '.>' ID
tilde    ::= '~' ID
dot      ::= '.' ID
nextatom ::= ID
           | 'this'
           | literal
           | LPAREN_NEW rawseq tuple? ')'
           | LSQUARE_NEW ( 'as' type ':' )? rawseq? ']'
           | ( 'object' ( '\' ID ( ',' ID )* '\' )? cap? ( 'is' type )? members | 'if' ( '\' ID ( ',' ID )* '\' )? rawseq 'then' rawseq ( elseif | 'else' annotatedrawseq )? | ( 'while' ( '\' ID ( ',' ID )* '\' )? | 'for' ( '\' ID ( ',' ID )* '\' )? idseq 'in' ) rawseq 'do' rawseq ( 'else' annotatedrawseq )? ) 'end'
           | ( '{' | '@{' ) ( '\' ID ( ',' ID )* '\' )? cap? ID? typeparams? ( '(' | LPAREN_NEW ) lambdaparams? ')' lambdacaptures? ( ':' type )? '?'? '=>' rawseq '}' cap?
           | '@' ( ID | STRING ) typeargs? ( '(' | LPAREN_NEW ) positional? named? ')' '?'?
           | '__loc'
caseatom ::= ID
           | 'this'
           | literal
           | ( '(' | LPAREN_NEW ) rawseq tuple? ')'
           | ( '[' | LSQUARE_NEW ) ( 'as' type ':' )? rawseq? ']'
           | ( 'object' ( '\' ID ( ',' ID )* '\' )? cap? ( 'is' type )? members | ( 'while' ( '\' ID ( ',' ID )* '\' )? | 'for' ( '\' ID ( ',' ID )* '\' )? idseq 'in' ) rawseq 'do' rawseq ( 'else' annotatedrawseq )? ) 'end'
           | ( '{' | '@{' ) ( '\' ID ( ',' ID )* '\' )? cap? ID? typeparams? ( '(' | LPAREN_NEW ) lambdaparams? ')' lambdacaptures? ( ':' type )? '?'? '=>' rawseq '}' cap?
           | '@' ( ID | STRING ) typeargs? ( '(' | LPAREN_NEW ) positional? named? ')' '?'?
           | '__loc'
atom     ::= ID
           | 'this'
           | literal
           | ( '(' | LPAREN_NEW ) rawseq tuple? ')'
           | ( '[' | LSQUARE_NEW ) ( 'as' type ':' )? rawseq? ']'
           | ( 'object' ( '\' ID ( ',' ID )* '\' )? cap? ( 'is' type )? members | 'if' ( '\' ID ( ',' ID )* '\' )? rawseq 'then' rawseq ( elseif | 'else' annotatedrawseq )? | ( 'while' ( '\' ID ( ',' ID )* '\' )? | 'for' ( '\' ID ( ',' ID )* '\' )? idseq 'in' ) rawseq 'do' rawseq ( 'else' annotatedrawseq )? ) 'end'
           | ( '{' | '@{' ) ( '\' ID ( ',' ID )* '\' )? cap? ID? typeparams? ( '(' | LPAREN_NEW ) lambdaparams? ')' lambdacaptures? ( ':' type )? '?'? '=>' rawseq '}' cap?
           | '@' ( ID | STRING ) typeargs? ( '(' | LPAREN_NEW ) positional? named? ')' '?'?
           | '__loc'
tuple    ::= ( ',' rawseq )+
lambdacaptures
         ::= ( '(' | LPAREN_NEW ) ( lambdacapture | 'this' ) ( ',' ( lambdacapture | 'this' ) )* ')'
lambdacapture
         ::= ID ( ':' type )? ( '=' infix )?
lambdaparams
         ::= lambdaparam ( ',' lambdaparam )*
lambdaparam
         ::= ID ( ':' type )? ( '=' infix )?
positional
         ::= rawseq ( ',' rawseq )*
named    ::= 'where' namedarg ( ',' namedarg )*
namedarg ::= ID '=' rawseq
type     ::= atomtype ( '->' atomtype )*
atomtype ::= 'this'
           | cap
           | ( '(' | LPAREN_NEW ) infixtype tupletype? ')'
           | nominal
           | lambdatype
           | barelambdatype
barelambdatype
         ::= '@{' cap? ID? typeparams? ( '(' | LPAREN_NEW ) ( type ( ',' type )* )? ')' ( ':' type )? '?'? '}' ( cap | gencap )? ( '^' | '!' )?
lambdatype
         ::= '{' cap? ID? typeparams? ( '(' | LPAREN_NEW ) ( type ( ',' type )* )? ')' ( ':' type )? '?'? '}' ( cap | gencap )? ( '^' | '!' )?
tupletype
         ::= ( ',' infixtype )+
infixtype
         ::= type antlr_5*
isecttype
         ::= '&' type
uniontype
         ::= '|' type
nominal  ::= ID ( '.' ID )? typeargs? ( cap | gencap )? ( '^' | '!' )?
gencap   ::= '#read'
           | '#send'
           | '#share'
           | '#alias'
           | '#any'
cap      ::= 'iso'
           | 'trn'
           | 'ref'
           | 'val'
           | 'box'
           | 'tag'
typeargs ::= '[' typearg ( ',' typearg )* ']'
typeparams
         ::= ( '[' | LSQUARE_NEW ) typeparam ( ',' typeparam )* ']'
params   ::= ( param | '...' ) ( ',' ( param | '...' ) )*
typeparam
         ::= ID ( ':' type )? ( '=' typearg )?
typearg  ::= type
           | literal
           | '#' postfix
literal  ::= 'true'
           | 'false'
           | INT
           | FLOAT
           | STRING
param    ::= ID ':' type ( '=' infix )?
antlr_0  ::= binop
           | isop
           | 'as' type
antlr_1  ::= binop
           | isop
           | 'as' type
antlr_2  ::= dot
           | tilde
           | chain
           | typeargs
           | call
antlr_3  ::= dot
           | tilde
           | chain
           | typeargs
           | call
antlr_4  ::= dot
           | tilde
           | chain
           | typeargs
           | call
antlr_5  ::= uniontype
           | isecttype
_        ::= LINECOMMENT
           | NESTEDCOMMENT
           | WS
           | NEWLINE
          /* ws: definition */

<?TOKENS?>

ID       ::= ( LETTER | '_' ) ( LETTER | DIGIT | '_' | "'" )*
INT      ::= DIGIT ( DIGIT | '_' )*
           | '0' ( 'x' ( HEX | '_' )+ | 'b' ( BINARY | '_' )+ )
           | "'" CHAR_CHAR* "'"
FLOAT    ::= DIGIT ( DIGIT | '_' )* ( '.' DIGIT ( DIGIT | '_' )* )? EXP?
STRING   ::= '"' STRING_CHAR* '"'
           | '"""' ( ( '"' | '""' )? [^"] )* '"""' '"'*
LPAREN_NEW
         ::= NEWLINE '('
LSQUARE_NEW
         ::= NEWLINE '['
MINUS_NEW
         ::= NEWLINE '-'
MINUS_TILDE_NEW
         ::= NEWLINE '-~'
LINECOMMENT
         ::= '//' [^#xA]*
NESTEDCOMMENT
         ::= '/*' ( NESTEDCOMMENT | '/' [^*] | '*'* [^*/] )* '*'+ '/'
WS       ::= [ #x9#xD]+
NEWLINE  ::= #xA [ #x9#xD]*
CHAR_CHAR
         ::= '\' "'"
           | CHAR_ESC
           | [^'\]
STRING_CHAR
         ::= '\' '"'
           | ESC
           | [^"\]
EXP      ::= ( 'e' | 'E' ) ( '+' | '-' )? ( DIGIT | '_' )+
LETTER   ::= [a-zA-Z]
BINARY   ::= [0-1]
DIGIT    ::= [0-9]
HEX      ::= DIGIT
           | [a-fA-F]
ESC      ::= CHAR_ESC
           | UNICODE_ESC
           | UNICODE2_ESC
CHAR_ESC ::= '\' ( 'a' | 'b' | 'e' | 'f' | 'n' | 'r' | 't' | 'v' | '\' | '0' )
           | HEX_ESC
HEX_ESC  ::= '\' 'x' HEX HEX
UNICODE_ESC
         ::= '\' 'u' HEX HEX HEX HEX
UNICODE2_ESC
         ::= '\' 'U' HEX HEX HEX HEX HEX HEX

mingodad avatar Mar 04 '25 12:03 mingodad