Skip to content

Grammar railroad diagram #105

Description

@mingodad

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.

//
// 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' )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions