Syntax Reference¶
Here we present a rough description of Idris’ surface syntax as an eBNF grammar. This presentend grammar may differ from syntax that Idris’ parser can handle due to the parser and grammar description not being in sync.
Notation¶
Grammar shortcut notation:
~CHARSEQ = complement of char sequence (i.e. any character except CHARSEQ)
RULE? = optional rule (i.e. RULE or nothing)
RULE* = repeated rule (i.e. RULE zero or more times)
RULE+ = repeated rule with at least one match (i.e. RULE one or more times)
RULE! = invalid rule (i.e. rule that is not valid in context, report meaningful error in case)
RULE{n} = rule repeated n times
Main Grammar¶
ModuleHeader ::=DocComment_t? "module"Identifier_t";"? ; Import ::= "import"Identifier_t";"? ; Prog ::=Decl*EOF; Decl ::=DeclP|Using|Params|Mutual|Namespace|Interface|Implementation|DSL|Directive|Provider|Transform|Import! |RunElabDecl; DeclP ::=Fixity|FunDecl|Data|Record|SyntaxDecl;
Syntax Declarations¶
SyntaxDecl ::=SyntaxRule; SyntaxRuleOpts ::= "term" | "pattern" ; SyntaxRule ::=SyntaxRuleOpts? "syntax"SyntaxSym+ "="TypeExprTerminator; SyntaxSym ::= '['Name_t']' | '{'Name_t'}' |Name_t|StringLiteral_t; SyntaxSym ::= '['Name_t']' | '{'Name_t'}' |Name_t|StringLiteral_t;
Functions¶
FunDecl ::=FunDeclP; FunDeclP ::=DocComment_t?FnOpts*Accessibility?FnOpts*FnNameTypeSigTerminator|Postulate|Pattern|CAF; FnOpts ::=FnOpt*AccessibilityFnOpt* ; FnOpt ::= 'total' | 'partial' | 'covering' | 'implicit' | '%' 'no_implicit' | '%' 'assert_total' | '%' 'error_handler' | '%' 'reflection' | '%' 'specialise' '['NameTimesList? ']' ; NameTimes ::=FnNameNatural?; NameTimesList ::=NameTimes|NameTimes','NameTimesList; Postulate ::=DocComment_t? 'postulate'FnOpts*Accesibility?FnOpts*FnNameTypeSigTerminator;
Blocks & Namespaces¶
Using ::= 'using' '(' UsingDeclList ')' OpenBlock Decl* CloseBlock ;
UsingDeclList ::= UsingDeclListP | `NameList TypeSig`;
UsingDeclListP ::= UsingDecl | UsingDecl ',' UsingDeclListP ;
NameList ::= Name | Name ',' NameList ;
UsingDecl ::= FnName TypeSig | FnName FnName+ ;
Params ::= 'parameters' '(' TypeDeclList ')' OpenBlock Decl* CloseBlock;
Mutual ::= 'mutual' OpenBlock Decl* CloseBlock ;
Namespace ::= 'namespace' identifier OpenBlock Decl+ CloseBlock ;
Interfaces & Implementation¶
ImplementationBlock ::= 'where'OpenBlockFnDecl*CloseBlock; MethodOrImplementation ::=FnDecl|Implementation; InterfaceBlock ::= 'where'OpenBlockConstructor?MethodOrImplementation*CloseBlock; InterfaceArgument ::=Name| '('Name':'Expr')'; Interface ::= :=DocComment_t?Accessibility? 'interface'ConstraintList?NameInterfaceArgument*InterfaceBlock?; Implementation ::=DocComment_t? 'implementation'ImplementationName?ConstraintList?NameSimpleExpr*ImplementationBlock? ; ImplementationName ::= '['Name']';
Bodies¶
Pattern ::=Clause; CAF ::= 'let'FnName'='ExprTerminator; ArgExpr ::=HSimpleExpr| "In Pattern External (User-defined) Expression"; RHS ::= '='Expr| '?='RHSName?Expr|Impossible; RHSName ::= '{'FnName'}' ; RHSOrWithBlock ::=RHSWhereOrTerminator| 'with'SimpleExprOpenBlockFnDecl+CloseBlock; Clause ::=WExpr+RHSOrWithBlock|SimpleExpr'<=='FnNameRHSWhereOrTerminator|ArgExprOperatorArgExprWExpr*RHSOrWithBlock{- Except "=" and "?=" operators to avoid ambiguity -} |FnNameConstraintArg*ImplicitOrArgExpr*WExpr*RHSOrWithBlock; ImplicitOrArgExpr ::= :=ImplicitArg|ArgExpr; WhereOrTerminator ::= :=WhereBlock|Terminator; WExpr ::= := '|'Expr'; WhereBlock ::= 'where'OpenBlockDecl+CloseBlock;
Directives¶
Codegen ::= 'C'
| 'Java'
| 'JavaScript'
| 'Node'
| 'LLVM'
| 'Bytecode' ;
StringList ::= String | String ',' StringList ;
Directive ::= '%' DirectiveP;
DirectiveP ::= 'lib' CodeGen String_t
| 'link' CodeGen String_t
| 'flag' CodeGen String_t
| 'include' CodeGen String_t
| 'hide' Name
| 'freeze' Name
| 'thaw' Name
| 'access' Accessibility
| 'default' Totality
| 'logging' Natural
| 'dynamic' StringList
| 'name' Name NameList
| 'error_handlers' Name NameList
| 'language' 'TypeProviders'
| 'language' 'ErrorReflection'
| 'deprecated' Name String
| 'fragile' Name Reason ;
LangExt ::= "TypeProviders"
| "ErrorReflection"
| "UniquenessTypes"
| "LinearTypes"
| "DSLNotation"
| "ElabReflection"
| "FirstClassReflection" ;
Totality ::= 'partial' | 'total' | 'covering'
Provider ::= DocComment_t? '%' 'provide' Provider_What? '(' FnName TypeSig ')' 'with' Expr;
ProviderWhat ::= 'proof' | 'term' | 'type' | 'postulate'
Transform ::= '%' 'transform' Expr '==>' Expr;
RunElabDecl ::= '%' 'runElab' Expr;
Expressions¶
FullExpr ::=ExprEOF_t; Expr ::=Pi; OpExpr ::= "Expression Parser with Operators based on ExprP" ; ExprP ::= "External (User-defined) Syntax" |InternalExpr; InternalExpr ::=UnifyLog|RecordType|SimpleExpr|Lambda|QuoteGoal|Let|If|RewriteTerm|CaseExpr|DoBlock|App;
Bodies¶
Impossible ::=impossible; CaseExpr ::= "case"Expr"of"OpenBlockCaseOption+CloseBlock; CaseOption ::=Expr(Impossible| "=>"Expr)Terminator; ProofExpr ::= "proof"OpenBlock`Tactic'`*CloseBlock; TacticsExpr ::= "tactics"OpenBlock`Tactic'`*CloseBlock; SimpleExpr ::= "External (User-defined) Simple Expression" | "?"Name| "%" "implementation" | "Refl" ("{"Expr"}")? |ProofExpr|TacticsExpr|FnName|Idiom|List|Alt|Bracketed|Constant|Type| "Void" |Quasiquote|NameQuote|Unquote| "_" ; Bracketed ::= "("BracketedP; BracketedP ::= ")" |Expr")" |ExprList")" |DependentPair")" |OperatorExpr")" |ExprOperator")" ; Alt ::= "(|"Expr_List"|)" ; Expr_List ::= `Expr'` | `Expr'` ","Expr_List; HSimpleExpr ::= "."SimpleExpr|SimpleExpr; UnifyLog ::= "%" "unifyLog"SimpleExpr; RunTactics ::= "%" "runElab"SimpleExpr; Disamb ::= "with"NameListExpr; NoImplicits ::= "%" "noImplicits"SimpleExpr; App ::= "mkForeign"ArgArg* |MatchApp|SimpleExprArg* ; MatchApp ::=SimpleExpr"<=="FnName; Arg ::= ` ImplicitArg` |ConstraintArg|SimpleExpr; ImplicitArg ::= "{"Name("="Expr)? "}" ; ConstraintArg ::= "@{"Expr"}" ; Quasiquote ::= "`("Expr")" ; Unquote ::= ","Expr; RecordType ::= "record" "{"FieldTypeList"}" ; FieldTypeList ::=FieldType|FieldType","FieldTypeList; FieldType ::=FnName"="Expr; TypeSig ::= ":"Expr; TypeExpr ::=ConstraintList?Expr; Lambda ::= "\\"TypeOptDeclListLambdaTail| "\\"SimpleExprListLambdaTail; SimpleExprList ::=SimpleExpr|SimpleExpr","SimpleExprList; LambdaTail ::=Impossible| "=>"Expr; RewriteTerm ::= "rewrite"Expr("==>"Expr)? "in"Expr; RigCount ::= "1" : "0" ; Let ::= "let"NameTypeSig"? "="Expr"in"Expr| "let" `Expr'` "=" `Expr'` "in"Expr; TypeSig' ::= ":" `Expr'` ; If ::= "if"Expr"then"Expr"else"Expr; QuoteGoal ::= "quoteGoal"Name"by"Expr"in"Expr;
Pies¶
Pi ::=PiOptsStatic?PiP; PiP ::=OpExpr("->"Pi)? | "("TypeDeclList")" "->"Pi| "{"TypeDeclList"}" "->"Pi| "{" "auto"TypeDeclList"}" "->"Pi| "{" "default"SimpleExprTypeDeclList"}" "->"Pi; PiOpts ::= "."? ; ConstraintList ::= "("Expr_List")" "=>" |Expr"=>" ; TypeDeclList ::=FunctionSignatureList|NameListTypeSig; FunctionSignatureList ::=NameTypeSig|NameTypeSig","FunctionSignatureList; TypeOptDeclList ::=NameOrPlaceholderTypeSig? |NameOrPlaceholderTypeSig? ","TypeOptDeclList; NameOrPlaceHolder ::=Name: "_" ; ListExpr ::= "[" "]" | "["Expr"|"DoList"]" | "["ExprList"]" ; ExprList ::=Expr|Expr","ExprList;
Do Blocks & Idioms¶
DoList ::=Do:Do","DoList; Do' ::=DoKeepTerminator; DoBlock ::= "do"OpenBlock`Do'`+CloseBlock; Do ::= "let"NameTypeSig"? "="Expr| "let" `Expr'` "="Expr| "rewrite"Expr|Name"<-"Expr| `Expr'` "<-"Expr|Expr; Idiom ::= "[|"Expr"|]" ;
Constants¶
Constant ::= | "Integer"
| "Int"
| "Char"
| "Double"
| "String"
| "Bits8"
| "Bits16"
| "Bits32"
| "Bits64"
| Float_t
| Natural_t
| VerbatimString_t
| String_t
| Char_t ;
VerbatimString_t ::= "\"\"\"" ~"\"\"\"" "\""* "\"\"\"" ;
Tactics¶
Tactic ::= "intro"NameList? | "intros" | "refine"NameImp+ | "mrefine"Name| "rewrite"Expr| "induction"Expr| "equiv"Expr| "let"Name":" `Expr'` "="Expr| "let"Name"="Expr| "focus"Name| "exact"Expr| "applyTactic"Expr| "reflect"Expr| "fill"Expr| "try"Tactic"|"Tactic| "{"TacticSeq"}" | "compute" | "trivial" | "solve" | "attack" | "state" | "term" | "undo" | "qed" | "abandon" | ":" "q" ; TacticSeq ::=Tactic";"Tactic|Tactic";"TacticSeq;
Misc¶
Imp ::= "?" | "_" ; Static ::= "%static" ;
Data¶
Record ::=DocCommentAccessibility? "record"FnNameTypeSig"where"OpenBlockConstructorKeepTerminatorCloseBlock; DataI ::= "data" | "codata"; Data ::=DocComment?Accessibility?DataIFnNameTypeSigExplicitTypeDataRest?DocComment?Accessibility?DataIFnNameName*DataRest? ; Constructor' ::=ConstructorKeepTerminator; ExplicitTypeDataRest ::= "where"OpenBlock`Constructor'`*CloseBlock; DataRest ::= "="SimpleConstructorListTerminator| "where"!; SimpleConstructorList ::=SimpleConstructor|SimpleConstructor"|"SimpleConstructorList; Constructor ::=DocComment?FnNameTypeSig; SimpleConstructor ::=FnNameSimpleExpr*DocComment?; DSL ::= "dsl"FnNameOpenBlock`Overload'`+CloseBlock; OverloadIdentifier ::= "let" |Identifier; Overload ::=OverloadIdentifier"="Expr;
Operators¶
BacktickOperator ::=Name; OperatorName ::=SymbolicOperator:BacktickOperator; OperatorFront ::= "(" "=" ")" | (Identifier_t".")? "("Operator_t")" ; FnName ::=Name|OperatorFront; Fixity ::=FixityTypeNatural_tOperatorListTerminator; FixityType ::= "infixl" | "infixr" | "infix" | "prefix";
Documentation¶
SingleLineComment_t ::= "--" ~EOL_t*EOL_t; MultiLineComment_t ::= "{" .. "}" | "{ -"InCommentChars_t; InCommentChars_t ::= "- }" |MultiLineComment_tInCommentChars_t| ~"- }"+InCommentChars_t; DocComment_t ::=DocCommentLine(ArgCommentLineDocCommentLine*)* ; DocCommentLine ::= "|||" ~EOL_t*EOL_t; ArgCommentLine ::= "|||" "@" ~EOL_t*EOL_t;