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)