Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar railroad diagram #126

Open
mingodad opened this issue Sep 20, 2024 · 2 comments
Open

Grammar railroad diagram #126

mingodad opened this issue Sep 20, 2024 · 2 comments

Comments

@mingodad
Copy link

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 <[email protected]> */

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 ::= "|}"
@bvdberg
Copy link
Member

bvdberg commented Sep 20, 2024

I think all people starting to write a language start with bison/yacc/flex. Then they all arrive to the same conclusion; it doesn't really work nicely in that it becomes one big mess. A custom tokenizer with a handwritten parser is much easier and faster, so that's where they all end up :)

What you a clickable EBNF have as advantage?

@mingodad
Copy link
Author

What you a clickable EBNF have as advantage?
Documentation !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants