Skip to content

Grammar railroad diagram #126

@mingodad

Description

@mingodad

On https://github.com/c3lang/c3c/blob/master/resources/grammar/grammar.y they have a fully working grammar using bison/flex and that can be used to make a C2lang grammar.

Another option is to use the EBNF generated from that grammar that can be understood by (IPV4) https://rr.red-dove.com/ui or (IPV6) https://www.bottlecaps.de/rr/ui to also trim down/expand to a c2lang grammar with a nice navigable railroad diagram (see instructions bellow at the top).

//
// 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 Mon Sep 16, 2024, 15:37 (UTC+02) by bison-to-w3c v0.68-SNAPSHOT which is Copyright (c) 2011-2024 by Gunther Rademacher <grd@gmx.net> */

start_here ::= translation_unit // to navigate from the top

path     ::= ( IDENT SCOPE )+

path_const ::= path? CONST_IDENT

path_ident ::= path? IDENT

path_at_ident ::= path? AT_IDENT

ident_expr ::= CONST_IDENT
	| IDENT
	| AT_IDENT

local_ident_expr ::= CT_IDENT
	| HASH_IDENT

ct_call  ::= CT_ALIGNOF
	| CT_EXTNAMEOF
	| CT_NAMEOF
	| CT_OFFSETOF
	| CT_QNAMEOF

ct_castable ::= CT_ASSIGNABLE

ct_analyse ::= CT_EVAL
	| CT_SIZEOF
	| CT_STRINGIFY
	| CT_IS_CONST

ct_vaarg ::= CT_VACONST
	| CT_VAARG
	| CT_VAREF
	| CT_VAEXPR

flat_path ::= primary_expr param_path?
	| type

maybe_optional_type ::= optional_type
	| /*empty*/

string_expr ::= STRING_LITERAL+

expr_block ::= LBRAPIPE opt_stmt_list RBRAPIPE

base_expr ::= string_expr
	| INTEGER
	| BYTES+
	| NUL
	| CHAR_LITERAL
	| REAL
	| TRUE
	| FALSE
	| base_expr_assignable

base_expr_assignable ::= BUILTIN ( CONST_IDENT | IDENT )
	| path? ident_expr
	| local_ident_expr
	| type ( initializer_list | '.' ( access_ident | CONST_IDENT ) )
	| ( '(' expr | ct_call '(' flat_path | ct_analyse '(' expression_list | CT_DEFINED '(' arg_list | CT_FEATURE '(' CONST_IDENT | ct_castable '(' expr ',' type ) ')'
	| expr_block
	| ct_vaarg '[' expr ']'
	| CT_VACOUNT
	| lambda_decl compound_statement

primary_expr ::= base_expr
	| initializer_list

range_loc ::= '^'? expr

range_expr ::= ( range_loc ( DOTDOT | ':' ) | DOTDOT ) range_loc?
	| ':' range_loc

call_invocation ::= '(' call_arg_list ')' AT_IDENT*

access_ident ::= IDENT
	| AT_IDENT
	| HASH_IDENT
	| CT_EVAL '(' expr ')'
	| TYPEID

call_trailing ::= '[' ( range_loc | range_expr ) ']'
	| call_invocation compound_statement?
	| '.' access_ident
	| generic_expr
	| INC_OP
	| DEC_OP
	| '!'
	| BANGBANG

call_expr ::= primary_expr call_trailing*

unary_expr ::= unary_op* call_expr

unary_stmt_expr ::= base_expr_assignable call_trailing*
	| unary_op unary_expr

unary_op ::= '&'
	| AND_OP
	| '*'
	| '+'
	| '-'
	| '~'
	| '!'
	| INC_OP
	| DEC_OP
	| '(' type ')'

mult_op  ::= '*'
	| '/'
	| '%'

mult_expr ::= unary_expr ( mult_op unary_expr )*

shift_op ::= SHL_OP
	| SHR_OP

shift_expr ::= mult_expr ( shift_op mult_expr )*

bit_op   ::= '&'
	| '^'
	| '|'

bit_expr ::= shift_expr ( bit_op shift_expr )*

additive_op ::= '+'
	| '-'
	| CT_CONCAT_OP

additive_expr ::= bit_expr ( additive_op bit_expr )*

relational_op ::= '<'
	| '>'
	| LE_OP
	| GE_OP
	| EQ_OP
	| NE_OP

relational_expr ::= additive_expr ( relational_op additive_expr )*

try_catch_rhs_expr ::= call_expr
	| lambda_decl IMPLIES relational_expr

try_chain_expr ::= ( lambda_decl IMPLIES )? relational_expr

and_expr ::= relational_expr ( ( AND_OP | CT_AND_OP ) relational_expr )*

or_expr  ::= and_expr ( ( OR_OP | CT_OR_OP ) and_expr )*

or_stmt_expr ::= unary_stmt_expr ( mult_op unary_expr )* ( shift_op mult_expr )* ( bit_op shift_expr )* ( additive_op bit_expr )* ( relational_op additive_expr )* ( ( AND_OP | CT_AND_OP ) relational_expr )* ( ( OR_OP | CT_OR_OP ) and_expr )*

suffix_expr ::= or_expr ( '?' '!'? )?

suffix_stmt_expr ::= or_stmt_expr ( '?' '!'? )?

ternary_expr ::= ( or_expr '?' expr ':' | suffix_expr ( ELVIS | OPTELSE ) )* ( suffix_expr | lambda_decl implies_body )

ternary_stmt_expr ::= suffix_stmt_expr ( ( ELVIS | OPTELSE ) ternary_expr )?
	| or_stmt_expr '?' expr ':' ternary_expr
	| lambda_decl implies_body

assignment_op ::= '='
	| ADD_ASSIGN
	| SUB_ASSIGN
	| MUL_ASSIGN
	| DIV_ASSIGN
	| MOD_ASSIGN
	| SHL_ASSIGN
	| SHR_ASSIGN
	| AND_ASSIGN
	| XOR_ASSIGN
	| OR_ASSIGN

assignment_expr ::= ( unary_expr assignment_op )* ( ternary_expr | CT_TYPE_IDENT '=' type )

assignment_stmt_expr ::= ternary_stmt_expr
	| CT_TYPE_IDENT '=' type
	| unary_stmt_expr assignment_op assignment_expr

implies_body ::= IMPLIES expr

lambda_decl ::= FN maybe_optional_type fn_parameter_list opt_attributes

expr_no_list ::= assignment_stmt_expr

expr     ::= assignment_expr

constant_expr ::= ternary_expr

param_path_element ::= '[' expr ( DOTDOT expr )? ']'
	| '.' primary_expr

param_path ::= param_path_element+

arg_name ::= IDENT
	| CT_TYPE_IDENT
	| HASH_IDENT
	| CT_IDENT

arg      ::= param_path ( '=' ( expr | type ) )?
	| arg_name ':' ( expr | type )
	| type
	| ELLIPSIS? expr
	| CT_VASPLAT ( '[' range_expr ']' )?

arg_list ::= arg ( ',' arg? )*

opt_arg_list ::= arg_list
	| /*empty*/

call_arg_list ::= opt_arg_list ( ';' parameters? )?

opt_interface_impl ::= '(' ( TYPE_IDENT opt_generic_parameters ( ',' TYPE_IDENT opt_generic_parameters )* )? ')'
	| /*empty*/

enum_constants ::= enum_constant ( ',' enum_constant )*

enum_list ::= enum_constants ','?

enum_constant ::= CONST_IDENT opt_attributes ( '=' constant_expr )?

enum_param_decl ::= type IDENT

base_type ::= VOID
	| BOOL
	| CHAR
	| ICHAR
	| SHORT
	| USHORT
	| INT
	| UINT
	| LONG
	| ULONG
	| INT128
	| UINT128
	| FLOAT
	| DOUBLE
	| FLOAT16
	| BFLOAT16
	| FLOAT128
	| IPTR
	| UPTR
	| ISZ
	| USZ
	| ANYFAULT
	| ANY
	| TYPEID
	| path? TYPE_IDENT opt_generic_parameters
	| CT_TYPE_IDENT
	| ( CT_TYPEOF '(' expr | ( CT_TYPEFROM | CT_EVALTYPE ) '(' constant_expr ) ')'
	| CT_VATYPE '[' constant_expr ']'

type     ::= base_type ( '*' | '[' ( constant_expr | '*' )? ']' | LVEC ( constant_expr | '*' ) RVEC )*

optional_type ::= type '!'?

local_decl_after_type ::= CT_IDENT ( '=' constant_expr )?
	| IDENT opt_attributes ( '=' expr )?

local_decl_storage ::= STATIC
	| TLOCAL

decl_or_expr ::= var_decl
	| optional_type local_decl_after_type
	| expr

var_decl ::= VAR ( IDENT '=' expr | CT_IDENT ( '=' expr )? | CT_TYPE_IDENT ( '=' type )? )

initializer_list ::= '{' opt_arg_list '}'

ct_case_stmt ::= ( CT_CASE ( constant_expr | type ) | CT_DEFAULT ) ':' opt_stmt_list

ct_for_stmt ::= CT_FOR '(' for_cond ')' opt_stmt_list CT_ENDFOR

ct_foreach_stmt ::= CT_FOREACH '(' CT_IDENT ( ',' CT_IDENT )? ':' expr ')' opt_stmt_list CT_ENDFOREACH

ct_switch ::= CT_SWITCH ( '(' ( constant_expr | type ) ')' )?

ct_switch_stmt ::= ct_switch ct_case_stmt+ CT_ENDSWITCH

var_stmt ::= var_decl ';'

decl_stmt_after_type ::= local_decl_after_type ( ',' local_decl_after_type )*

declaration_stmt ::= const_declaration
	| local_decl_storage? optional_type decl_stmt_after_type ';'

return_stmt ::= RETURN expr? ';'

catch_unwrap_list ::= relational_expr ( ',' relational_expr )*

catch_unwrap ::= CATCH ( type? IDENT '=' )? catch_unwrap_list

try_unwrap ::= TRY ( try_catch_rhs_expr | type? IDENT '=' try_chain_expr )

try_unwrap_chain ::= try_unwrap ( AND_OP ( try_unwrap | try_chain_expr ) )*

default_stmt ::= DEFAULT ':' opt_stmt_list

case_stmt ::= CASE ( expr ( DOTDOT expr )? | type ) ':' opt_stmt_list

switch_body ::= ( case_stmt | default_stmt )+

cond_repeat ::= decl_or_expr ( ',' decl_or_expr )*

cond     ::= try_unwrap_chain
	| catch_unwrap
	| cond_repeat ( ',' ( try_unwrap_chain | catch_unwrap ) )?

else_part ::= ELSE ( if_stmt | compound_statement )

if_stmt  ::= IF optional_label paren_cond ( '{' switch_body '}' else_part? | statement | compound_statement else_part )

expr_list_eos ::= expression_list? ';'

cond_eos ::= cond? ';'

for_cond ::= expr_list_eos cond_eos expression_list?

for_stmt ::= FOR optional_label '(' for_cond ')' statement

paren_cond ::= '(' cond ')'

while_stmt ::= WHILE optional_label paren_cond statement

do_stmt  ::= DO optional_label compound_statement ( WHILE '(' expr ')' )? ';'

optional_label_target ::= CONST_IDENT
	| /*empty*/

continue_stmt ::= CONTINUE optional_label_target ';'

break_stmt ::= BREAK optional_label_target ';'

nextcase_stmt ::= NEXTCASE ( ( CONST_IDENT ':' )? ( expr | type | DEFAULT ) )? ';'

foreach_var ::= optional_type? '&'? IDENT

foreach_vars ::= foreach_var ( ',' foreach_var )?

foreach_stmt ::= ( FOREACH | FOREACH_R ) optional_label '(' foreach_vars ':' expr ')' statement

defer_stmt ::= DEFER ( TRY | CATCH | '(' CATCH IDENT ')' )? statement

ct_if_stmt ::= CT_IF constant_expr ':' opt_stmt_list ( CT_ELSE opt_stmt_list )? CT_ENDIF

assert_stmt ::= ASSERT '(' expr ( ',' expr )* ')' ';'

asm_stmts ::= asm_stmt+

asm_instr ::= ( INT | IDENT ) ( '.' IDENT )?

asm_addr ::= asm_expr ( additive_op asm_expr ( ( '*' ( INTEGER additive_op )? | shift_op | additive_op ) INTEGER )? )?

asm_expr ::= CT_IDENT
	| CT_CONST_IDENT
	| '&'? IDENT
	| CONST_IDENT
	| REAL
	| INTEGER
	| '(' expr ')'
	| '[' asm_addr ']'

asm_stmt ::= asm_instr ( asm_expr ( ',' asm_expr )* )? ';'

asm_block_stmt ::= ASM ( '(' constant_expr ')' AT_IDENT? ';' | AT_IDENT? '{' asm_stmts? '}' )

statement ::= compound_statement
	| var_stmt
	| declaration_stmt
	| return_stmt
	| if_stmt
	| while_stmt
	| defer_stmt
	| switch_stmt
	| do_stmt
	| for_stmt
	| foreach_stmt
	| continue_stmt
	| break_stmt
	| nextcase_stmt
	| asm_block_stmt
	| ct_echo_stmt
	| ct_assert_stmt
	| ct_if_stmt
	| ct_switch_stmt
	| ct_foreach_stmt
	| ct_for_stmt
	| expr_no_list? ';'
	| assert_stmt

compound_statement ::= '{' opt_stmt_list '}'

opt_stmt_list ::= statement+
	| /*empty*/

switch_stmt ::= SWITCH optional_label ( paren_cond opt_attributes )? '{' switch_body? '}'

expression_list ::= decl_or_expr ( ',' decl_or_expr )*

optional_label ::= CONST_IDENT ':'
	| /*empty*/

ct_assert_stmt ::= ( CT_ASSERT ( constant_expr ':' )? | CT_ERROR ) constant_expr ';'

ct_include_stmt ::= CT_INCLUDE string_expr ';'

ct_echo_stmt ::= CT_ECHO constant_expr ';'

bitstruct_declaration ::= BITSTRUCT TYPE_IDENT opt_interface_impl ':' type opt_attributes bitstruct_body

bitstruct_body ::= '{' ( bitstruct_def* | ( base_type IDENT ';' )+ ) '}'

bitstruct_def ::= base_type IDENT ':' constant_expr ( DOTDOT constant_expr )? ';'

attribute_name ::= AT_IDENT
	| path? AT_TYPE_IDENT

attribute_operator_expr ::= '&' '[' ']'
	| '[' ']' '='?

attr_param ::= attribute_operator_expr
	| constant_expr

attribute ::= attribute_name ( '(' attr_param ( ',' attr_param )* ')' )?

opt_attributes ::= attribute+
	| /*empty*/

trailing_block_param ::= AT_IDENT ( '(' parameters? ')' )?

macro_params ::= parameters ( ';' trailing_block_param )?
	| ';' trailing_block_param
	| /*empty*/

macro_func_body ::= implies_body ';'
	| compound_statement

macro_declaration ::= MACRO macro_header '(' macro_params ')' opt_attributes macro_func_body

struct_or_union ::= STRUCT
	| UNION

struct_declaration ::= struct_or_union TYPE_IDENT opt_interface_impl opt_attributes struct_body

struct_body ::= '{' struct_member_decl+ '}'

enum_params ::= enum_param_decl ( ',' enum_param_decl )*

struct_member_decl ::= ( type IDENT ( ',' IDENT )* | INLINE type IDENT? ) opt_attributes ';'
	| struct_or_union IDENT? opt_attributes struct_body
	| BITSTRUCT IDENT? ':' type opt_attributes bitstruct_body

enum_spec ::= ':' ( base_type ( '(' enum_params ')' )? | '(' enum_params ')' )

enum_declaration ::= ENUM TYPE_IDENT opt_interface_impl enum_spec? opt_attributes '{' enum_list '}'

faults   ::= CONST_IDENT ( ',' CONST_IDENT )*

fault_declaration ::= FAULT TYPE_IDENT opt_interface_impl opt_attributes '{' faults ','? '}'

func_macro_name ::= IDENT
	| AT_IDENT

func_header ::= optional_type ( type '.' )? func_macro_name

macro_header ::= func_header
	| ( type '.' )? func_macro_name

fn_parameter_list ::= '(' parameters? ')'

parameter_default ::= parameter ( '=' expr )?

parameters ::= parameter_default ( ',' parameter_default? )*

parameter ::= type ( ( '&'? IDENT | HASH_IDENT )? opt_attributes | ELLIPSIS ( IDENT? opt_attributes | CT_IDENT ) | CT_IDENT )
	| ( '&' IDENT | HASH_IDENT | IDENT ELLIPSIS? ) opt_attributes
	| ELLIPSIS
	| CT_IDENT ELLIPSIS?

func_defintion_decl ::= FN func_header fn_parameter_list opt_attributes ';'

func_definition ::= func_defintion_decl
	| FN func_header fn_parameter_list opt_attributes macro_func_body

const_declaration ::= CONST ( CONST_IDENT opt_attributes '=' expr | type CONST_IDENT opt_attributes ( '=' expr )? ) ';'

func_typedef ::= FN optional_type fn_parameter_list

opt_inline ::= INLINE
	| /*empty*/

typedef_type ::= func_typedef
	| type

global_storage ::= TLOCAL
	| /*empty*/

global_declaration ::= global_storage optional_type IDENT ( opt_attributes ( '=' expr )? | ( ',' IDENT )+ opt_attributes ) ';'

define_attribute ::= AT_TYPE_IDENT ( '(' parameters ')' )? opt_attributes '=' '{' opt_attributes '}'

generic_expr ::= LGENPAR ( expr | type ) ( ',' ( expr | type ) )* RGENPAR

opt_generic_parameters ::= generic_expr
	| /*empty*/

define_ident ::= ( IDENT '=' path_ident | CONST_IDENT '=' path_const | AT_IDENT '=' path_at_ident ) opt_generic_parameters

define_declaration ::= DEF ( define_ident | define_attribute | TYPE_IDENT opt_attributes '=' typedef_type ) opt_attributes ';'

interface_declaration ::= INTERFACE TYPE_IDENT '{' func_defintion_decl* '}'

distinct_declaration ::= DISTINCT TYPE_IDENT opt_interface_impl opt_attributes '=' opt_inline type ';'

module_param ::= CONST_IDENT
	| TYPE_IDENT

module   ::= MODULE path_ident ( LGENPAR module_param ( ',' module_param )* RGENPAR )? opt_attributes ';'

import_decl ::= IMPORT path_ident ( ',' path_ident )* opt_attributes ';'

translation_unit ::= top_level+
	| /*empty*/

opt_extern ::= EXTERN
	| /*empty*/

exec_decl ::= CT_EXEC '(' expr ( ',' initializer_list ( ',' expr )? )? ')' opt_attributes ';'

top_level ::= module
	| import_decl
	| exec_decl
	| opt_extern ( func_definition | const_declaration | global_declaration )
	| ct_assert_stmt
	| ct_echo_stmt
	| ct_include_stmt
	| struct_declaration
	| fault_declaration
	| enum_declaration
	| macro_declaration
	| define_declaration
	| bitstruct_declaration
	| distinct_declaration
	| interface_declaration

//
// Tokens
//

//\("[^"]+"\)\s+{\s*count(); return(\([^)]+\)).+  -> \2 ::= \1
//\(\S+\)\s+\(\S+\)  -> \2 ::= \1

CT_ALIGNOF ::= "$alignof"
CT_ASSERT ::= "$assert"
CT_ASSIGNABLE ::= "$assignable"
CT_CASE ::= "$case"
CT_DEFAULT ::= "$default"
CT_DEFINED ::= "$defined"
CT_ECHO ::= "$echo"
CT_ELSE ::= "$else"
CT_ENDFOR ::= "$endfor"
CT_ENDFOREACH ::= "$endforeach"
CT_ENDIF ::= "$endif"
CT_ENDSWITCH ::= "$endswitch"
CT_ERROR ::= "$error"
CT_EVAL ::= "$eval"
CT_EVALTYPE ::= "$evaltype"
CT_EXEC ::= "$exec"
CT_EXTNAMEOF ::= "$extnameof"
CT_FEATURE ::= "$feature"
CT_FOR ::= "$for"
CT_FOREACH ::= "$foreach"
CT_IF ::= "$if"
CT_IS_CONST ::= "$is_const"
CT_INCLUDE ::= "$include"
CT_NAMEOF ::= "$nameof"
CT_OFFSETOF ::= "$offsetof"
CT_QNAMEOF ::= "$qnameof"
CT_SIZEOF ::= "$sizeof"
CT_STRINGIFY ::= "$stringify"
CT_SWITCH ::= "$switch"
CT_TYPEFROM ::= "$typefrom"
CT_TYPEOF ::= "$typeof"
CT_VAARG ::= "$vaarg"
CT_VACONST ::= "$vaconst"
CT_VACOUNT ::= "$vacount"
CT_VAEXPR ::= "$vaexpr"
CT_VAREF ::= "$varef"
CT_VASPLAT ::= "$vasplat"
CT_VATYPE ::= "$vatype"

ANY ::= "any"
ANYFAULT ::= "anyfault"
ASM ::= "asm"
ASSERT ::= "assert"
BITSTRUCT ::= "bitstruct"
BOOL ::= "bool"
BREAK ::= "break"
CASE ::= "case"
CATCH ::= "catch"
CHAR ::= "char"
CONST ::= "const"
CONTINUE ::= "continue"
DEF ::= "def"
DEFAULT ::= "default"
DEFER ::= "defer"
DISTINCT ::= "distinct"
DO ::= "do"
DOUBLE ::= "double"
ELSE ::= "else"
ENUM ::= "enum"
EXTERN ::= "extern"
FALSE ::= "false"
FAULT ::= "fault"
FLOAT ::= "float"
BFLOAT16 ::= "bfloat16"
FLOAT16 ::= "float16"
FLOAT128 ::= "float128"
FN ::= "fn"
FOR ::= "for"
FOREACH ::= "foreach"
FOREACH_R ::= "foreach_r"
ICHAR ::= "ichar"
IF ::= "if"
IMPORT ::= "import"
INLINE ::= "inline"
INT ::= "int"
INT128 ::= "int128"
IPTR ::= "iptr"
ISZ ::= "isz"
LONG ::= "long"
MACRO ::= "macro"
MODULE ::= "module"
NEXTCASE ::= "nextcase"
NUL ::= "null"
RETURN ::= "return"
SHORT ::= "short"
STRUCT ::= "struct"
STATIC ::= "static"
SWITCH ::= "switch"
TLOCAL ::= "tlocal"
TRUE ::= "true"
TRY ::= "try"
TYPEID ::= "typeid"
UINT ::= "uint"
UINT128 ::= "uint128"
ULONG ::= "ulong"
UNION ::= "union"
UPTR ::= "uptr"
USHORT ::= "ushort"
USZ ::= "usz"
VAR ::= "var"
VOID ::= "void"
WHILE ::= "while"

INTERFACE ::= "interface"
CT_ASSIGNABLE ::= CT_ASSIGNABLE
CT_IS_CONST ::= CT_IS_CONST



ELLIPSIS ::= "..."
DOTDOT ::= ".."
CT_AND_OP ::= "&&&"
CT_OR_OP ::= "|||"
CT_CONCAT_OP ::= "+++"
SHR_ASSIGN ::= ">>="
SHL_ASSIGN ::= "<<="
ADD_ASSIGN ::= "+="
SUB_ASSIGN ::= "-="
MUL_ASSIGN ::= "*="
DIV_ASSIGN ::= "/="
MOD_ASSIGN ::= "%="
AND_ASSIGN ::= "&="
XOR_ASSIGN ::= "^="
OR_ASSIGN ::= "|="
SHR_OP ::= ">>"
SHL_OP ::= "<<"
INC_OP ::= "++"
DEC_OP ::= "--"
AND_OP ::= "&&"
OR_OP ::= "||"
LE_OP ::= "<="
GE_OP ::= ">="
EQ_OP ::= "=="
NE_OP ::= "!="
OPTELSE ::= "??"
SCOPE ::= "::"
ELVIS ::= "?:"
IMPLIES ::= "=>"
LVEC ::= "[<"
RVEC ::= ">]"
LGENPAR ::= "(<"
RGENPAR ::= ">)"
BUILTIN ::= "$$"
BANGBANG ::= "!!"
LBRAPIPE ::= "{|"
RBRAPIPE ::= "|}"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions