//
// EBNF to generate railroad diagram at
// https://www.bottlecaps.de/rr/ui
//
// From https://raw.githubusercontent.com/fubark/tree-sitter-cyber/refs/heads/main/src/grammar.json
//
source_file ::=
shebang? _statement*
keyword ::=
[a-zA-Z_]([a-zA-Z_]|'#')*
_whitespace ::=
[ #x09]+
_newline ::=
_NEWLINE
_indent ::=
_INDENT
_dedent ::=
_DEDENT
codepoint ::=
numeric_literal | [\u0000-\u007F] [\u0000-\u007F] | 'x'[0-9a-fA-F]'{2}' | '\' | [uU][0-9a-fA-F]'{1,6}'
numeric_literal ::=
( [0-9]? ( 'o' | 'O' ) [+-]? [0-7]+ | [~]? [+-]? ( [0-9][0-9_]*('.'[0-9_]+)?([eE][+-]?[0-9_]+)? [uUfF]? | ( '0x' | '0b' ) [0-9a-fA-F]'{2,8}'+ ( "'" [0-9a-fA-F]'{2,8}'+ )* ) | [~]? [+-]? '0x' | '0b' ( [0-9]+'#'[0-9a-fA-F._-]+'#'([eE][+-]?[0-9_]+)? [uUfF]? | [0-9]+ ( "'" [0-9]+ )+ ) )
identifier ::=
[a-z_][a-zA-Z0-9_-]*
name ::=
[a-zA-Z_][a-zA-Z0-9_-]*
_identifier ::=
builtin_function | var_identifier | type_identifier | import_export | exception_identifiers | repeat_identifiers | identifier
var_identifier ::=
[a-z] | [a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]
type_identifier ::=
_builtin_type | [a-zA-Z] | [a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]
_builtin_type ::=
'int' | 'float' | 'bool' | 'none' | 'any' | 'void' | 'object' | 'atype' | 'tagtype' | 'true' | 'false' | 'number' | 'pointer' | 'string' | 'rawstring' | 'boolean' | 'char' | 'byte' | 'short' | 'long' | 'uchar' | 'ushort' | 'ulong' | 'uint' | 'int8' | 'int16' | 'int32' | 'int64' | 'charPtr' | 'voidPtr' | 'double' | cfunc | error
import_export ::=
'import'
| 'export'
comment ::=
( '--' '.'* )
exception_identifiers ::=
try_identifier
| catch_identifier
| 'recover'
repeat_identifiers ::=
'do'
| 'while'
| 'for'
| 'yield'
| 'break'
| 'continue'
| 'pass'
builtin_function ::=
( 'len' | 'map' | 'print' | 'typeid' | 'indexChar' | 'insert' | 'string' | 'exit' )
escape_sequence ::=
( '\' ( [uU][0-9a-fA-F]'{1,6}' | 'x'[0-9a-fA-F]'{2}' | ["'`$\abfnrtv] | [0-7]'{1,3}' ) )
encoded_string ::=
numeric_literal string
multiline_string ::=
_string_start ( string_interpolation | _string_content )* _string_end
| _string_start ( string_interpolation | _string_content )* _string_end
string ::=
"'" ( [^'{}\]+ | '\.' | string_interpolation )* "'"
string_interpolation ::=
_open_brace _expression _close_brace
_statement ::=
_standard_statements
| _complex_statement
_standard_statements ::=
_standard_statement _newline
_standard_statement ::=
import_statement
| _declaration
| _expression_statement
| coyield_statement
| print_statement
| return_statement
| exit_statement
_complex_statement ::=
if_statement
| match_statement
| loop_statement
| while_loop
| for_range_loop
| for_iterable_loop
| try_statement
| recover_block
_declaration ::=
local_declaration | typed_statement | var_declaration | function_definition | tagtype_declaration
shebang ::=
'#!' '.'* _newline
import_statement ::=
'import' _identifier string
local_declaration ::=
_expression ( '=' ( _expression | _statement ) | _identifier )
var_declaration ::=
'var' _identifier type_identifier? ':' ( _expression | _statement )
function_definition ::=
_func ( function_declaration | method_declaration ) _identifier? ( _block_group | ( '=' _standard_statements ) | _standard_statements )
function_declaration ::=
_identifier ( ( '(' _newline? ( typed_parameter _newline? ( ',' typed_parameter _newline? )* ','? )? _newline? ')' ) | ( '(' _newline? parameter ( ( type_identifier | field_expression ) )? _newline? ( ',' parameter ( ( type_identifier | field_expression ) )? _newline? )* ','? _newline? ')' ) )
method_declaration ::=
_identifier method_parameter_list
parenthesized_expression ::=
'(' ( _identifier | binary_operator | _expression ) ')'
method_parameter_list ::=
'(' _newline? self ','? ( parameter _newline? ( ',' parameter _newline? )* ','? )? _newline? ')'
typed_parameter ::=
_identifier ( type_identifier | field_expression )
parameter ::=
_expression | _identifier type_identifier?
typed_statement ::=
_type type_identifier ( field_expression | _identifier ) ( object_definition | _newline )
object_definition ::=
_scope_start object_block
_object_member ::=
_identifier type_identifier | field_expression _newline
object_block ::=
_indent _object_member+ _statement* _dedent
type_alias ::=
_newline
tagtype_declaration ::=
'tagtype' _identifier _tagtype_body?
_tagtype_body ::=
_identifier ( ',' _identifier )*
_expression_statement ::=
_expression
if_statement ::=
'if' _if_statement _else_statement*
_if_statement ::=
_expression _block_group
if_statement_inline ::=
_expression _statement
_else_statement ::=
else_identifier _expression? _block_group
match_statement ::=
'match' _expression match_block
match_block ::=
_scope_start _indent match_case+ _dedent
match_case ::=
( _expression | _expression ( ',' _expression )+ | else_identifier ) ':' ( _standard_statement | _expression )
match_default ::=
else_identifier _block_group
loop_statement ::=
'loop' _block_group
while_loop ::=
'while' _expression? ( 'some' _identifier )? _block_group
for_range_loop ::=
'for' _for_range_loop
for_iterable_loop ::=
'for' _for_iterable_loop
_for_range_loop ::=
( range_expression | _expression '..' '='? _expression ) ( ',' _expression )? ( 'each' _identifier )? _block_group
_for_iterable_loop ::=
_expression 'each' _identifier ( ',' _identifier )? _block_group
try_statement ::=
try_identifier _block_group catch_statement
catch_identifier ::=
'catch'
catch_statement ::=
catch_identifier _identifier? catch_block
catch_block ::=
_scope_start _indent _statement+ ( _dedent | _newline )
coyield_statement ::=
coyield _newline
print_statement ::=
'print' _expression
exit_statement ::=
'exit' numeric_literal
return_statement ::=
'return' ( _expression _newline? ( ',' _expression _newline? )* ','? )? _newline?
_block_group ::=
inline_block | block
inline_block ::=
_inline_statement _statement _newline
block ::=
_scope_start _indent _statement+ _dedent
recover_block ::=
'recover' _identifier _block_group
_expressions ::=
_expression
| expression_list
_expression ::=
parenthesized_expression | _identifier | numeric_literal | string | encoded_string | multiline_string | boolean | binary_operator | boolean_operator | negation_operator | comparison_operator | object_initializer | augmented_assignment | if_expression | lambda_multiline | cfunc_call | cstruct_call | field_expression | range_expression | call_expression | type_cast | lambda_expression | capture_expression | lambda_call | static_expression | error_expression | throw_expression | try_expression | try_else_expression | catch_expression | panic_expression | coinit_expression | coresume_expression | enclosed_expression | tag_expression | index_expression
or_operator ::=
'or'
and_operator ::=
'and'
not_operator ::=
'not'
bang_operator ::=
'!'
boolean_operator ::=
_expression and_operator _expression | _expression or_operator _expression | ( not_operator | bang_operator ) _expression
binary_operator ::=
parameter '+' parameter | '+' parameter | parameter '+'
| parameter '-' parameter | '-' parameter | parameter '-'
| parameter '*' parameter | '*' parameter | parameter '*'
| parameter '@' parameter | '@' parameter | parameter '@'
| parameter '/' parameter | '/' parameter | parameter '/'
| parameter '%' parameter | '%' parameter | parameter '%'
| parameter '//' parameter | '//' parameter | parameter '//'
| parameter '|' parameter | '|' parameter | parameter '|'
| parameter '||' parameter | '||' parameter | parameter '||'
| parameter '~' parameter | '~' parameter | parameter '~'
| parameter '&' parameter | '&' parameter | parameter '&'
| parameter '^' parameter | '^' parameter | parameter '^'
| parameter '<<' parameter | '<<' parameter | parameter '<<'
| parameter '>>' parameter | '>>' parameter | parameter '>>'
arithmetic_expression ::=
( parameter '+' )+ | ( '+' parameter )+ | ( '+'? parameter '+' )+ | '+' numeric_literal | numeric_literal '+' | numeric_literal '+' numeric_literal | _expression '+' | '+' _expression | _expression '+' numeric_literal | numeric_literal '+' _expression
| ( parameter '-' )+ | ( '-' parameter )+ | ( '-'? parameter '-' )+ | '-' numeric_literal | numeric_literal '-' | numeric_literal '-' numeric_literal | _expression '-' | '-' _expression | _expression '-' numeric_literal | numeric_literal '-' _expression
| ( parameter '*' )+ | ( '*' parameter )+ | ( '*'? parameter '*' )+ | '*' numeric_literal | numeric_literal '*' | numeric_literal '*' numeric_literal | _expression '*' | '*' _expression | _expression '*' numeric_literal | numeric_literal '*' _expression
| ( parameter '@' )+ | ( '@' parameter )+ | ( '@'? parameter '@' )+ | '@' numeric_literal | numeric_literal '@' | numeric_literal '@' numeric_literal | _expression '@' | '@' _expression | _expression '@' numeric_literal | numeric_literal '@' _expression
| ( parameter '/' )+ | ( '/' parameter )+ | ( '/'? parameter '/' )+ | '/' numeric_literal | numeric_literal '/' | numeric_literal '/' numeric_literal | _expression '/' | '/' _expression | _expression '/' numeric_literal | numeric_literal '/' _expression
| ( parameter '%' )+ | ( '%' parameter )+ | ( '%'? parameter '%' )+ | '%' numeric_literal | numeric_literal '%' | numeric_literal '%' numeric_literal | _expression '%' | '%' _expression | _expression '%' numeric_literal | numeric_literal '%' _expression
| ( parameter '//' )+ | ( '//' parameter )+ | ( '//'? parameter '//' )+ | '//' numeric_literal | numeric_literal '//' | numeric_literal '//' numeric_literal | _expression '//' | '//' _expression | _expression '//' numeric_literal | numeric_literal '//' _expression
| ( parameter '|' )+ | ( '|' parameter )+ | ( '|'? parameter '|' )+ | '|' numeric_literal | numeric_literal '|' | numeric_literal '|' numeric_literal | _expression '|' | '|' _expression | _expression '|' numeric_literal | numeric_literal '|' _expression
| ( parameter '||' )+ | ( '||' parameter )+ | ( '||'? parameter '||' )+ | '||' numeric_literal | numeric_literal '||' | numeric_literal '||' numeric_literal | _expression '||' | '||' _expression | _expression '||' numeric_literal | numeric_literal '||' _expression
| ( parameter '~' )+ | ( '~' parameter )+ | ( '~'? parameter '~' )+ | '~' numeric_literal | numeric_literal '~' | numeric_literal '~' numeric_literal | _expression '~' | '~' _expression | _expression '~' numeric_literal | numeric_literal '~' _expression
| ( parameter '&' )+ | ( '&' parameter )+ | ( '&'? parameter '&' )+ | '&' numeric_literal | numeric_literal '&' | numeric_literal '&' numeric_literal | _expression '&' | '&' _expression | _expression '&' numeric_literal | numeric_literal '&' _expression
| ( parameter '^' )+ | ( '^' parameter )+ | ( '^'? parameter '^' )+ | '^' numeric_literal | numeric_literal '^' | numeric_literal '^' numeric_literal | _expression '^' | '^' _expression | _expression '^' numeric_literal | numeric_literal '^' _expression
| ( parameter '<<' )+ | ( '<<' parameter )+ | ( '<<'? parameter '<<' )+ | '<<' numeric_literal | numeric_literal '<<' | numeric_literal '<<' numeric_literal | _expression '<<' | '<<' _expression | _expression '<<' numeric_literal | numeric_literal '<<' _expression
| ( parameter '>>' )+ | ( '>>' parameter )+ | ( '>>'? parameter '>>' )+ | '>>' numeric_literal | numeric_literal '>>' | numeric_literal '>>' numeric_literal | _expression '>>' | '>>' _expression | _expression '>>' numeric_literal | numeric_literal '>>' _expression
negation_operator ::=
( '-' ) ( parenthesized_expression )
comparison_operator ::=
( numeric_literal | _expression ) ( '<' | '<=' | '==' | '!=' | '>=' | '>' | '<>' | 'in' | not_operator 'in' | 'is' | 'is' not_operator ) ( numeric_literal | _expression )
augmented_assignment ::=
_left_hand_side ( '+=' | '-=' | '*=' | '/=' ) _right_hand_side
_left_hand_side ::=
pattern
_right_hand_side ::=
_expression _newline? ( ',' _expression _newline? )* ','? | augmented_assignment
pattern ::=
_identifier
| index_expression
| range_expressions
| tag_expression
| call_expression
| field_expression
pattern_list ::=
pattern pattern ( ',' pattern )+
expression_list ::=
_expression ( ',' _expression )+
if_expression ::=
'if' _expression 'then' _expression else_identifier _expression
accessor ::=
( _expression '.' )+
field_expression ::=
_expression '.' ( accessor | _expression )
call_expression ::=
_identifier '(' _newline?( parameter _newline? ( ',' parameter _newline? )* ','?)? _newline? ')'
object_initializer ::=
type_identifier _open_brace ( member_assignment | member_assignment ( ','? member_assignment )+ ) ','? _close_brace
member_assignment ::=
_identifier ':' _expression ','? _newline?
argument_list ::=
_expression ( ',' _expression )+
as_identifier ::=
'as'
type_cast ::=
_expression as_identifier type_identifier
lambda_operator ::=
'=>'
anon_identifier ::=
'(' ')'
lambda_function ::=
_func anon_identifier | _func '(' _newline? parameter _newline? ( ',' parameter _newline? )* ','? _newline? ')'
lambda_multiline ::=
lambda_function _block_group?
lambda_call ::=
parenthesized_expression '(' ( parameter _newline? ( ',' parameter _newline? )* ','? )? ')'
lambda_expression ::=
anon_identifier lambda_operator _expression | '(' _newline? parameter _newline? ( ',' parameter _newline? )* ','? _newline? ')' lambda_operator _expression | _expression lambda_operator _expression
capture_identifier ::=
'capture'
capture_expression ::=
capture_identifier _expression
static_identifier ::=
'static'
static_expression ::=
static_identifier _expression
error_expression ::=
error '.' _expression | error _open_paren _expression _close_paren
try_expression ::=
try_identifier _expression else_expression | try_identifier _expression
else_expression ::=
else_identifier _expression
try_else_expression ::=
try_expression else_expression
catch_expression ::=
catch_identifier _expression ( 'then' _expression )? ( as_identifier _identifier 'then' _expression )?
panic_expression ::=
panic_identifier _expression
throw_expression ::=
throw_identifier _expression
cfunc_call ::=
cfunc _open_brace symbol_parameter args_parameter ret_parameter _close_brace
symbol_parameter ::=
'sym' ':' string ','
args_parameter ::=
'args' ':' array_contents ','
ret_parameter ::=
'ret' ':' ( _identifier | tag_expression )
cstruct_call ::=
'CStruct' _open_brace fields_parameter object_parameter _close_brace
fields_parameter ::=
'fields' ':' array_contents ','
object_parameter ::=
'type' ':' _identifier
find_rune ::=
'findRune' _open_paren ( encoded_string | string | numeric_literal ) _close_paren
tag_expression ::=
'#' _identifier
coinit_expression ::=
coinit coinit_declaration
coinit_declaration ::=
_identifier ( '.' ( _identifier '.' )* )? ( '(' _newline? ( parameter _newline? ( ',' parameter _newline? )* ','? )? _newline? ')' )
coresume_expression ::=
coresume _expression
range_expressions ::=
range_expression
range_expression ::=
_identifier range_operator _identifier
index_expression ::=
_expression ( _open_bracket ( array_contents | slice ) _close_bracket )
key_value_pair ::=
_expression ':' _expression
slice ::=
( range_operator _expression | _expression range_operator | _expression range_operator _expression )
map_literal ::=
( key_value_pair ( ',' _newline? key_value_pair )+ | (key_value_pair ','? _newline?)+ )
enclosed_expression ::=
object_initializer
| _open_paren _expression _close_paren
| ( _open_bracket array_contents? _close_bracket )
| _open_brace map_literal? _close_brace
array_contents ::=
_expression _newline? ( ','? _expression _newline? )* ','?
_statement_indicator ::=
':'
true ::=
'true'
false ::=
'false'
none ::=
'none'
self ::=
'self'
_type ::=
'type'
_func ::=
'func'
error ::=
'error'
cfunc ::=
'CFunc'
try_identifier ::=
'try'
else_identifier ::=
'else'
panic_identifier ::=
'panic'
throw_identifier ::=
'throw'
range_operator ::=
'..'
func ::=
'func'
ident ::=
[a-zA-Z\x80-\xff]('_'?[a-zA-Z0-9\x80-\xff])*
boolean ::=
'true'
| 'false'
| 'none'
coinit ::=
'coinit'
coresume ::=
'coresume'
coyield ::=
'coyield'
_open_paren ::=
'open_paren'
_close_paren ::=
')'
_open_brace ::=
'{'
_close_brace ::=
'}'
_open_bracket ::=
'['
_close_bracket ::=
']'
keyword_identifier ::=
( 'async' | 'await' | 'coinit' | 'coyield' | 'coresume' | 'recover' | 'panic' | 'try' | 'catch' | 'if' | 'then' | 'as' | 'none' | 'atype' | 'any' | 'typeid' | 'type' | 'object' | 'match' | 'in' | 'is' | 'not' | 'true' | 'false' | 'print' | 'insert' | 'remove' | 'indexChar' )
Would be nice to have a railroad diagram for
cyber, using https://mingodad.github.io/plgh/json2ebnf.html and manually fixing small tool mistakes we get an EBNF understood by https://github.com/GuntherRademacher/rr that can generate nice navigable railroad diagrams see bellow with instructions at the top.