1. Felix Grammar


semi:
  | SEMI

exprx:
expr expr_terminator

expr_terminator:
  | SEMI
  | USER_KEYWORD
  | VBAR
  | ENDMARKER
  | ALL
  | ASSERT
  | AXIOM
  | BODY
  | CALL
  | CASE
  | CASENO
  | CCLASS
  | CFUNCTION
  | CLASS
  | COMMENT_KEYWORD
  | COMPOUND
  | CONST
  | CPARSE
  | CPROCEDURE
  | CSTRUCT
  | CTOR
  | CTYPES
  | DEF
  | DO
  | DONE
  | ELIF
  | ELSE
  | ENDCASE
  | ENDIF
  | ENDMATCH
  | ENUM
  | EXPECT
  | EXPORT
  | FOR
  | FORGET
  | FORK
  | FUNCTOR
  | FUNCTION
  | GENERATOR
  | GOTO
  | HALT
  | HEADER
  | IDENT
  | INCLUDE
  | INCOMPLETE
  | INF
  | IN
  | INSTANCE
  | IS
  | INHERIT
  | INLINE
  | JUMP
  | LEMMA
  | LET
  | LOOP
  | LVAL
  | MACRO
  | MODULE
  | NAMESPACE
  | NAN
  | NEW
  | NOINLINE
  | NONTERM
  | NORETURN
  | NOT
  | OBJECT
  | OPEN
  | PACKAGE
  | POD
  | PRIVATE
  | PROCEDURE
  | PROPERTY
  | REDUCE
  | REF
  | RENAME
  | REQUIRES
  | RETURN
  | STRUCT
  | THEN
  | TODO
  | TO
  | TYPEDEF
  | TYPE
  | TYPECLASS
  | UNION
  | USE
  | VAL
  | VAR
  | VIRTUAL
  | WHERE
  | WHEN
  | WITH
  | YIELD
  | GC_POINTER
  | GC_TYPE
  | SVC
  | DEREF

statementsx:
  | statement_aster statements_terminator

statements_terminator:
  | VBAR
  | DONE
  | USER_KEYWORD
  | ENDMARKER

compilation_unit:
  | statement_aster ENDMARKER

expression:
  | expr ENDMARKER

statement_aster:
  | statement statement_aster
  | /* empty */

statement:
  | binding_definition
  | declarative
  | executable
  | inclusion
  | directive
  | publish
  | comment
  | null_statement
  | user_statement
  | cparse

comment:
  | COMMENT_KEYWORD STRING SEMI

binding_definition:
  | abstract_type
  | const_def
  | binding_header
  | export_statement

publish:
/*
  | PUBLISH STRING binding_definition
  | PUBLISH STRING declarative
*/
  | PRIVATE declarative
  | PRIVATE binding_definition
  | PRIVATE var_def
  | PRIVATE val_def

declarative:
  | function_definition
  | object_definition
  | procedure_definition
  | module_definition
  | union_decl
  | struct_decl
  | type_alias

directive:
  | open_decl
  | use_decl
  | regdef
  | glr_production
  | macro_definition

executable:
  | var_def
  | val_def
  | call
  | svc
  | return
  | ifgoto_stmt
/*  | whilst_stmt  */
  | todo
  | assignment
  | inline_cpp
  | goto_statement
  | label_statement
  | assert_statement

null_statement:
  | SEMI

user_statement:
  | USER_STATEMENT_DRIVER

inclusion:
  | INCLUDE STRING SEMI

cparse:
  | CPARSE STRING SEMI
declname: /* reverse order */
  | declname COLONCOLON NAME tvarlist
  | NAME tvarlist

regdef:
  | REGEXP NAME EQUAL re1 SEMI

re0:
  | re1 AS NAME
  | re1

re1:
  | re1 VBAR re2
  | re2

re2:
  | re2 re3
  | re3

re3:
  | re4 STAR
  | re4 PLUS
  | re4 QUEST
  | re4

re4:
  | STRING
  | UNDERSCORE
  | DOT
  | LPAR re0 RPAR
  | LSQB charset RSQB
  | LSQB CIRCUMFLEX charset RSQB
  | re_name

re_name:
  | re_name COLONCOLON NAME
  | NAME

charset0:
  | INTEGER MINUS INTEGER
  | STRING MINUS STRING
  | STRING
  | INTEGER

charset:
  | charset charset0
  | charset0

eqorin:
  | EQUAL typeexpr
  | IN typeexpr
  | /* empty */

tvar:
  | NAME eqorin
  | NAME COLON typeexpr eqorin

tvar_comma_list:
  | tvar COMMA tvar_comma_list
  | tvar
  | /* empty */

qualified_name_comma_list:
  | qualified_name COMMA qualified_name_comma_list
  | qualified_name
  | /* empty */

opt_type_constraint:
  | WITH qualified_name_comma_list WHERE expr
  | WHERE expr WITH qualified_name_comma_list
  | WITH qualified_name_comma_list
  | WHERE expr
  | /* empty */

tvarlist:
  | LSQB tvar_comma_list opt_type_constraint RSQB
  | /* empty */

type_qual:
  | INCOMPLETE
  | POD  /* POD types don't require destructors */
  | GC_POINTER
  | GC_TYPE expr

type_quals:
  | type_qual type_quals
  | /* empty */

abstract_type:
  | type_quals CTYPES basic_name_comma_list requires_clause SEMI
  | type_quals TYPE declname EQUAL code_spec requires_clause SEMI
  | type_quals TYPE declname EQUAL NEW typeexpr SEMI
  | CALLBACK PROCEDURE NAME COLON expr requires_clause SEMI
  | CALLBACK FUNCTION NAME COLON expr requires_clause SEMI

union_decl:
  | ENUM NAME LBRACE enum_items RBRACE SEMI
  | UNION declname EQUAL type_sum_items SEMI
  | UNION declname EQUAL VBAR type_sum_items SEMI
  | UNION declname LBRACE type_sum_items2 RBRACE

opt_value:
  | EQUAL INTEGER
  | /* empty */

enum_items:
  | enum_items COMMA enum_item
  | enum_item

enum_item:
  | NAME opt_value

type_sum_items:
  | type_sum_items VBAR type_sum_item
  | type_sum_item

type_sum_item:
  | NAME tvarlist OF expr
  | NAME tvarlist

type_sum_items2:
  | type_sum_items2 type_sum_item SEMI
  | type_sum_item SEMI

opt_equal:
  | EQUAL
  | /* empty */

struct_decl:
  | STRUCT declname opt_equal LBRACE struct_component_aster RBRACE
  | CSTRUCT declname opt_equal LBRACE struct_component_aster RBRACE
  | CCLASS declname opt_equal LBRACE class_component_aster RBRACE
  | CLASS declname opt_equal compound
  | TYPECLASS declname opt_equal compound
  | INSTANCE tvarlist qualified_name opt_equal compound

struct_component_aster:
  | struct_component struct_component_aster
  | /* empty */

struct_component:
  | NAME COLON expr SEMI

opt_name:
  | NAME
  | /* empty */

class_component_aster:
  | class_component class_component_aster
  | /* empty */

class_component:
  | VAR NAME COLON expr SEMI
  | VAL NAME COLON expr SEMI
  | CTOR opt_name COLON expr opt_cstring SEMI
  | FUNCTION NAME tvarlist COLON expr opt_cstring SEMI
  | PROCEDURE NAME tvarlist COLON expr opt_cstring SEMI

typeclass_component_aster:
  | typeclass_component typeclass_component_aster
  | /* empty */

typeclass_component:
  | FUNCTION NAME COLON expr SEMI
  | PROCEDURE NAME COLON expr SEMI

const_def:
  | CONST declname COLON expr EQUAL code_spec requires_clause SEMI
  | CONST declname COLON expr requires_clause SEMI

code_spec:
  | STRING
  | CSTRING
  | IDENT

requirement:
  | qualified_name
  | BODY code_spec
  | HEADER code_spec
  | PROPERTY STRING
  | PACKAGE code_spec

requirement_atom:
  | requirement
  | LPAR requirements RPAR

requirement_and:
  | requirement_and AND requirement_atom
  | requirement_atom

requirement_or:
  | requirement_or OR requirement_and
  | requirement_and

requirements:
  | requirements COMMA requirement_or
  | requirement_or

requires_clause:
  | REQUIRES requirements
  | /* empty */

binding_header:
  | HEADER code_spec requires_clause SEMI
  | BODY code_spec requires_clause SEMI
  | HEADER EQUAL code_spec requires_clause SEMI
  | BODY EQUAL code_spec requires_clause SEMI
  | HEADER declname EQUAL code_spec requires_clause SEMI
  | BODY declname EQUAL code_spec requires_clause SEMI
  | REQUIRES requirements SEMI
  | NAME REQUIRES requirements SEMI

inline_cpp:
  | CODE code_spec SEMI
  | NORETURN CODE code_spec SEMI

type_alias:
  | TYPEDEF declname EQUAL expr SEMI
  | TYPEDEF FUNCTION declname typefun_args COLON expr EQRIGHTARROW expr SEMI
  | TYPEDEF FUNCTION declname COLON expr EQUAL type_matchings SEMI
  | RENAME declname EQUAL qualified_name SEMI
  | RENAME FUNCTION declname EQUAL qualified_name SEMI
  | INHERIT qualified_name SEMI

export_statement:
  | EXPORT FUNCTION suffixed_name AS STRING SEMI
  | EXPORT PROCEDURE suffixed_name AS STRING SEMI
  | EXPORT TYPE LPAR expr RPAR AS STRING SEMI

open_decl:
  | OPEN tvarlist qualified_name SEMI

use_decl:
  | USE qualified_name SEMI
  | USE NAME EQUAL qualified_name SEMI

mac_arg:
  | NAME COLON FUNCTION
  | NAME COLON PROCEDURE
  | NAME COLON NAME
  | NAME

mac_args:
  | mac_arg COMMA mac_args
  | mac_arg

mac_arg_list:
  | LPAR mac_args RPAR
  | LPAR RPAR

eqop:
  | EQUAL
  | EQRIGHTARROW

macro_definition:
  | MACRO NAME IS expr SEMI
  | MACRO FOR NAME IN expr DO statement_aster DONE SEMI
/*
  | MACRO NAME COLON LIST IDENT EQUAL rev_name_list SEMI
*/
  | MACRO NAME IS NEW SEMI
  | MACRO VAR macro_names EQUAL expr SEMI
  | MACRO macro_names EQUAL expr SEMI
  | MACRO VAL macro_names EQUAL expr SEMI
  | MACRO VAL NAME IS tuple SEMI
  | MACRO FUNCTION NAME mac_arg_list eqop expr SEMI
  | MACRO PROCEDURE NAME mac_arg_list compound
  | MACRO compound SEMI
  | MACRO FORGET macro_names SEMI
  | MACRO GOTO NAME SEMI
  | MACRO NAME COLONGREATER
  | MACRO IF expr GOTO NAME SEMI
  | MACRO FOR VAL macro_names IN expr DO statement_aster DONE SEMI

macro_name_list:
  | macro_name_list COMMA NAME
  | NAME

macro_names:
  | macro_name_list
  | /* empty */
/*

rev_name_list:
  | NAME COMMA rev_name_list
  | NAME
*/

typefun_arg:
  | LPAR typeparameter_comma_list RPAR
  | NAME

typefun_args:
  | typefun_arg typefun_args
  | typefun_arg

fun_arg:
  | LPAR parameter_comma_list WHEN expr RPAR
  | LPAR parameter_comma_list RPAR
  | NAME

fun_args:
  | fun_arg fun_args
  | fun_arg

opt_fun_args:
  | fun_args
  | /* empty */

opt_type_expr:
  | COLON expr EXPECT expr
  | COLON expr
  | EXPECT expr
  | /* empty */

opt_cstring:
  | EQUAL code_spec
  | /* empty */

adjective:
  | INLINE
  | NOINLINE
  | VIRTUAL

adjectives:
  | adjective adjectives
  | /* empty */

opt_prec:
  | IS NAME
  | /* empty */

opt_traint_eq:
  | EXPECT expr EQUAL
  | /* empty */

reduce_args:
  | LPAR typeparameter_comma_list RPAR

fun_kind:
  | CFUNCTION
  | FUNCTION
  | GENERATOR

function_definition:
  | REDUCE declname reduce_args COLON expr EQRIGHTARROW expr SEMI
  | AXIOM declname fun_arg COLON expr SEMI
  | AXIOM declname fun_arg COLON expr EQUAL expr SEMI
  | LEMMA declname fun_arg COLON expr SEMI
  | LEMMA declname fun_arg COLON expr EQUAL expr SEMI
  | adjectives fun_kind declname fun_args opt_type_expr EQRIGHTARROW expr SEMI
  | adjectives fun_kind declname fun_args opt_type_expr EQUAL compound
  | adjectives fun_kind declname opt_type_expr opt_cstring opt_prec requires_clause SEMI
  | adjectives fun_kind declname opt_type_expr EQRIGHTARROW expr SEMI
  | adjectives fun_kind declname opt_type_expr EQUAL matchings SEMI

ctor_init:
  | NAME LPAR expr RPAR

ctor_init_list:
  | ctor_init COMMA ctor_init_list
  | ctor_init

ctor_inits:
  | COLON ctor_init_list
  | /* empty */

proc_kind:
  | PROCEDURE
  | CPROCEDURE

procedure_definition:
  | CTOR tvarlist opt_fun_args opt_traint_eq ctor_inits compound
  | adjectives proc_kind declname opt_fun_args opt_traint_eq compound
  | adjectives proc_kind declname COLON expr opt_cstring requires_clause SEMI

object_definition:
  | OBJECT declname fun_args compound

typeparameter_comma_list:
  | typeparameter COMMA typeparameter_comma_list
  | typeparameter
  | /* empty */

typeparameter:
  | NAME COLON arrow
  | NAME

parameter_comma_list:
  | parameter COMMA parameter_comma_list
  | parameter
  | /* empty */

param_qual:
  | VAL
  | VAR
  | REF
  | FUNCTION
  | /* empty */

parameter:
  | param_qual NAME COLON arrow
  | param_qual NAME

assert_statement:
  | ASSERT expr SEMI

goto_statement:
  | GOTO NAME SEMI

label_statement:
  | NAME COLONGREATER

svc:
  | SVC NAME SEMI

open_opt:
  | OPEN
  | /* empty */

module_definition:
  | open_opt MODULE declname opt_equal compound
  | open_opt NAMESPACE declname opt_equal compound

name_suffix:
  | COMMA NAME name_suffix
  | COMMA NAME

var_def:
  | VAR NAME name_suffix EQUAL expr SEMI
  | VAR declname EQUAL expr SEMI
  | VAR declname COLON expr LEFTARROW expr SEMI
  | VAR AMPER NAME tvarlist COLON expr LEFTARROW expr SEMI
  | VAR declname COLON expr EQUAL expr SEMI
  | VAR declname COLON expr SEMI

val_def:
  | VAL NAME name_suffix EQUAL expr SEMI
  | VAL declname EQUAL expr SEMI
  | VAL declname COLON expr EQUAL expr SEMI
  | VAL declname COLON expr SEMI
  | REF declname LEFTARROW expr SEMI
  | REF declname COLON expr LEFTARROW expr SEMI

return:
  | YIELD expr SEMI
  | RETURN expr SEMI
  | RETURN SEMI
  | HALT STRING SEMI

compound:
  | LBRACE statement_aster RBRACE

call:
  | expr SEMI
  | CALL expr SEMI
  | JUMP expr SEMI
  | LOOP expr SEMI

assignop:
  | EQUAL
  | COLONEQUAL

rmwop:
  | PLUSEQUAL
  | MINUSEQUAL
  | STAREQUAL
  | SLASHEQUAL
  | PERCENTEQUAL
  | LEFTSHIFTEQUAL
  | RIGHTSHIFTEQUAL
  | CARETEQUAL
  | VBAREQUAL
  | AMPEREQUAL
  | TILDEEQUAL

swapop:
  | LEFTRIGHTARROW

incrop:
  | PLUSPLUS
  | MINUSMINUS

lelement:
  | VAL NAME
  | VAR NAME
  | NAME
  | UNDERSCORE
  | LPAR lexprs RPAR

tlelement:
  | lelement COLON factor
  | lelement

lexprs:
  | tlelement COMMA lexprs
  | tlelement

lexpr:
  | lexprs

assignment:
  | VAR NAME LEFTARROW NEW expr SEMI
  | expr LEFTARROW expr SEMI
  | expr swapop expr SEMI
  | DEF lexpr EQUAL expr SEMI
  | expr assignop expr SEMI
  | expr rmwop expr SEMI
  | expr incrop SEMI
  | incrop expr SEMI

todo:
  | TODO STRING SEMI
  | TODO SEMI

elif_clause:
  | ELIF expr DO statement_aster
  | ELIF expr RETURN SEMI
  | ELIF expr GOTO NAME SEMI

elif_clauses:
  | elif_clauses elif_clause
  | elif_clause

else_clause:
  | elif_clauses ELSE statement_aster
  | ELSE statement_aster
  | elif_clauses

ifgoto_stmt:
  | IF expr GOTO NAME SEMI
  | IF expr RETURN SEMI
  | IF expr CALL expr SEMI
  | IF expr DO statement_aster else_clause DONE SEMI
  | IF expr DO statement_aster DONE SEMI
/*

whilst_stmt:
  | WHILST expr DO statement_aster DONE SEMI
  | UNTIL expr DO statement_aster DONE SEMI
*/

regmatch_expr:
  | REGMATCH expr WITH regmatch_alternatives ENDMATCH
  | REGLEX expr TO expr WITH regmatch_alternatives ENDMATCH

regmatch_alternatives:
  | regmatch_alternatives regmatch_alternative
  | regmatch_alternative

regmatch_alternative:
  | VBAR re1 EQRIGHTARROW expr

match_expr:
  | MATCH expr WITH matchings ENDMATCH

matchings:
  | matching matchings
  | matching

matching:
  | VBAR pattern EQRIGHTARROW expr
  | VBAR EQRIGHTARROW expr

typecaseargs:
  | LSQB basic_name_comma_list RSQB

typecase:
  | TYPECASE typecaseargs expr EQRIGHTARROW expr ENDCASE

pattern:
  | as_pattern WHEN expr
  | as_pattern

as_pattern:
  | variant_pattern AS NAME
  | variant_pattern

variant_pattern:
  | tuple_pattern

tuple_pattern:
  | coercive_pattern_list

coercive_pattern_list:
  | coercive_pattern COMMA coercive_pattern_list
  | coercive_pattern

coercive_pattern:
  | atomic_pattern COLON arrow
  | atomic_pattern

atomic_pattern:
/* constants */
  | STRING
  | integral
  | NAN
/* ranges */
  | STRING DOTDOT STRING
  | integral DOTDOT integral
  | floating DOTDOT floating
/* other */
  | ctor_pattern
/*
  | QUEST NAME
*/
  | QUEST NAME
  | QUEST
  | UNDERSCORE
  | LPAR pattern RPAR
  | REGEXP STRING LPAR basic_name_comma_list RPAR
  | STRUCT LBRACE pat_assigns RBRACE

pat_assign:
  | NAME EQUAL pattern SEMI

pat_assigns:
  | pat_assign pat_assigns
  | pat_assign

ctor_pattern:
  | ctor_name atomic_pattern
  | ctor_name

ctor_name:
  | qualified_name
  | CASE INTEGER

integral:
  | INTEGER
  | MINUS INTEGER

floating:
  | FLOAT
  | MINUS FLOAT
  | INF
  | MINUS INF

basic_name:
  | NAME

basic_name_comma_list:
  | basic_name COMMA basic_name_comma_list
  | basic_name
  | /* empty */

tpattern_comma_list:
  | tpattern COMMA tpattern_comma_list
  | tpattern
  | /* empty */

tuple_tpattern:
  | tpattern_comma_list

tpattern:
  | tpattern AS NAME
  | tpat0

tpat0:
  | tpat1 RIGHTARROW tpat0
  | tpat1

tpat1:
  | sumpat

sumpat:
  | tpat2 PLUS sumpat
  | tpat2

tpat2:
  | mulpat

mulpat:
  | tpat3 STAR mulpat
  | tpat3

tpat3:
  | NAME tpatlist
  | LPAR tuple_tpattern RPAR
  | QUEST NAME
  | QUEST
  | UNDERSCORE
  | INTEGER

tpatlist:
  | LSQB tpattern_comma_list RSQB
  | /* empty */

type_match_expr:
  | TYPEMATCH expr WITH type_matchings ENDMATCH

type_matchings:
  | type_matching type_matchings
  | type_matching

type_matching:
/*
  | VBAR tuple_tpattern EQRIGHTARROW expr
*/
  | VBAR expr EQRIGHTARROW expr

glr_term:
  | qualified_name
/* | LSQB glr_alts RSQB   */
  | LBRACE glr_alternatives RBRACE
  | LPAR glr_alternatives RPAR
  | glr_term QUEST
  | glr_term STAR
  | glr_term PLUS

glr_alternatives:
  | glr_sequence VBAR glr_alts
  | glr_sequence

glr_alts:
  | glr_sequence VBAR glr_alts
  | glr_sequence

glr_sequence:
  | glr_term glr_seqs
  | glr_term

glr_seqs:
  | glr_term glr_seqs
  | glr_term

glr_entry:
  | NAME COLON glr_term
  | glr_term

glr_entries:
  | glr_entry glr_entries
  | glr_entry

glr_matching:
  | VBAR glr_entries EQRIGHTARROW expr
  | VBAR EQRIGHTARROW expr

glr_matchings:
  | glr_matching glr_matchings
  | glr_matching

glr_production:
  | NONTERM NAME COLON expr EQUAL glr_matchings SEMI

glr_parse:
  | PARSE expr WITH glr_matchings ENDMATCH

expr:
  | LET pattern EQUAL expr IN expr
  | rvalue

rvalue:
  | lambda
/* cannot use fun_args, since ambiguity on the third case (NAME) */

lambda_fun_arg:
  | LPAR parameter_comma_list WHEN expr RPAR
  | LPAR parameter_comma_list RPAR

lambda_fun_args:
  | lambda_fun_arg lambda_fun_args
  | lambda_fun_arg

lambda:
  | dollar_apply
  | adjectives FUNCTION tvarlist lambda_fun_args opt_type_expr EQUAL compound
  | adjectives FUNCTION tvarlist lambda_fun_args opt_type_expr EQRIGHTARROW expr
  | adjectives PROCEDURE tvarlist lambda_fun_args compound
  | adjectives PROCEDURE tvarlist compound

dollar_apply:
  | tuple UNLESS expr THEN dollar_apply
  | tuple DOLLAR dollar_apply
  | tuple

tuple:
  | or_condition tuple_suffix
  | or_condition

tuple_suffix:
  | COMMA or_condition tuple_suffix
  | COMMA or_condition
/* oring formation is 'psuedo-associative' */
typeexpr: or_condition

or_condition:
  | and_condition OR or_list
  | and_condition

or_list:
  | and_condition OR or_list
  | and_condition
/* oring formation is 'psuedo-associative' */

and_condition:
  | not_condition AND and_list
  | not_condition

and_list:
  | not_condition AND and_list
  | not_condition

notop:
  | NOT

not_condition:
  | notop not_condition
  | comparison

chain_cmp_op:
  | ANDEQEQUAL
  | ANDNOTEQUAL
  | ANDLESS
  | ANDGREATER
  | ANDLESSEQUAL
  | ANDGREATEREQUAL

cmp_item:
  | chain_cmp_op sum

cmp_item_list:
  | cmp_item cmp_item_list
  | cmp_item

cmp_op:
  | EQEQUAL
  | NOTEQUAL
  | LESS
  | GREATER
  | LESSEQUAL
  | GREATEREQUAL
  | ISIN
/* hack */

comparison:
  | sum cmp_op sum cmp_item_list
  | sum cmp_op sum
  | as_expr

as_expr:
  | as_expr AS NAME
  | setunion

setunion:
  | user10 VBARVBAR setunion_list
  | user10

setunion_list:
  | user10 VBARVBAR setunion_list
  | user10

user10:
  | user10 USER10 setintersection
  | setintersection

setintersection:
  | arrow AMPERAMPER setintersection_list
  | arrow

setintersection_list:
  | arrow AMPERAMPER setintersection_list
  | arrow

arrow:
  | case_literal RIGHTARROW arrow
  | case_literal LONGRIGHTARROW arrow
  | case_literal

case_literal:
  | CASE INTEGER
  | CASE INTEGER OF sum
  | CASE NAME OF sum
  | bor

bor:
  | bor SLOSHVBAR bxor
  | bxor

bxor:
  | bxor SLOSHCIRCUMFLEX band
  | band

band:
  | band SLOSHAMPER shift
  | shift

shift:
  | shift LEFTSHIFT sum
  | shift RIGHTSHIFT sum
  | sum
/* sum formation is 'psuedo-associative' */

sum:
  | subtraction PLUS sum_list
  | subtraction

sum_list:
  | subtraction PLUS sum_list
  | subtraction

subtraction:
  | subtraction MINUS product
  | product
/* product formation is 'psuedo-associative' */

product:
  | term STAR product_list
  | term

product_list:
  | term STAR product_list
  | term
/* division is left associative: note higher precedence
the product, so that
a * b/c * d -> a * (b/c) * d
*/

term:
  | term SLASH power
  | term PERCENT power
  | prefixed
/* note weird recursion here: we need to support
-x ** -x = -(x**(-x))
*/

prefixed:
  | LVAL power
/*
  | HASH power
*/
  | EXCLAMATION power
  | PLUS power
  | MINUS power
  | TILDE power
  | power
/* exponentiation is right associative */

power:
  | superscript STARSTAR prefixed
  | superscript

superscript:
  | superscript CIRCUMFLEX refr
  | refr

refr:
  | UNION LBRACE type_sum_items2 RBRACE
  | STRUCT compound
  | AMPER refr
  | STAR refr
  | DEREF refr
  | NEW refr
  | application
/* applications is left associative */

application:
  | application coercion
/*
  | MAP coercion coercion
*/
  | CASENO coercion
  | MACRO CTOR NAME coercion
  | coercion

coercion:
  | coercion COLON factor
  | suffixed_name
  | factor

factor:
  | hash_name
  | factor DOT LSQB expr RSQB
  | factor DOT LSQB expr TO expr RSQB
  | factor DOT LSQB expr TO RSQB
  | factor DOT LSQB TO expr RSQB
  | factor DOT simple_name_parts
  | factor DOTRIGHTARROW simple_name_parts
  | factor DOT LPAR INTEGER RPAR

hash_name:
  | HASH hash_name
  | the_name

the_name:
  | NOEXPAND qualified_name
  | THE qualified_name
  | qualified_name
  | QUEST NAME
  | atom

qualified_name:
  | qualified_name COLONCOLON simple_name_parts
  | simple_name_parts

elif:
  | ELIF expr THEN expr

elifs:
  | elifs elif
  | elif

else_part:
  | elifs ELSE expr
  | ELSE expr

cond:
  | IF expr THEN expr else_part ENDIF

expr_code_prefix:
  | CODE LSQB expr RSQB

atom:
  | UNDERSCORE
  | CALLBACK LSQB qualified_name RSQB
  | DOTDOTDOT
  | type_match_expr
  | expr_code_prefix NAME
  | expr_code_prefix STRING
  | LSQBAR expr RSQBAR
  | LBRACE expr RBRACE
  | glr_parse
  | match_expr
  | regmatch_expr
  | typecase
  | compound
  | LPAR expr RPAR
  | LPAR RPAR
  | literal
  | cond
  | FSTRING
  | QSTRING
  | USERLB expr USERRB

literal:
  | integer_literal
  | string_literal
  | float_literal

integer_literal:
  | INTEGER

float_literal:
  | FLOAT

string_literal:
  | STRING
  | WSTRING
  | USTRING
  | CSTRING

simple_name_parts:
  | NAME LSQB expr RSQB
  | NAME

suffixed_name:
  | qualified_name OF factor
Start python section to spkgs/grammar.py[1 /1 ]
     1: #line 29 "./lpsrc/flx_mkgrammar.pak"
     2: iscr_source = ['lpsrc/flx_mkgrammar.pak']
     3: weaver_directory = 'doc/grammar/'
     4: pkg_requires = ['flx_compiler']
     5: 
End python section to spkgs/grammar.py[1]