Fable icon indicating copy to clipboard operation
Fable copied to clipboard

Grammar railroad diagram

Open mingodad opened this issue 2 years ago • 5 comments

Using an extension to bison found here https://github.com/mingodad/lalr-parser-test we can generate an EBNF accepted by https://www.bottlecaps.de/rr/ui to generate a nice navigable railroad diagram from https://github.com/fable-compiler/Fable/blob/main/src/fcs-fable/src/Compiler/pars.fsy and manually adding the tokens.

Copy the EBNF shown bellow and paste it at https://www.bottlecaps.de/rr/ui on the tab Edit Grammar then switch to the tab View Diagram (be patient because it takes a bit of time). It can also generated offline with this download https://www.bottlecaps.de/rr/download/rr-2.0-java11.zip .

fable ::=
	YY_PARSE_signatureFile signatureFile YYEOF
	| YY_PARSE_implementationFile implementationFile YYEOF
	| YY_PARSE_interaction interaction YYEOF
	| YY_PARSE_typedSequentialExprEOF typedSequentialExprEOF YYEOF
	| YY_PARSE_typEOF typEOF YYEOF

interaction ::=
	/*empty*/
	| interactiveItemsTerminator
	| SEMICOLON
	| OBLOCKSEP

interactiveTerminator ::=
	/*empty*/
	| SEMICOLON_SEMICOLON
	| EOF

interactiveItemsTerminator ::=
	/*empty*/
	| interactiveTerminator
	| interactiveDefns interactiveTerminator
	| interactiveExpr interactiveTerminator
	| interactiveHash interactiveTerminator
	| interactiveDefns interactiveSeparators interactiveItemsTerminator
	| interactiveExpr interactiveSeparators interactiveItemsTerminator
	| interactiveHash interactiveSeparators interactiveItemsTerminator

interactiveDefns ::=
	/*empty*/
	| moduleDefn
	| moduleDefn interactiveDefns

interactiveExpr ::=
	/*empty*/
	| opt_attributes opt_access declExpr

interactiveHash ::=
	/*empty*/
	| hashDirective

interactiveSeparators ::=
	/*empty*/
	| interactiveSeparator
	| interactiveSeparator interactiveSeparators

interactiveSeparator ::=
	/*empty*/
	| SEMICOLON
	| OBLOCKSEP

hashDirective ::=
	/*empty*/
	| HASH IDENT hashDirectiveArgs

hashDirectiveArgs ::=
	/*empty*/
	| /*empty*/
	| hashDirectiveArgs hashDirectiveArg

hashDirectiveArg ::=
	/*empty*/
	| string
	| sourceIdentifier

signatureFile ::=
	/*empty*/
	| fileNamespaceSpecs EOF
	| fileNamespaceSpecs error EOF
	| error EOF

moduleIntro ::=
	/*empty*/
	| moduleKeyword opt_attributes opt_access opt_rec path
	| moduleKeyword opt_attributes opt_access opt_rec OBLOCKSEP
	| moduleKeyword opt_attributes opt_access opt_rec recover

namespaceIntro ::=
	/*empty*/
	| NAMESPACE opt_rec path
	| NAMESPACE opt_rec recover

fileNamespaceSpecs ::=
	/*empty*/
	| fileModuleSpec
	| fileModuleSpec fileNamespaceSpecList

fileNamespaceSpecList ::=
	/*empty*/
	| fileNamespaceSpec fileNamespaceSpecList
	| fileNamespaceSpec

fileNamespaceSpec ::=
	/*empty*/
	| namespaceIntro deprecated_opt_equals fileModuleSpec

fileModuleSpec ::=
	/*empty*/
	| opt_attributes opt_access moduleIntro moduleSpfnsPossiblyEmptyBlock
	| moduleSpfnsPossiblyEmptyBlock

moduleSpfnsPossiblyEmptyBlock ::=
	/*empty*/
	| moduleSpfnsPossiblyEmpty
	| OBLOCKBEGIN moduleSpfnsPossiblyEmpty oblockend opt_OBLOCKSEP
	| OBLOCKBEGIN moduleSpfnsPossiblyEmpty recover
	| OBLOCKBEGIN error oblockend

moduleSpfnsPossiblyEmpty ::=
	/*empty*/
	| moduleSpfns
	| error
	| /*empty*/

moduleSpfns ::=
	/*empty*/
	| moduleSpfn opt_topSeparators moduleSpfns
	| error topSeparators moduleSpfns
	| moduleSpfn opt_topSeparators

moduleSpfn ::=
	/*empty*/
	| hashDirective
	| valSpfn
	| opt_attributes opt_access moduleIntro colonOrEquals namedModuleAbbrevBlock
	| opt_attributes opt_access moduleIntro colonOrEquals moduleSpecBlock
	| opt_attributes opt_access moduleIntro error
	| opt_attributes opt_access typeKeyword tyconSpfn tyconSpfnList
	| opt_attributes opt_access exconSpfn
	| openDecl

valSpfn ::=
	/*empty*/
	| opt_attributes opt_access VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn

optLiteralValueSpfn ::=
	/*empty*/
	| /*empty*/
	| EQUALS declExpr
	| EQUALS OBLOCKBEGIN declExpr oblockend opt_ODECLEND

moduleSpecBlock ::=
	/*empty*/
	| OBLOCKBEGIN moduleSpfns oblockend
	| OBLOCKBEGIN sigOrBegin moduleSpfnsPossiblyEmpty END oblockend
	| sigOrBegin moduleSpfnsPossiblyEmpty END

tyconSpfnList ::=
	/*empty*/
	| AND tyconSpfn tyconSpfnList
	| /*empty*/

tyconSpfn ::=
	/*empty*/
	| typeNameInfo EQUALS tyconSpfnRhsBlock
	| typeNameInfo opt_classSpfn

tyconSpfnRhsBlock ::=
	/*empty*/
	| OBLOCKBEGIN tyconSpfnRhs opt_OBLOCKSEP classSpfnMembers opt_classSpfn oblockend opt_classSpfn
	| tyconSpfnRhs opt_classSpfn

tyconSpfnRhs ::=
	/*empty*/
	| tyconDefnOrSpfnSimpleRepr
	| tyconClassSpfn
	| DELEGATE OF topType

tyconClassSpfn ::=
	/*empty*/
	| classSpfnBlockKindUnspecified
	| classOrInterfaceOrStruct classSpfnBlock END
	| classOrInterfaceOrStruct classSpfnBlock recover
	| classOrInterfaceOrStruct error END

classSpfnBlockKindUnspecified ::=
	/*empty*/
	| OBLOCKBEGIN classSpfnMembers oblockend
	| OBLOCKBEGIN classSpfnMembers recover
	| BEGIN classSpfnBlock END
	| BEGIN classSpfnBlock recover

classSpfnBlock ::=
	/*empty*/
	| OBLOCKBEGIN classSpfnMembers oblockend
	| OBLOCKBEGIN classSpfnMembers recover
	| classSpfnMembers

classSpfnMembers ::=
	/*empty*/
	| classSpfnMembersAtLeastOne
	| /*empty*/

classSpfnMembersAtLeastOne ::=
	/*empty*/
	| classMemberSpfn opt_seps classSpfnMembers

classMemberSpfn ::=
	/*empty*/
	| opt_attributes opt_access memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn
	| opt_attributes opt_access interfaceMember appType
	| opt_attributes opt_access INHERIT appType
	| opt_attributes opt_access INHERIT recover
	| opt_attributes opt_access VAL fieldDecl
	| opt_attributes opt_access STATIC VAL fieldDecl
	| opt_attributes opt_access STATIC typeKeyword tyconSpfn
	| opt_attributes opt_access NEW COLON topTypeWithTypeConstraints

classMemberSpfnGetSet ::=
	/*empty*/
	| /*empty*/
	| WITH classMemberSpfnGetSetElements
	| OWITH classMemberSpfnGetSetElements OEND
	| OWITH classMemberSpfnGetSetElements error

classMemberSpfnGetSetElements ::=
	/*empty*/
	| nameop
	| nameop COMMA nameop
	| nameop COMMA recover
	| OBLOCKBEGIN oblockend ODECLEND

memberSpecFlags ::=
	/*empty*/
	| memberFlags
	| abstractMemberFlags

exconSpfn ::=
	/*empty*/
	| exconCore opt_classSpfn

opt_classSpfn ::=
	/*empty*/
	| WITH classSpfnBlock declEnd
	| /*empty*/

implementationFile ::=
	/*empty*/
	| fileNamespaceImpls EOF
	| fileNamespaceImpls error EOF
	| error EOF

fileNamespaceImpls ::=
	/*empty*/
	| fileModuleImpl
	| fileModuleImpl fileNamespaceImplList

fileNamespaceImplList ::=
	/*empty*/
	| fileNamespaceImpl fileNamespaceImplList
	| fileNamespaceImpl

fileNamespaceImpl ::=
	/*empty*/
	| namespaceIntro deprecated_opt_equals fileModuleImpl

fileModuleImpl ::=
	/*empty*/
	| opt_attributes opt_access moduleIntro moduleDefnsOrExprPossiblyEmptyOrBlock
	| moduleDefnsOrExprPossiblyEmptyOrBlock

moduleDefnsOrExprPossiblyEmptyOrBlock ::=
	/*empty*/
	| OBLOCKBEGIN moduleDefnsOrExprPossiblyEmpty oblockend opt_OBLOCKSEP
	| OBLOCKBEGIN moduleDefnsOrExprPossiblyEmpty recover
	| OBLOCKBEGIN error oblockend
	| moduleDefnsOrExprPossiblyEmpty

moduleDefnsOrExprPossiblyEmpty ::=
	/*empty*/
	| moduleDefnsOrExpr
	| /*empty*/

moduleDefnsOrExpr ::=
	/*empty*/
	| opt_attributes opt_access declExpr topSeparators moduleDefnsOrExpr
	| opt_attributes opt_access declExpr topSeparators
	| opt_attributes opt_access declExpr
	| moduleDefns
	| opt_attributes error

moduleDefns ::=
	/*empty*/
	| moduleDefnOrDirective moduleDefns
	| moduleDefnOrDirective topSeparators moduleDefnsOrExpr
	| moduleDefnOrDirective
	| moduleDefnOrDirective topSeparators
	| error topSeparators moduleDefnsOrExpr

moduleDefnOrDirective ::=
	/*empty*/
	| moduleDefn
	| hashDirective

moduleDefn ::=
	/*empty*/
	| opt_attributes opt_access defnBindings
	| opt_attributes opt_access hardwhiteLetBindings
	| opt_attributes opt_access doBinding
	| opt_attributes opt_access typeKeyword tyconDefn tyconDefnList
	| opt_attributes opt_access exconDefn
	| opt_attributes opt_access moduleIntro EQUALS namedModuleDefnBlock
	| opt_attributes opt_access moduleIntro error
	| attributes recover
	| openDecl

openDecl ::=
	/*empty*/
	| OPEN path
	| OPEN recover
	| OPEN typeKeyword appType
	| OPEN typeKeyword recover

namedModuleAbbrevBlock ::=
	/*empty*/
	| OBLOCKBEGIN path oblockend
	| path

namedModuleDefnBlock ::=
	/*empty*/
	| OBLOCKBEGIN wrappedNamedModuleDefn oblockend
	| OBLOCKBEGIN wrappedNamedModuleDefn recover
	| OBLOCKBEGIN moduleDefnsOrExpr oblockend
	| OBLOCKBEGIN moduleDefnsOrExpr recover
	| OBLOCKBEGIN error oblockend
	| wrappedNamedModuleDefn
	| path

wrappedNamedModuleDefn ::=
	/*empty*/
	| structOrBegin moduleDefnsOrExprPossiblyEmpty END
	| structOrBegin moduleDefnsOrExprPossiblyEmpty recover
	| structOrBegin error END

tyconDefnAugmentation ::=
	/*empty*/
	| WITH classDefnBlock declEnd

opt_attributes ::=
	/*empty*/
	| attributes
	| /*empty*/

attributes ::=
	/*empty*/
	| attributeList
	| attributeList attributes

attributeList ::=
	/*empty*/
	| LBRACK_LESS attributeListElements opt_seps GREATER_RBRACK opt_OBLOCKSEP
	| LBRACK_LESS error GREATER_RBRACK opt_OBLOCKSEP
	| LBRACK_LESS attributeListElements opt_seps ends_coming_soon_or_recover
	| LBRACK_LESS ends_coming_soon_or_recover

attributeListElements ::=
	/*empty*/
	| attribute
	| attributeListElements seps attribute

attribute ::=
	/*empty*/
	| path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
	| attributeTarget path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
	| attributeTarget OBLOCKBEGIN path oblockend opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType

attributeTarget ::=
	/*empty*/
	| moduleKeyword COLON
	| typeKeyword COLON
	| ident COLON
	| YIELD COLON

memberFlags ::=
	/*empty*/
	| STATIC MEMBER
	| STATIC
	| MEMBER
	| OVERRIDE
	| DEFAULT

typeNameInfo ::=
	/*empty*/
	| opt_attributes tyconNameAndTyparDecls opt_typeConstraints

tyconDefnList ::=
	/*empty*/
	| AND tyconDefn tyconDefnList
	| /*empty*/

tyconDefn ::=
	/*empty*/
	| typeNameInfo
	| typeNameInfo tyconDefnAugmentation
	| typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec EQUALS tyconDefnRhsBlock
	| typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec recover

tyconDefnRhsBlock ::=
	/*empty*/
	| OBLOCKBEGIN tyconDefnRhs opt_OBLOCKSEP classDefnMembers opt_classDefn oblockend opt_classDefn
	| OBLOCKBEGIN tyconDefnRhs opt_OBLOCKSEP classDefnMembers opt_classDefn recover
	| OBLOCKBEGIN oblockend
	| tyconDefnRhs opt_classDefn

tyconDefnRhs ::=
	/*empty*/
	| tyconDefnOrSpfnSimpleRepr
	| tyconClassDefn
	| DELEGATE OF topType

tyconClassDefn ::=
	/*empty*/
	| classDefnBlockKindUnspecified
	| classOrInterfaceOrStruct classDefnBlock END
	| classOrInterfaceOrStruct classDefnBlock ends_coming_soon_or_recover
	| classOrInterfaceOrStruct error END

classDefnBlockKindUnspecified ::=
	/*empty*/
	| OBLOCKBEGIN classDefnMembersAtLeastOne recover
	| OBLOCKBEGIN classDefnMembersAtLeastOne oblockend

classDefnBlock ::=
	/*empty*/
	| OBLOCKBEGIN classDefnMembers recover
	| OBLOCKBEGIN classDefnMembers oblockend
	| classDefnMembers

classDefnMembers ::=
	/*empty*/
	| classDefnMembersAtLeastOne
	| error classDefnMembers
	| /*empty*/

classDefnMembersAtLeastOne ::=
	/*empty*/
	| classDefnMember opt_seps classDefnMembers

classDefnMemberGetSet ::=
	/*empty*/
	| WITH classDefnMemberGetSetElements
	| OWITH classDefnMemberGetSetElements OEND
	| OWITH classDefnMemberGetSetElements error

classDefnMemberGetSetElements ::=
	/*empty*/
	| classDefnMemberGetSetElement
	| classDefnMemberGetSetElement AND classDefnMemberGetSetElement

classDefnMemberGetSetElement ::=
	/*empty*/
	| opt_inline opt_attributes bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock

memberCore ::=
	/*empty*/
	| opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock
	| opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints OBLOCKSEP
	| opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints recover
	| opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints classDefnMemberGetSet

abstractMemberFlags ::=
	/*empty*/
	| ABSTRACT
	| ABSTRACT MEMBER
	| STATIC ABSTRACT
	| STATIC ABSTRACT MEMBER

classDefnMember ::=
	/*empty*/
	| opt_attributes opt_access classDefnBindings
	| opt_attributes opt_access STATIC classDefnBindings
	| opt_attributes opt_access memberFlags memberCore opt_ODECLEND
	| opt_attributes opt_access memberFlags recover
	| opt_attributes opt_access interfaceMember appType opt_interfaceImplDefn
	| opt_attributes opt_access interfaceMember recover
	| opt_attributes opt_access abstractMemberFlags opt_inline nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet opt_ODECLEND
	| opt_attributes opt_access inheritsDefn
	| opt_attributes opt_access valDefnDecl opt_ODECLEND
	| opt_attributes opt_access STATIC valDefnDecl opt_ODECLEND
	| opt_attributes opt_access memberFlags autoPropsDefnDecl opt_ODECLEND
	| opt_attributes opt_access NEW atomicPattern optAsSpec EQUALS typedSequentialExprBlock opt_ODECLEND
	| opt_attributes opt_access NEW atomicPattern optAsSpec ends_coming_soon_or_recover
	| opt_attributes opt_access NEW atomicPattern optAsSpec OBLOCKSEP
	| opt_attributes opt_access NEW recover opt_OBLOCKSEP
	| opt_attributes opt_access STATIC typeKeyword tyconDefn

valDefnDecl ::=
	/*empty*/
	| VAL opt_mutable opt_access ident COLON typ
	| VAL opt_mutable opt_access ident COLON recover
	| VAL opt_mutable opt_access ident recover
	| VAL opt_mutable opt_access recover

autoPropsDefnDecl ::=
	/*empty*/
	| VAL opt_mutable opt_access ident opt_typ EQUALS typedSequentialExprBlock classMemberSpfnGetSet
	| VAL opt_mutable opt_access ident opt_typ ends_coming_soon_or_recover
	| VAL opt_mutable opt_access ident opt_typ OBLOCKSEP
	| VAL opt_mutable opt_access recover

opt_typ ::=
	/*empty*/
	| /*empty*/
	| COLON typ
	| COLON recover

atomicPatternLongIdent ::=
	/*empty*/
	| UNDERSCORE DOT pathOp
	| GLOBAL DOT pathOp
	| pathOp
	| access UNDERSCORE DOT pathOp
	| access pathOp

opt_access ::=
	/*empty*/
	| /*empty*/
	| access

access ::=
	/*empty*/
	| PRIVATE
	| PUBLIC
	| INTERNAL

opt_interfaceImplDefn ::=
	/*empty*/
	| WITH objectImplementationBlock declEnd
	| WITH
	| /*empty*/

opt_classDefn ::=
	/*empty*/
	| WITH classDefnBlock declEnd
	| /*empty*/

inheritsDefn ::=
	/*empty*/
	| INHERIT atomTypeNonAtomicDeprecated optBaseSpec
	| INHERIT atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType optBaseSpec
	| INHERIT ends_coming_soon_or_recover

optAsSpec ::=
	/*empty*/
	| asSpec
	| /*empty*/

asSpec ::=
	/*empty*/
	| AS ident
	| AS recover

optBaseSpec ::=
	/*empty*/
	| baseSpec
	| /*empty*/

baseSpec ::=
	/*empty*/
	| AS ident
	| AS BASE

objectImplementationBlock ::=
	/*empty*/
	| OBLOCKBEGIN objectImplementationMembers oblockend
	| OBLOCKBEGIN objectImplementationMembers recover
	| objectImplementationMembers

objectImplementationMembers ::=
	/*empty*/
	| objectImplementationMember opt_seps objectImplementationMembers
	| objectImplementationMember opt_seps

objectImplementationMember ::=
	/*empty*/
	| opt_attributes staticMemberOrMemberOrOverride memberCore opt_ODECLEND
	| opt_attributes staticMemberOrMemberOrOverride autoPropsDefnDecl opt_ODECLEND
	| opt_attributes staticMemberOrMemberOrOverride error
	| opt_attributes error memberCore opt_ODECLEND

staticMemberOrMemberOrOverride ::=
	/*empty*/
	| STATIC MEMBER
	| MEMBER
	| OVERRIDE

tyconDefnOrSpfnSimpleRepr ::=
	/*empty*/
	| opt_attributes opt_access path LQUOTE STRING recover
	| opt_attributes opt_access typ
	| opt_attributes opt_access unionTypeRepr
	| opt_attributes opt_access braceFieldDeclList
	| opt_attributes opt_access LPAREN HASH string HASH rparen

braceFieldDeclList ::=
	/*empty*/
	| LBRACE recdFieldDeclList rbrace
	| LBRACE recdFieldDeclList recover
	| LBRACE error rbrace

anonRecdType ::=
	/*empty*/
	| STRUCT braceBarFieldDeclListCore
	| braceBarFieldDeclListCore

braceBarFieldDeclListCore ::=
	/*empty*/
	| LBRACE_BAR recdFieldDeclList bar_rbrace
	| LBRACE_BAR recdFieldDeclList recover
	| LBRACE_BAR error bar_rbrace

classOrInterfaceOrStruct ::=
	/*empty*/
	| CLASS
	| INTERFACE
	| STRUCT

interfaceMember ::=
	/*empty*/
	| INTERFACE
	| OINTERFACE_MEMBER

tyconNameAndTyparDecls ::=
	/*empty*/
	| opt_access path
	| opt_access prefixTyparDecls path
	| opt_access path postfixTyparDecls
	| opt_access recover

prefixTyparDecls ::=
	/*empty*/
	| typar
	| LPAREN typarDeclList rparen

typarDeclList ::=
	/*empty*/
	| typarDeclList COMMA typarDecl
	| typarDecl

typarDecl ::=
	/*empty*/
	| opt_attributes typar
	| opt_attributes typar AMP intersectionConstraints

postfixTyparDecls ::=
	/*empty*/
	| opt_HIGH_PRECEDENCE_TYAPP LESS typarDeclList opt_typeConstraints GREATER

explicitValTyparDeclsCore ::=
	/*empty*/
	| typarDeclList COMMA DOT_DOT
	| typarDeclList
	| /*empty*/

explicitValTyparDecls ::=
	/*empty*/
	| opt_HIGH_PRECEDENCE_TYAPP LESS explicitValTyparDeclsCore opt_typeConstraints GREATER

opt_explicitValTyparDecls ::=
	/*empty*/
	| explicitValTyparDecls
	| /*empty*/

opt_typeConstraints ::=
	/*empty*/
	| /*empty*/
	| WHEN typeConstraints

typeConstraints ::=
	/*empty*/
	| typeConstraints AND typeConstraint
	| typeConstraint

intersectionConstraints ::=
	/*empty*/
	| intersectionConstraints AMP atomType
	| atomType

typeConstraint ::=
	/*empty*/
	| DEFAULT typar COLON typ
	| typar COLON_GREATER typ
	| typar COLON STRUCT
	| typar COLON IDENT STRUCT
	| typar COLON NULL
	| typar COLON LPAREN classMemberSpfn rparen
	| LPAREN typeAlts rparen COLON LPAREN classMemberSpfn rparen
	| typar COLON DELEGATE typeArgsNoHpaDeprecated
	| typar COLON IDENT typeArgsNoHpaDeprecated
	| typar COLON IDENT
	| appType

typeAlts ::=
	/*empty*/
	| typeAlts OR appType
	| appType

unionTypeRepr ::=
	/*empty*/
	| barAndgrabXmlDoc attrUnionCaseDecls
	| firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls
	| firstUnionCaseDecl

barAndgrabXmlDoc ::=
	/*empty*/
	| BAR

attrUnionCaseDecls ::=
	/*empty*/
	| attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls
	| attrUnionCaseDecl

attrUnionCaseDecl ::=
	/*empty*/
	| opt_attributes opt_access unionCaseName
	| opt_attributes opt_access recover
	| opt_attributes opt_access unionCaseName OF unionCaseRepr
	| opt_attributes opt_access unionCaseName unionCaseRepr
	| opt_attributes opt_access OF unionCaseRepr
	| opt_attributes opt_access OF recover
	| opt_attributes opt_access unionCaseName OF recover
	| opt_attributes opt_access unionCaseName COLON topType
	| opt_attributes opt_access unionCaseName EQUALS atomicExpr

unionCaseName ::=
	/*empty*/
	| nameop
	| LPAREN COLON_COLON rparen
	| LPAREN LBRACK RBRACK rparen

firstUnionCaseDeclOfMany ::=
	/*empty*/
	| ident opt_OBLOCKSEP
	| ident EQUALS atomicExpr opt_OBLOCKSEP
	| firstUnionCaseDecl opt_OBLOCKSEP

firstUnionCaseDecl ::=
	/*empty*/
	| ident OF unionCaseRepr
	| ident OF recover
	| OF unionCaseRepr
	| ident EQUALS atomicExpr opt_OBLOCKSEP

unionCaseReprElements ::=
	/*empty*/
	| unionCaseReprElement STAR unionCaseReprElements
	| unionCaseReprElement

unionCaseReprElement ::=
	/*empty*/
	| ident COLON appType
	| appType
	| ident COLON invalidUseOfAppTypeFunction
	| invalidUseOfAppTypeFunction

unionCaseRepr ::=
	/*empty*/
	| braceFieldDeclList
	| unionCaseReprElements

recdFieldDeclList ::=
	/*empty*/
	| recdFieldDecl seps recdFieldDeclList
	| recdFieldDecl opt_seps

recdFieldDecl ::=
	/*empty*/
	| opt_attributes fieldDecl

fieldDecl ::=
	/*empty*/
	| opt_mutable opt_access ident COLON typ
	| opt_mutable opt_access ident COLON recover
	| opt_mutable opt_access ident recover

exconDefn ::=
	/*empty*/
	| exconCore opt_classDefn

exconCore ::=
	/*empty*/
	| EXCEPTION opt_attributes opt_access exconIntro exconRepr
	| EXCEPTION opt_attributes opt_access recover

exconIntro ::=
	/*empty*/
	| ident
	| ident OF unionCaseRepr
	| ident OF recover

exconRepr ::=
	/*empty*/
	| /*empty*/
	| EQUALS path

defnBindings ::=
	/*empty*/
	| LET opt_rec localBindings
	| cPrototype

doBinding ::=
	/*empty*/
	| DO typedSequentialExprBlock

hardwhiteLetBindings ::=
	/*empty*/
	| OLET opt_rec localBindings hardwhiteDefnBindingsTerminator

hardwhiteDoBinding ::=
	/*empty*/
	| ODO typedSequentialExprBlock hardwhiteDefnBindingsTerminator
	| ODO ODECLEND

classDefnBindings ::=
	/*empty*/
	| defnBindings
	| doBinding
	| hardwhiteLetBindings
	| hardwhiteDoBinding

hardwhiteDefnBindingsTerminator ::=
	/*empty*/
	| ODECLEND
	| recover

cPrototype ::=
	/*empty*/
	| EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN externArgs rparen

externArgs ::=
	/*empty*/
	| externMoreArgs
	| externArg
	| /*empty*/

externMoreArgs ::=
	/*empty*/
	| externMoreArgs COMMA externArg
	| externArg COMMA externArg

externArg ::=
	/*empty*/
	| opt_attributes cType
	| opt_attributes cType ident

cType ::=
	/*empty*/
	| path
	| cType opt_HIGH_PRECEDENCE_APP LBRACK RBRACK
	| cType STAR
	| cType AMP
	| VOID STAR

cRetType ::=
	/*empty*/
	| opt_attributes cType
	| opt_attributes VOID

localBindings ::=
	/*empty*/
	| attr_localBinding moreLocalBindings

moreLocalBindings ::=
	/*empty*/
	| AND attr_localBinding moreLocalBindings
	| /*empty*/

attr_localBinding ::=
	/*empty*/
	| opt_attributes localBinding
	| error

localBinding ::=
	/*empty*/
	| opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedExprWithStaticOptimizationsBlock
	| opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error
	| opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints recover

typedExprWithStaticOptimizationsBlock ::=
	/*empty*/
	| OBLOCKBEGIN typedExprWithStaticOptimizations oblockend
	| OBLOCKBEGIN typedExprWithStaticOptimizations recover
	| typedExprWithStaticOptimizations

typedExprWithStaticOptimizations ::=
	/*empty*/
	| typedSequentialExpr opt_staticOptimizations

opt_staticOptimizations ::=
	/*empty*/
	| opt_staticOptimizations staticOptimization
	| /*empty*/

staticOptimization ::=
	/*empty*/
	| WHEN staticOptimizationConditions EQUALS typedSequentialExprBlock

staticOptimizationConditions ::=
	/*empty*/
	| staticOptimizationConditions AND staticOptimizationCondition
	| staticOptimizationCondition

staticOptimizationCondition ::=
	/*empty*/
	| typar COLON typ
	| typar STRUCT

rawConstant ::=
	/*empty*/
	| INT8
	| UINT8
	| INT16
	| UINT16
	| INT32
	| UINT32
	| INT64
	| UINT64
	| NATIVEINT
	| UNATIVEINT
	| IEEE32
	| IEEE64
	| CHAR
	| DECIMAL
	| BIGNUM
	| string
	| sourceIdentifier
	| BYTEARRAY

rationalConstant ::=
	/*empty*/
	| INT32 INFIX_STAR_DIV_MOD_OP INT32
	| MINUS INT32 INFIX_STAR_DIV_MOD_OP INT32
	| INT32
	| MINUS INT32

atomicUnsignedRationalConstant ::=
	/*empty*/
	| INT32
	| LPAREN rationalConstant rparen

atomicRationalConstant ::=
	/*empty*/
	| atomicUnsignedRationalConstant
	| MINUS atomicUnsignedRationalConstant

constant ::=
	/*empty*/
	| rawConstant
	| rawConstant HIGH_PRECEDENCE_TYAPP measureTypeArg

bindingPattern ::=
	/*empty*/
	| headBindingPattern

simplePattern ::=
	/*empty*/
	| ident
	| QMARK ident
	| simplePattern COLON typeWithTypeConstraints
	| simplePattern COLON recover
	| attributes simplePattern

simplePatternCommaList ::=
	/*empty*/
	| simplePattern
	| simplePattern COMMA simplePatternCommaList

opt_simplePatterns ::=
	/*empty*/
	| simplePatterns
	| /*empty*/

simplePatterns ::=
	/*empty*/
	| LPAREN simplePatternCommaList rparen
	| LPAREN rparen
	| LPAREN simplePatternCommaList recover
	| LPAREN error rparen
	| LPAREN recover

headBindingPattern ::=
	/*empty*/
	| headBindingPattern AS constrPattern
	| headBindingPattern BAR headBindingPattern
	| headBindingPattern COLON_COLON headBindingPattern
	| tuplePatternElements
	| conjPatternElements
	| constrPattern

tuplePatternElements ::=
	/*empty*/
	| tuplePatternElements COMMA headBindingPattern
	| headBindingPattern COMMA headBindingPattern
	| tuplePatternElements COMMA ends_coming_soon_or_recover
	| headBindingPattern COMMA ends_coming_soon_or_recover
	| COMMA headBindingPattern
	| COMMA ends_coming_soon_or_recover

conjPatternElements ::=
	/*empty*/
	| conjPatternElements AMP headBindingPattern
	| headBindingPattern AMP headBindingPattern

namePatPairs ::=
	/*empty*/
	| namePatPair opt_seps
	| namePatPair seps namePatPairs
	| namePatPair seps seps namePatPairs

namePatPair ::=
	/*empty*/
	| ident EQUALS parenPattern
	| ident EQUALS recover
	| ident recover

constrPattern ::=
	/*empty*/
	| atomicPatternLongIdent explicitValTyparDecls
	| atomicPatternLongIdent explicitValTyparDecls atomicPatsOrNamePatPairs
	| atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs
	| atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs
	| atomicPatternLongIdent atomicPatsOrNamePatPairs
	| atomicPatternLongIdent HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs
	| atomicPatternLongIdent HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs
	| COLON_QMARK atomTypeOrAnonRecdType
	| atomicPattern

atomicPatsOrNamePatPairs ::=
	/*empty*/
	| LPAREN namePatPairs rparen
	| atomicPatterns

atomicPatterns ::=
	/*empty*/
	| atomicPattern atomicPatterns
	| atomicPattern HIGH_PRECEDENCE_BRACK_APP atomicPatterns
	| atomicPattern HIGH_PRECEDENCE_PAREN_APP atomicPatterns
	| atomicPattern

atomicPattern ::=
	/*empty*/
	| quoteExpr
	| LBRACE recordPatternElementsAux rbrace
	| LBRACE error rbrace
	| LBRACK listPatternElements RBRACK
	| LBRACK_BAR listPatternElements BAR_RBRACK
	| UNDERSCORE
	| QMARK ident
	| atomicPatternLongIdent
	| constant
	| FALSE
	| TRUE
	| NULL
	| LPAREN parenPatternBody rparen
	| LPAREN parenPatternBody recover
	| LPAREN error rparen
	| LPAREN recover
	| STRUCT LPAREN tupleParenPatternElements rparen
	| STRUCT LPAREN tupleParenPatternElements recover
	| STRUCT LPAREN error rparen
	| STRUCT LPAREN recover

parenPatternBody ::=
	/*empty*/
	| parenPattern
	| /*empty*/

parenPattern ::=
	/*empty*/
	| parenPattern AS constrPattern
	| parenPattern BAR parenPattern
	| tupleParenPatternElements
	| conjParenPatternElements
	| parenPattern COLON typeWithTypeConstraints
	| parenPattern COLON recover
	| attributes parenPattern
	| parenPattern COLON_COLON parenPattern
	| constrPattern

tupleParenPatternElements ::=
	/*empty*/
	| tupleParenPatternElements COMMA parenPattern
	| parenPattern COMMA parenPattern
	| tupleParenPatternElements COMMA ends_coming_soon_or_recover
	| parenPattern COMMA ends_coming_soon_or_recover
	| COMMA parenPattern
	| COMMA ends_coming_soon_or_recover

conjParenPatternElements ::=
	/*empty*/
	| conjParenPatternElements AMP parenPattern
	| parenPattern AMP parenPattern

recordPatternElementsAux ::=
	/*empty*/
	| recordPatternElement opt_seps
	| recordPatternElement seps recordPatternElementsAux

recordPatternElement ::=
	/*empty*/
	| path EQUALS parenPattern
	| path EQUALS recover
	| path recover

listPatternElements ::=
	/*empty*/
	| /*empty*/
	| parenPattern opt_seps
	| parenPattern seps listPatternElements

typedSequentialExprBlock ::=
	/*empty*/
	| OBLOCKBEGIN typedSequentialExpr oblockend
	| OBLOCKBEGIN typedSequentialExpr recover
	| OBLOCKBEGIN oblockend
	| typedSequentialExpr

declExprBlock ::=
	/*empty*/
	| OBLOCKBEGIN typedSequentialExpr oblockend
	| OBLOCKBEGIN oblockend
	| declExpr

typedSequentialExprBlockR ::=
	/*empty*/
	| typedSequentialExpr ORIGHT_BLOCK_END
	| typedSequentialExpr
	| recover

typedSequentialExpr ::=
	/*empty*/
	| sequentialExpr COLON typeWithTypeConstraints
	| sequentialExpr COLON recover
	| sequentialExpr

typedSequentialExprEOF ::=
	/*empty*/
	| typedSequentialExpr EOF

sequentialExpr ::=
	/*empty*/
	| declExpr seps sequentialExpr
	| declExpr seps
	| declExpr
	| declExpr THEN sequentialExpr
	| declExpr OTHEN OBLOCKBEGIN typedSequentialExpr oblockend
	| hardwhiteLetBindings

recover ::=
	/*empty*/
	| error
	| EOF

moreBinders ::=
	/*empty*/
	| AND_BANG headBindingPattern EQUALS typedSequentialExprBlock IN moreBinders
	| OAND_BANG headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders
	| /*empty*/

declExpr ::=
	/*empty*/
	| defnBindings IN typedSequentialExpr
	| defnBindings IN error
	| hardwhiteLetBindings typedSequentialExprBlock
	| hardwhiteLetBindings error
	| hardwhiteLetBindings OBLOCKSEP typedSequentialExprBlock
	| hardwhiteLetBindings OBLOCKSEP error
	| hardwhiteDoBinding
	| anonMatchingExpr
	| anonLambdaExpr
	| MATCH typedSequentialExpr withClauses
	| MATCH typedSequentialExpr recover
	| MATCH_BANG typedSequentialExpr withClauses
	| MATCH_BANG typedSequentialExpr recover
	| TRY typedSequentialExprBlockR withClauses
	| TRY typedSequentialExprBlockR recover
	| TRY ORIGHT_BLOCK_END
	| TRY ORIGHT_BLOCK_END withClauses
	| TRY typedSequentialExprBlockR FINALLY typedSequentialExprBlock
	| IF declExpr ifExprCases
	| IF declExpr recover
	| IF recover
	| LAZY declExpr
	| ASSERT declExpr
	| ASSERT
	| OLAZY declExprBlock
	| OASSERT declExprBlock
	| OASSERT
	| WHILE whileExprCore
	| WHILE_BANG whileExprCore
	| FOR forLoopBinder doToken typedSequentialExprBlock doneDeclEnd
	| FOR forLoopBinder doToken typedSequentialExprBlock ends_coming_soon_or_recover
	| FOR forLoopBinder doToken error doneDeclEnd
	| FOR forLoopBinder doToken ends_coming_soon_or_recover
	| FOR forLoopBinder ends_coming_soon_or_recover
	| FOR forLoopBinder opt_OBLOCKSEP arrowThenExprR
	| FOR forLoopRange doToken typedSequentialExprBlock doneDeclEnd
	| FOR forLoopRange doToken typedSequentialExprBlock recover
	| FOR forLoopRange doToken error doneDeclEnd
	| FOR forLoopRange doToken recover
	| FOR forLoopRange recover
	| FOR error doToken typedSequentialExprBlock doneDeclEnd
	| FOR ends_coming_soon_or_recover
	| FOR parenPattern error doneDeclEnd
	| FOR parenPattern recover
	| YIELD declExpr
	| YIELD_BANG declExpr
	| YIELD recover
	| YIELD_BANG recover
	| BINDER headBindingPattern EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock
	| OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock
	| OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error
	| DO_BANG typedSequentialExpr IN opt_OBLOCKSEP typedSequentialExprBlock
	| ODO_BANG typedSequentialExprBlock hardwhiteDefnBindingsTerminator
	| FIXED declExpr
	| RARROW typedSequentialExprBlockR
	| declExpr COLON_QMARK typ
	| declExpr COLON_QMARK recover
	| declExpr COLON_GREATER typ
	| declExpr COLON_GREATER recover
	| declExpr COLON_QMARK_GREATER typ
	| declExpr COLON_QMARK_GREATER recover
	| declExpr COLON_EQUALS declExpr
	| minusExpr LARROW declExprBlock
	| tupleExpr
	| declExpr JOIN_IN declExpr
	| declExpr JOIN_IN ends_coming_soon_or_recover
	| declExpr BAR_BAR declExpr
	| declExpr BAR_BAR ends_coming_soon_or_recover
	| declExpr INFIX_BAR_OP declExpr
	| declExpr INFIX_BAR_OP ends_coming_soon_or_recover
	| declExpr OR declExpr
	| declExpr OR ends_coming_soon_or_recover
	| declExpr AMP declExpr
	| declExpr AMP ends_coming_soon_or_recover
	| declExpr AMP_AMP declExpr
	| declExpr AMP_AMP ends_coming_soon_or_recover
	| declExpr INFIX_AMP_OP declExpr
	| declExpr INFIX_AMP_OP ends_coming_soon_or_recover
	| declExpr EQUALS declExpr
	| declExpr EQUALS ends_coming_soon_or_recover
	| declExpr INFIX_COMPARE_OP declExpr
	| declExpr INFIX_COMPARE_OP ends_coming_soon_or_recover
	| declExpr DOLLAR declExpr
	| declExpr DOLLAR ends_coming_soon_or_recover
	| declExpr LESS declExpr
	| declExpr LESS ends_coming_soon_or_recover
	| declExpr GREATER declExpr
	| declExpr GREATER ends_coming_soon_or_recover
	| declExpr INFIX_AT_HAT_OP declExpr
	| declExpr INFIX_AT_HAT_OP ends_coming_soon_or_recover
	| declExpr PERCENT_OP declExpr
	| declExpr PERCENT_OP ends_coming_soon_or_recover
	| declExpr COLON_COLON declExpr
	| declExpr COLON_COLON ends_coming_soon_or_recover
	| declExpr PLUS_MINUS_OP declExpr
	| declExpr PLUS_MINUS_OP ends_coming_soon_or_recover
	| declExpr MINUS declExpr
	| declExpr MINUS ends_coming_soon_or_recover
	| declExpr STAR declExpr
	| declExpr STAR ends_coming_soon_or_recover
	| declExpr INFIX_STAR_DIV_MOD_OP declExpr
	| declExpr INFIX_STAR_DIV_MOD_OP ends_coming_soon_or_recover
	| declExpr INFIX_STAR_STAR_OP declExpr
	| declExpr INFIX_STAR_STAR_OP ends_coming_soon_or_recover
	| declExpr DOT_DOT declExpr
	| declExpr DOT_DOT
	| DOT_DOT declExpr
	| STAR
	| minusExpr

whileExprCore ::=
	/*empty*/
	| declExpr doToken typedSequentialExprBlock doneDeclEnd
	| declExpr doToken typedSequentialExprBlock recover
	| declExpr doToken error doneDeclEnd
	| declExpr recover
	| recover
	| error doneDeclEnd

dynamicArg ::=
	/*empty*/
	| IDENT
	| LPAREN typedSequentialExpr rparen

withClauses ::=
	/*empty*/
	| WITH withPatternClauses
	| OWITH withPatternClauses OEND
	| OWITH withPatternClauses recover
	| OWITH recover

withPatternClauses ::=
	/*empty*/
	| patternClauses
	| BAR patternClauses
	| BAR error
	| error

patternAndGuard ::=
	/*empty*/
	| parenPattern patternGuard

patternClauses ::=
	/*empty*/
	| patternAndGuard patternResult
	| patternAndGuard patternResult BAR patternClauses
	| patternAndGuard error BAR patternClauses
	| patternAndGuard patternResult BAR recover
	| patternAndGuard patternResult recover
	| patternAndGuard recover

patternGuard ::=
	/*empty*/
	| WHEN declExpr
	| /*empty*/

patternResult ::=
	/*empty*/
	| RARROW typedSequentialExprBlockR

ifExprCases ::=
	/*empty*/
	| ifExprThen ifExprElifs

ifExprThen ::=
	/*empty*/
	| THEN declExpr
	| THEN recover
	| OTHEN typedSequentialExprBlock
	| OTHEN recover

ifExprElifs ::=
	/*empty*/
	| /*empty*/
	| ELSE declExpr
	| OELSE typedSequentialExprBlock
	| ELIF declExpr ifExprCases
	| ELIF declExpr recover

tupleExpr ::=
	/*empty*/
	| tupleExpr COMMA declExpr
	| tupleExpr COMMA ends_coming_soon_or_recover
	| tupleExpr COMMA COMMA declExpr
	| tupleExpr COMMA COMMA ends_coming_soon_or_recover
	| declExpr COMMA ends_coming_soon_or_recover
	| declExpr COMMA declExpr
	| declExpr COMMA COMMA ends_coming_soon_or_recover
	| declExpr COMMA COMMA declExpr

minusExpr ::=
	/*empty*/
	| INFIX_AT_HAT_OP minusExpr
	| MINUS minusExpr
	| PLUS_MINUS_OP minusExpr
	| ADJACENT_PREFIX_OP minusExpr
	| PERCENT_OP minusExpr
	| AMP minusExpr
	| AMP_AMP minusExpr
	| NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType DOT atomicExprQualification
	| NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType
	| NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP error
	| NEW error
	| UPCAST minusExpr
	| DOWNCAST minusExpr
	| appExpr

appExpr ::=
	/*empty*/
	| appExpr argExpr
	| atomicExpr

argExpr ::=
	/*empty*/
	| ADJACENT_PREFIX_OP atomicExpr
	| atomicExpr

atomicExpr ::=
	/*empty*/
	| UNDERSCORE DOT atomicExpr
	| UNDERSCORE DOT appExpr recover
	| atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr
	| atomicExpr HIGH_PRECEDENCE_PAREN_APP atomicExpr
	| atomicExpr HIGH_PRECEDENCE_TYAPP typeArgsActual
	| PREFIX_OP atomicExpr
	| QUOTE ident
	| RESERVED
	| atomicExpr DOT atomicExprQualification
	| BASE DOT atomicExprQualification
	| QMARK nameop
	| atomicExpr QMARK dynamicArg
	| GLOBAL
	| identExpr
	| LBRACK listExprElements RBRACK
	| LBRACK listExprElements recover
	| LBRACK error RBRACK
	| LBRACK recover
	| STRUCT LPAREN tupleExpr rparen
	| STRUCT LPAREN tupleExpr recover
	| atomicExprAfterType

atomicExprQualification ::=
	/*empty*/
	| identOrOp
	| GLOBAL
	| /*empty*/
	| recover
	| LPAREN COLON_COLON rparen DOT INT32
	| LPAREN typedSequentialExpr rparen
	| LBRACK typedSequentialExpr RBRACK
	| LBRACK typedSequentialExpr recover
	| LBRACK error RBRACK
	| LBRACK recover

atomicExprAfterType ::=
	/*empty*/
	| constant
	| parenExpr
	| braceExpr
	| braceBarExpr
	| interpolatedString
	| NULL
	| FALSE
	| TRUE
	| quoteExpr
	| arrayExpr
	| beginEndExpr

beginEndExpr ::=
	/*empty*/
	| BEGIN typedSequentialExpr END
	| BEGIN typedSequentialExpr recover
	| BEGIN error END
	| BEGIN END

quoteExpr ::=
	/*empty*/
	| LQUOTE typedSequentialExpr RQUOTE
	| LQUOTE typedSequentialExpr recover
	| LQUOTE error RQUOTE
	| LQUOTE recover

arrayExpr ::=
	/*empty*/
	| LBRACK_BAR arrayExprElements BAR_RBRACK
	| LBRACK_BAR arrayExprElements recover
	| LBRACK_BAR error BAR_RBRACK
	| LBRACK_BAR recover

parenExpr ::=
	/*empty*/
	| LPAREN rparen
	| LPAREN parenExprBody rparen
	| LPAREN parenExprBody ends_other_than_rparen_coming_soon_or_recover
	| LPAREN error rparen
	| LPAREN TYPE_COMING_SOON
	| LPAREN MODULE_COMING_SOON
	| LPAREN RBRACE_COMING_SOON
	| LPAREN OBLOCKEND_COMING_SOON
	| LPAREN recover
	| LPAREN COMMA declExpr rparen

parenExprBody ::=
	/*empty*/
	| typars COLON LPAREN classMemberSpfn rparen typedSequentialExpr
	| typedSequentialExpr
	| inlineAssemblyExpr

typars ::=
	/*empty*/
	| typar
	| LPAREN typarAlts rparen

typarAlts ::=
	/*empty*/
	| typarAlts OR appType
	| typar

braceExpr ::=
	/*empty*/
	| LBRACE braceExprBody rbrace
	| LBRACE braceExprBody recover
	| LBRACE error rbrace
	| LBRACE recover
	| LBRACE rbrace

braceExprBody ::=
	/*empty*/
	| recdExpr
	| objExpr
	| computationExpr

listExprElements ::=
	/*empty*/
	| sequentialExpr
	| /*empty*/

arrayExprElements ::=
	/*empty*/
	| sequentialExpr
	| /*empty*/

computationExpr ::=
	/*empty*/
	| sequentialExpr

arrowThenExprR ::=
	/*empty*/
	| RARROW typedSequentialExprBlockR

forLoopBinder ::=
	/*empty*/
	| parenPattern IN declExpr
	| parenPattern IN ends_coming_soon_or_recover
	| parenPattern ends_coming_soon_or_recover

forLoopRange ::=
	/*empty*/
	| parenPattern EQUALS declExpr forLoopDirection declExpr

forLoopDirection ::=
	/*empty*/
	| TO
	| DOWNTO

inlineAssemblyExpr ::=
	/*empty*/
	| HASH string opt_inlineAssemblyTypeArg optCurriedArgExprs optInlineAssemblyReturnTypes HASH

optCurriedArgExprs ::=
	/*empty*/
	| optCurriedArgExprs argExpr
	| /*empty*/

opt_atomicExprAfterType ::=
	/*empty*/
	| /*empty*/
	| atomicExprAfterType

opt_inlineAssemblyTypeArg ::=
	/*empty*/
	| /*empty*/
	| typeKeyword LPAREN typ rparen

optInlineAssemblyReturnTypes ::=
	/*empty*/
	| /*empty*/
	| COLON typ
	| COLON LPAREN rparen

recdExpr ::=
	/*empty*/
	| INHERIT atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType recdExprBindings opt_seps_recd
	| recdExprCore

recdExprCore ::=
	/*empty*/
	| appExpr EQUALS declExprBlock recdExprBindings opt_seps_recd
	| appExpr EQUALS recover
	| appExpr
	| UNDERSCORE
	| UNDERSCORE EQUALS
	| UNDERSCORE EQUALS declExprBlock recdExprBindings opt_seps_recd
	| appExpr WITH recdBinding recdExprBindings opt_seps_recd
	| appExpr OWITH opt_seps_recd OEND
	| appExpr OWITH recdBinding recdExprBindings opt_seps_recd OEND

opt_seps_recd ::=
	/*empty*/
	| seps_recd
	| /*empty*/

seps_recd ::=
	/*empty*/
	| OBLOCKSEP
	| SEMICOLON
	| SEMICOLON OBLOCKSEP
	| OBLOCKSEP SEMICOLON

pathOrUnderscore ::=
	/*empty*/
	| path
	| UNDERSCORE

recdExprBindings ::=
	/*empty*/
	| recdExprBindings seps_recd recdBinding
	| /*empty*/

recdBinding ::=
	/*empty*/
	| pathOrUnderscore EQUALS declExprBlock
	| pathOrUnderscore EQUALS
	| pathOrUnderscore EQUALS ends_coming_soon_or_recover
	| pathOrUnderscore
	| pathOrUnderscore ends_coming_soon_or_recover

objExpr ::=
	/*empty*/
	| objExprBaseCall objExprBindings opt_OBLOCKSEP opt_objExprInterfaces
	| objExprBaseCall opt_OBLOCKSEP objExprInterfaces
	| NEW atomTypeNonAtomicDeprecated

objExprBaseCall ::=
	/*empty*/
	| NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType baseSpec
	| NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType
	| NEW atomTypeNonAtomicDeprecated

opt_objExprBindings ::=
	/*empty*/
	| objExprBindings
	| /*empty*/

objExprBindings ::=
	/*empty*/
	| WITH localBindings
	| OWITH localBindings OEND
	| WITH objectImplementationBlock opt_declEnd

objExprInterfaces ::=
	/*empty*/
	| objExprInterface opt_objExprInterfaces

opt_objExprInterfaces ::=
	/*empty*/
	| /*empty*/
	| objExprInterface opt_objExprInterfaces
	| error opt_objExprInterfaces

objExprInterface ::=
	/*empty*/
	| interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP

braceBarExpr ::=
	/*empty*/
	| STRUCT braceBarExprCore
	| braceBarExprCore

braceBarExprCore ::=
	/*empty*/
	| LBRACE_BAR recdExprCore bar_rbrace
	| LBRACE_BAR recdExprCore recover
	| LBRACE_BAR error bar_rbrace
	| LBRACE_BAR recover
	| LBRACE_BAR bar_rbrace

anonLambdaExpr ::=
	/*empty*/
	| FUN atomicPatterns RARROW typedSequentialExprBlock
	| FUN atomicPatterns RARROW error
	| OFUN atomicPatterns RARROW typedSequentialExprBlockR OEND
	| OFUN atomicPatterns RARROW typedSequentialExprBlockR recover
	| OFUN atomicPatterns RARROW ORIGHT_BLOCK_END OEND
	| OFUN atomicPatterns RARROW recover
	| OFUN atomicPatterns error OEND
	| OFUN error OEND

anonMatchingExpr ::=
	/*empty*/
	| FUNCTION withPatternClauses
	| OFUNCTION withPatternClauses OEND

typeWithTypeConstraints ::=
	/*empty*/
	| typ
	| typ WHEN typeConstraints

topTypeWithTypeConstraints ::=
	/*empty*/
	| topType
	| topType WHEN typeConstraints

opt_topReturnTypeWithTypeConstraints ::=
	/*empty*/
	| /*empty*/
	| COLON topTypeWithTypeConstraints
	| COLON recover

topType ::=
	/*empty*/
	| topTupleType RARROW topType
	| topTupleType RARROW recover
	| topTupleType

topTupleType ::=
	/*empty*/
	| topAppType STAR topTupleTypeElements
	| topAppType STAR recover
	| STAR topTupleTypeElements
	| topAppType

topTupleTypeElements ::=
	/*empty*/
	| topAppType STAR topTupleTypeElements
	| topAppType STAR recover
	| STAR topTupleTypeElements
	| topAppType

topAppType ::=
	/*empty*/
	| attributes appType COLON appType
	| attributes appType COLON recover
	| attributes QMARK ident COLON appType
	| attributes QMARK ident COLON recover
	| attributes appType
	| appType COLON appType
	| appType COLON recover
	| QMARK ident COLON appType
	| QMARK ident COLON recover
	| appType

invalidUseOfAppTypeFunction ::=
	/*empty*/
	| appType RARROW invalidUseOfAppTypeFunction
	| appType RARROW recover
	| appType RARROW RARROW invalidUseOfAppTypeFunction
	| appType RARROW appType

typ ::=
	/*empty*/
	| tupleType RARROW typ
	| tupleType RARROW recover
	| tupleType RARROW RARROW typ
	| tupleType

typEOF ::=
	/*empty*/
	| typ EOF

tupleType ::=
	/*empty*/
	| appType STAR tupleOrQuotTypeElements
	| appType STAR recover
	| STAR tupleOrQuotTypeElements
	| INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements
	| INFIX_STAR_DIV_MOD_OP recover
	| appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements
	| appType INFIX_STAR_DIV_MOD_OP recover
	| appType

tupleOrQuotTypeElements ::=
	/*empty*/
	| appType STAR tupleOrQuotTypeElements
	| appType STAR recover
	| STAR tupleOrQuotTypeElements
	| appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements
	| appType INFIX_STAR_DIV_MOD_OP recover
	| INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements
	| appType

intersectionType ::=
	/*empty*/
	| typar AMP intersectionConstraints
	| atomType AMP intersectionConstraints

appTypeCon ::=
	/*empty*/
	| path
	| typar

appTypeConPower ::=
	/*empty*/
	| appTypeCon INFIX_AT_HAT_OP atomicRationalConstant
	| appTypeCon

appType ::=
	/*empty*/
	| appType arrayTypeSuffix
	| appType HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix
	| appType appTypeConPower
	| LPAREN appTypePrefixArguments rparen appTypeConPower
	| powerType
	| intersectionType
	| typar COLON_GREATER typ
	| UNDERSCORE COLON_GREATER typ

arrayTypeSuffix ::=
	/*empty*/
	| LBRACK RBRACK
	| LBRACK COMMA RBRACK
	| LBRACK COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK
	| LBRACK COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA COMMA RBRACK

appTypePrefixArguments ::=
	/*empty*/
	| typeArgActual COMMA typeArgActual typeArgListElements

typeArgListElements ::=
	/*empty*/
	| typeArgListElements COMMA typeArgActual
	| typeArgListElements COMMA dummyTypeArg
	| /*empty*/

powerType ::=
	/*empty*/
	| atomTypeOrAnonRecdType
	| atomTypeOrAnonRecdType INFIX_AT_HAT_OP atomicRationalConstant

atomTypeNonAtomicDeprecated ::=
	/*empty*/
	| LPAREN appTypePrefixArguments rparen appTypeConPower
	| atomType

atomTypeOrAnonRecdType ::=
	/*empty*/
	| atomType
	| anonRecdType

atomType ::=
	/*empty*/
	| HASH atomType
	| appTypeConPower
	| UNDERSCORE
	| LPAREN typ rparen
	| LPAREN typ recover
	| STRUCT LPAREN appType STAR tupleOrQuotTypeElements rparen
	| STRUCT LPAREN appType STAR tupleOrQuotTypeElements recover
	| STRUCT LPAREN appType STAR recover
	| STRUCT LPAREN appType recover
	| STRUCT LPAREN recover
	| rawConstant
	| NULL
	| CONST atomicExpr
	| FALSE
	| TRUE
	| LPAREN error rparen
	| appTypeCon typeArgsNoHpaDeprecated
	| atomType DOT path
	| atomType DOT path typeArgsNoHpaDeprecated
	| appTypeCon DOT ends_coming_soon_or_recover

typeArgsNoHpaDeprecated ::=
	/*empty*/
	| typeArgsActual
	| HIGH_PRECEDENCE_TYAPP typeArgsActual

typeArgsActual ::=
	/*empty*/
	| LESS typeArgActualOrDummyIfEmpty COMMA typeArgActualOrDummyIfEmpty typeArgListElements GREATER
	| LESS typeArgActualOrDummyIfEmpty COMMA typeArgActualOrDummyIfEmpty typeArgListElements recover
	| LESS typeArgActualOrDummyIfEmpty COMMA ends_coming_soon_or_recover
	| LESS typeArgActual GREATER
	| LESS typeArgActual ends_coming_soon_or_recover
	| LESS GREATER
	| LESS recover

typeArgActual ::=
	/*empty*/
	| typ
	| typ EQUALS typ
	| typ EQUALS

typeArgActualOrDummyIfEmpty ::=
	/*empty*/
	| typeArgActual
	| dummyTypeArg

dummyTypeArg ::=
	/*empty*/
	| /*empty*/

measureTypeArg ::=
	/*empty*/
	| LESS measureTypeExpr GREATER
	| LESS UNDERSCORE GREATER

measureTypeAtom ::=
	/*empty*/
	| path
	| typar
	| LPAREN measureTypeExpr rparen

measureTypePower ::=
	/*empty*/
	| measureTypeAtom
	| measureTypeAtom INFIX_AT_HAT_OP atomicRationalConstant
	| INT32

measureTypeSeq ::=
	/*empty*/
	| measureTypePower
	| measureTypePower measureTypeSeq

measureTypeExpr ::=
	/*empty*/
	| measureTypeSeq
	| measureTypeExpr STAR measureTypeExpr
	| measureTypeExpr INFIX_STAR_DIV_MOD_OP measureTypeExpr
	| INFIX_STAR_DIV_MOD_OP measureTypeExpr

typar ::=
	/*empty*/
	| QUOTE ident
	| INFIX_AT_HAT_OP ident

ident ::=
	/*empty*/
	| IDENT

path ::=
	/*empty*/
	| GLOBAL
	| ident
	| path DOT ident
	| path DOT ends_coming_soon_or_recover

opName ::=
	/*empty*/
	| LPAREN operatorName rparen
	| LPAREN error rparen
	| LPAREN_STAR_RPAREN
	| LPAREN activePatternCaseNames BAR rparen
	| LPAREN activePatternCaseNames BAR UNDERSCORE BAR rparen

operatorName ::=
	/*empty*/
	| PREFIX_OP
	| INFIX_STAR_STAR_OP
	| INFIX_COMPARE_OP
	| INFIX_AT_HAT_OP
	| INFIX_BAR_OP
	| INFIX_AMP_OP
	| PLUS_MINUS_OP
	| INFIX_STAR_DIV_MOD_OP
	| DOLLAR
	| ADJACENT_PREFIX_OP
	| MINUS
	| STAR
	| EQUALS
	| OR
	| LESS
	| GREATER
	| QMARK
	| AMP
	| AMP_AMP
	| BAR_BAR
	| COLON_EQUALS
	| FUNKY_OPERATOR_NAME
	| PERCENT_OP
	| DOT_DOT
	| DOT_DOT DOT_DOT
	| LQUOTE RQUOTE

activePatternCaseName ::=
	/*empty*/
	| IDENT

activePatternCaseNames ::=
	/*empty*/
	| BAR activePatternCaseName
	| activePatternCaseNames BAR activePatternCaseName

identOrOp ::=
	/*empty*/
	| ident
	| opName

pathOp ::=
	/*empty*/
	| ident
	| opName
	| ident DOT pathOp
	| ident DOT ends_coming_soon_or_recover

nameop ::=
	/*empty*/
	| identOrOp

identExpr ::=
	/*empty*/
	| ident
	| opName

topSeparator ::=
	/*empty*/
	| SEMICOLON
	| SEMICOLON_SEMICOLON
	| OBLOCKSEP

topSeparators ::=
	/*empty*/
	| topSeparator
	| topSeparator topSeparators

opt_topSeparators ::=
	/*empty*/
	| topSeparator opt_topSeparators
	| /*empty*/

seps ::=
	/*empty*/
	| OBLOCKSEP
	| SEMICOLON
	| OBLOCKSEP SEMICOLON
	| SEMICOLON OBLOCKSEP

declEnd ::=
	/*empty*/
	| ODECLEND
	| OEND
	| END

opt_declEnd ::=
	/*empty*/
	| ODECLEND
	| OEND
	| END
	| /*empty*/

opt_ODECLEND ::=
	/*empty*/
	| ODECLEND
	| /*empty*/

deprecated_opt_equals ::=
	/*empty*/
	| EQUALS
	| /*empty*/

opt_equals ::=
	/*empty*/
	| EQUALS
	| /*empty*/

opt_OBLOCKSEP ::=
	/*empty*/
	| OBLOCKSEP
	| /*empty*/

opt_seps ::=
	/*empty*/
	| seps
	| /*empty*/

opt_rec ::=
	/*empty*/
	| REC
	| /*empty*/

opt_bar ::=
	/*empty*/
	| BAR
	| /*empty*/

opt_inline ::=
	/*empty*/
	| INLINE
	| /*empty*/

opt_mutable ::=
	/*empty*/
	| MUTABLE
	| /*empty*/

doToken ::=
	/*empty*/
	| DO
	| ODO

doneDeclEnd ::=
	/*empty*/
	| DONE
	| ODECLEND

structOrBegin ::=
	/*empty*/
	| STRUCT
	| BEGIN

sigOrBegin ::=
	/*empty*/
	| SIG
	| BEGIN

colonOrEquals ::=
	/*empty*/
	| COLON
	| EQUALS

string ::=
	/*empty*/
	| STRING

sourceIdentifier ::=
	/*empty*/
	| KEYWORD_STRING

interpolatedStringFill ::=
	/*empty*/
	| declExpr
	| declExpr COLON ident

interpolatedStringParts ::=
	/*empty*/
	| INTERP_STRING_END
	| INTERP_STRING_PART interpolatedStringFill interpolatedStringParts
	| INTERP_STRING_PART interpolatedStringParts

interpolatedString ::=
	/*empty*/
	| INTERP_STRING_BEGIN_PART interpolatedStringFill interpolatedStringParts
	| INTERP_STRING_BEGIN_END
	| INTERP_STRING_BEGIN_PART interpolatedStringParts

opt_HIGH_PRECEDENCE_APP ::=
	/*empty*/
	| HIGH_PRECEDENCE_BRACK_APP
	| HIGH_PRECEDENCE_PAREN_APP
	| /*empty*/

opt_HIGH_PRECEDENCE_TYAPP ::=
	/*empty*/
	| HIGH_PRECEDENCE_TYAPP
	| /*empty*/

typeKeyword ::=
	/*empty*/
	| TYPE_COMING_SOON typeKeyword
	| TYPE_IS_HERE
	| TYPE

moduleKeyword ::=
	/*empty*/
	| MODULE_COMING_SOON moduleKeyword
	| MODULE_IS_HERE
	| MODULE

rbrace ::=
	/*empty*/
	| RBRACE_COMING_SOON rbrace
	| RBRACE_IS_HERE
	| RBRACE

bar_rbrace ::=
	/*empty*/
	| BAR_RBRACE

rparen ::=
	/*empty*/
	| RPAREN_COMING_SOON rparen
	| RPAREN_IS_HERE
	| RPAREN

oblockend ::=
	/*empty*/
	| OBLOCKEND_COMING_SOON oblockend
	| OBLOCKEND_IS_HERE
	| OBLOCKEND

ends_other_than_rparen_coming_soon_or_recover ::=
	/*empty*/
	| TYPE_COMING_SOON
	| MODULE_COMING_SOON
	| RBRACE_COMING_SOON
	| OBLOCKEND_COMING_SOON
	| recover

ends_coming_soon_or_recover ::=
	/*empty*/
	| TYPE_COMING_SOON
	| MODULE_COMING_SOON
	| RBRACE_COMING_SOON
	| RPAREN_COMING_SOON
	| OBLOCKEND_COMING_SOON
	| recover

//Tokens

LQUOTE ::= "<@"
LQUOTE ::= "<@@"
RQUOTE ::= "@>"
RQUOTE ::= "@@>"
HASH ::= '#'
AMP ::= '&'
AMP_AMP ::= "&&"
BAR_BAR ::= "||"
QUOTE ::= "'"
LPAREN ::= '('
RPAREN ::= ')'
STAR ::= '*'
COMMA ::= ','
RARROW ::= "->"
QMARK ::= "?"
QMARK_QMARK ::= "??"
DOT_DOT ::= ".."
DOT_DOT_HAT ::= "..^"
DOT ::= "."
COLON ::= ":"
COLON_COLON ::= "::"
COLON_GREATER ::= ":>"
RQUOTE_DOT ::= "@>."
RQUOTE_DOT ::= "@@>."
GREATER_BAR_RBRACK ::= ">|]"
COLON_QMARK_GREATER ::= ":?>"
COLON_QMARK ::= ":?"
COLON_EQUALS ::= ":="
SEMICOLON_SEMICOLON ::= ";;"
SEMICOLON ::= ";"
LARROW ::= "<-"
EQUALS ::= "="
LBRACK ::= "["
LBRACK_BAR ::= "[|"
LBRACE_BAR ::= "{|"
LESS ::= "<"
GREATER ::= ">"
LBRACK_LESS ::= "[<"
RBRACK ::= "]"
BAR_RBRACK ::= "|]"
BAR_RBRACE ::= "|}"
GREATER_RBRACK ::= ">]"
BAR ::= "|"
DOLLAR ::= "$"
PERCENT_OP ::= "%"
PERCENT_OP ::= "%%"
MINUS ::= "-"
RESERVED ::= "~"
FUNKY_OPERATOR_NAME ::= ".()<-" | ".()"

ABSTRACT ::= "abstract"
AND ::= "and"
AS ::= "as"
ASSERT ::= "assert"
INFIX_STAR_STAR_OP ::= "asr"
BASE ::= "base"
BEGIN ::= "begin"
CLASS ::= "class"
CONST ::= "const"
DEFAULT ::= "default"
DELEGATE ::= "delegate"
DO ::= "do"
DONE ::= "done"
DOWNCAST ::= "downcast"
DOWNTO ::= "downto"
ELIF ::= "elif"
ELSD ::= "else"
END ::= "end"
EXCEPTION ::= "exception"
EXTERN ::= "extern"
FALSE ::= "false"
FINALLY ::= "finally"
FIXED ::= "fixed"
FOR ::= "for"
FUN ::= "fun"
FUNCTION ::= "function"
GLOBAL ::= "global"
IF ::= "if"
IN ::= "in"
INHERIT ::= "inherit"
INLINE ::= "inline"
INTERFACE ::= "interface"
INTERNAL ::= "internal"
INFIX_STAR_DIV_MOD_OP ::= "land"
LAZY ::= "lazy"
LET ::= "let"
INFIX_STAR_DIV_MOD_OP ::= "lor"
INFIX_STAR_STAR_OP ::= "lsl"
INFIX_STAR_STAR_OP ::= "lsr"
INFIX_STAR_DIV_MOD_OP ::= "lxor"
MATCH ::= "match"
MEMBER ::= "member"
INFIX_STAR_DIV_MOD_OP ::= "mod"
MODULE ::= "module"
MUTABLE ::= "mutable"
NAMESPACE ::= "namespace"
NEW ::= "new"
NULL ::= "null"
OF ::= "of"
OPEN ::= "open"
OR ::= "or"
OVERRIDE ::= "override"
PRIVATE ::= "private"
PUBLIC ::= "public"
REC ::= "rec"
YIELD ::= "return"
SIG ::= "sig"
STATIC ::= "static"
STRUCT ::= "struct"
THEN ::= "then"
TO ::= "to"
TRUE ::= "true"
TRY ::= "try"
TYPE ::= "type"
UPCAST ::= "upcast"
LET ::= "use"
VAL ::= "val"
VOID ::= "void"
WHEN ::= "when"
WHILE ::= "while"
WITH ::= "with"
YIELD ::= "yield"
UNDERSCOR ::= "_"
/*------- for prototyping and explaining offside rule */
OBLOCKSEP ::= "__token_OBLOCKSEP"
OWITWH ::= "__token_OWITH"
ODECLEND ::= "__token_ODECLEND"
OTHEN ::= "__token_OTHEN"
OELSE ::= "__token_OELSE"
OEND ::= "__token_OEND"
ODO ::= "__token_ODO"
OLET ::= "__token_OLET"
CONSTRAINT ::= "__token_constraint"

/*------- reserved keywords which are ml-compatibility ids */
/*
"break"
"checked"
"component"
"constraint"
"continue"
"fori"
"include"
"mixin"
"parallel"
"params"
"process"
"protected"
"pure"
"sealed"
"trait"
"tailcall"
"virtual"
*/

mingodad avatar Nov 05 '23 23:11 mingodad

Hello @mingodad,

Sorry to ask but could you please explain what is the goal of your issue ? I am not familiar with the EBNF stuff.

If you used the https://github.com/fable-compiler/Fable/blob/0de8beb1865ff12f58b5827f17147ef0a4ee62bf/src/fcs-fable/src/Compiler/pars.fsy file to generate the EBNF, then this is the F# parser that you are working on and not Fable. Fable doesn't really parse the F# files, it use the F# Compiler Service in order to do that.

MangelMaxime avatar Nov 06 '23 09:11 MangelMaxime

Thank you for reply ! So it's effectively a F# EBNF for railroad diagram generation. This is not really an issue, it shows what can be done to help document/debug/develop the language . Maybe move it to a Discussion would be better.

mingodad avatar Nov 06 '23 09:11 mingodad

Is this the original F# parser ? Because when giving it to bison/byacc/... it gives a lot of conflicts:

bison-nb -v fsharp-parser.g.y
fsharp-parser.g.y: warning: 16618 shift/reduce conflicts [-Wconflicts-sr]
fsharp-parser.g.y: warning: 1119463 reduce/reduce conflicts [-Wconflicts-rr]
fsharp-parser.g.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples

mingodad avatar Nov 06 '23 11:11 mingodad

I've compared it with https://github.com/dotnet/fsharp/blob/main/src/Compiler/pars.fsy and indeed it is the original one (with a small difference, maybe due to library changes):

--- <unnamed>
+++ <unnamed>
@@ -158,9 +158,9 @@
 %type <Ident> ident
 %type <SynType> typ typEOF
 %type <SynTypeDefnSig list> tyconSpfnList
-%type <SynArgPats * Range> atomicPatsOrNamePatPairs
+%type <SynArgPats * range> atomicPatsOrNamePatPairs
 %type <SynPat list> atomicPatterns
-%type <Range * SynExpr> patternResult
+%type <range * SynExpr> patternResult
 %type <SynExpr> declExpr
 %type <SynExpr> minusExpr
 %type <SynExpr> appExpr

mingodad avatar Nov 06 '23 11:11 mingodad

@mingodad Yes, it's the same parser that F# compiler uses, the minor difference you see there is for consistency, to make it compile without F# signature files. Range and range are the same type.

Fable is a downstream repo, we only consume the F# compiler as a service. Perhaps you can move this issue to the upstream repo https://github.com/dotnet/fsharp, where it will get more visibility.

The F# compiler uses fslex/fsyacc, and yes, it usually generates a lot of conflicts, but it seems to work.

ncave avatar Nov 06 '23 14:11 ncave