Grammar ======= Here is the grammar used to parse FunL presented in EBNF. Syntactic Grammar ----------------- The syntactic grammar productions:: source ::= Newline | statements declaration ::= imports | natives | constants | variables | data | definitions imports ::= 'import' importModule | 'import' Indent importModule+ Dedent Newline importModule ::= name natives ::= 'native' name | 'native' Indent name+ Dedent Newline | 'function' name | 'function' Indent name+ Dedent Newline dottedName ::= ident ('.' ident)* qualifier ::= ident ('=>' ident)? name ::= dottedName ('=>' ident)? Newline | dottedName '.' '{' qualifier (',' qualifier)* '}' Newline | dottedName '.' '*' Newline identifiers ::= ident (',' ident)* constants ::= 'val' constant | 'val' Indent constant+ Dedent Newline constant ::= pattern '=' expressionOrBlock Newline variables ::= 'var' variable | 'var' Indent variable+ Dedent Newline variable ::= ident ('=' expressionOrBlock)? Newline data ::= 'data' datatype | 'data' Indent datatype+ Dedent Newline datatype ::= ident '=' constructor ('|' constructor)* Newline | constructor Newline constructor ::= ident '(' identifiers ')' | ident definitions ::= 'def' definition | 'def' Indent definition+ Dedent Newline definition ::= ident ('(' (pattern (',' pattern)*)? ')')? (optionallyGuardedPart | guardedParts) optionallyGuardedPart ::= ('|' booleanExpression)? '=' expressionOrBlock Newline guardedPart ::= '|' ('otherwise' | booleanExpression) '=' expressionOrBlock Newline guardedParts ::= Indent guardedPart+ Dedent Newline statements ::= statement+ optionalNewline ::= Newline? expressionStatement ::= expression Newline statement ::= expressionStatement | declaration blockExpression ::= Indent statements Dedent assignment ::= '=' | '+=' | '-=' | '*=' | '/=' | '\=' | '^=' expression ::= lvalueExpression (',' lvalueExpression)* assignment nonAssignmentExpression (',' nonAssignmentExpression)* | nonAssignmentExpression lambdaExpression ::= ('(' pattern (',' pattern)* ')' | pattern) ('|' booleanExpression)? '->' expression caseFunctionExpression ::= Indent lambdaExpression (Newline lambdaExpression)* Dedent functionExpression ::= lambdaExpression | caseFunctionExpression nonAssignmentExpression ::= functionExpression | controlExpression elif ::= optionalNewline 'elif' booleanExpression ('then' expressionOrBlock | blockExpression) generator ::= pattern '<-' expression ('if' expression)? generators ::= generator (',' generator)* expressionOrBlock ::= expression | blockExpression elif ::= optionalNewline 'elif' booleanExpression ('then' expressionOrBlock | blockExpression) elsePart ::= (optionalNewline 'else' expressionOrBlock)? controlExpression ::= 'if' booleanExpression ('then' expressionOrBlock | blockExpression) elif* elsePart | 'for' generators ('do' expressionOrBlock | blockExpression) elsePart | 'for' expressionOrBlock | 'while' expression ('do' expressionOrBlock | blockExpression) elsePart | 'do' expression optionalNewline 'while' expression elsePart | 'do' expression optionalNewline 'until' expression elsePart | 'break' | 'continue' | 'return' expression? | 'case' expression ('of' functionExpression | caseFunctionExpression) | orExpression booleanExpression ::= orExpression orExpression ::= orExpression ('or' | 'xor') andExpression | andExpression andExpression ::= andExpression ('and' | 'rotateright' | 'rotateleft' | 'shiftright' | 'shiftleft') notExpression | notExpression notExpression ::= 'not' notExpression | comparisonExpression comparisonExpression ::= iteratorExpression ('==' | '!=' | '<' | '>' | '<=' | '>=' | 'in' | 'not' 'in'^ 'notin' | '|' | '/|') iteratorExpression | iteratorExpression 'is' ident | iteratorExpression iteratorExpression ::= (consExpression '|') generators | consExpression consExpression ::= rangeExpression (':' consExpression) | rangeExpression ('#' consExpression) | rangeExpression keyExpression ::= rangeExpression rangeExpression ::= additiveExpression ('..' | 'until') additiveExpression ('by' additiveExpression)? | (additiveExpression '..') ('by' additiveExpression)? | additiveExpression additiveExpression ::= additiveExpression ('+' | '-') multiplicativeExpression | multiplicativeExpression multiplicativeExpression ::= multiplicativeExpression ('*' | '/' | '\' | '%') exponentialExpression | multiplicativeExpression applyExpression | exponentialExpression exponentialExpression ::= exponentialExpression '^' negationExpression | negationExpression negationExpression ::= '-' incrementExpression | incrementExpression incrementExpression ::= ('++' | '--') applyExpression | applyExpression ('++' | '--') | applyExpression lvalueExpression ::= applyExpression applyExpression ::= applyExpression ('(' (expression (',' expression)*)? ')') | applyExpression ('.' | '.>') ident | primaryExpression MapEntry ::= keyExpression ':' expression comprehensionExpression ::= consExpression '|' generators primaryExpression ::= numericLit | stringLit | '(' infix ')' | '(' expression infix ')' | '(' infixNoMinus expression ')' | '(' expression ')' | ident | ('true' | 'false') | '(' ')' | ('(' nonAssignmentExpression ',') nonAssignmentExpression (',' nonAssignmentExpression)* ')' | '[' comprehensionExpression ']' | '[' (nonAssignmentExpression (',' nonAssignmentExpression)*)? ']' | 'null' | '{' (keyExpression (',' keyExpression)*)? '}' | '{' MapEntry (',' MapEntry)* '}' | '$' ident | '?' ident infixNoMinus ::= '+' | '*' | '/' | '\' | '^' | '%' | '==' | '!=' | '<' | '>' | '<=' | '>=' | ':' | '#' | 'and' | 'or' | 'xor' infix ::= infixNoMinus | '-' pattern ::= ident '@' typePattern | typePattern typePattern ::= consPattern '::' ident | consPattern consPattern ::= primaryPattern ':' consPattern | primaryPattern primaryPattern ::= numericLit | stringLit | 'true' | 'false' | '(' ')' | 'null' | ident '(' pattern (',' pattern)* ')' | ident | '(' pattern ',' pattern (',' pattern)* ')' | '[' (pattern (',' pattern)*)? ']' | '{' '}' | '(' pattern '|' pattern ('|' pattern)* ')' | '(' pattern ')' Lexical Grammar --------------- The reserved words in the language are: ``and``, ``break``, ``by``, ``case``, ``class``, ``continue``, ``data``, ``def``, ``do``, ``elif``, ``else``, ``false``, ``for``, ``forever``, ``function``, ``if``, ``import``, ``in``, ``is``, ``mod``, ``native``, ``not``, ``null``, ``of``, ``or``, ``otherwise``, ``repeat``, ``return``, ``then``, ``true``, ``until``, ``val``, ``var``, ``while``, ``xor``, ``yield``. The special delimiters are: ``+``, ``*``, ``-``, ``/``, ``^``, ``(``, ``)``, ``[``, ``]``, ``|``, ``{``, ``}``, ``,``, ``=``, ``==``, ``!=``, ``<``, ``$``, ``>``, ``<-``, ``<=``, ``>=``, ``--``, ``++``, ``.``, ``..``, ``<-``, ``->``, ``=>``, ``+=``, ``-=``, ``*=``, ``/=``, ``^=``, ``:``, ``\\``, ``::``, ``@``, ``?``. The lexical grammar productions:: decimalParser = rep1(digit) ~ optFraction ~ optExponent | fraction ~ optExponent sign = '+' | '-' optSign = opt( sign ) fraction = '.' ~ rep1(digit) optFraction = opt( fraction ) exponent = ('e' | 'E') ~ optSign ~ rep1(digit) optExponent = opt(exponent)