Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
211 lines (171 sloc) 6.85 KB
(*
EBNF Syntax Definition for the Elm programming language, version 0.15
Author: Jeff Smits
Reproduced based on the existing language by Evan Czaplicki
*)
(* Start symbol *)
Start = Module
(* Lexical primitives *)
lower = "a" | "b" | "c" | "d" | "e" | "f" | "g"
| "h" | "i" | "j" | "k" | "l" | "m" | "n"
| "o" | "p" | "q" | "r" | "s" | "t" | "u"
| "v" | "w" | "x" | "y" | "z"
upper = "A" | "B" | "C" | "D" | "E" | "F" | "G"
| "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U"
| "V" | "W" | "X" | "Y" | "Z"
number = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
id-char = lower | upper | number | "_" | "'"
anything = ? any single character ?
nothing = ""
newline = ? newline character ? | ? carriage return character ?
(* Lexical syntax *)
(* Assume greedy matching for repetition *)
ID = lower, {id-char}
UPPERID = upper, {id-char}
INT = ["-"], number, {number}
FLOAT = {number}, ".", number, {number}
PREFIXTUPLEOP = "(,", {","}, ")"
BinOp = BinOpChar, {BinOpChar}
| CONSTROP
| ". "
NonBinOp = "." | "=" | "->" | "<-" | "--"
BINOP = BinOp - NonBinOp
BinOpChar = "~" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "-"
| "+" | "=" | "<" | ">" | "/" | "?" | "\" | "|" | "." | "_"
CONSTROP = ":", ConstrOpChar, {ConstrOpChar}
ConstrOpChar = BinOpChar | ":"
STRING = '"', {StringChar}, '"'
| '"""', {HereDocChar}, '"""'
HereDocChar = anything - '"'
| '"', ? not followed by '""' ?
StringChar = anything - newline - '"'
| "\", '"'
| "\", ? not followed by '"' ?
CHAR = "'" CharChar "'"
CharChar = anything - newline - "'"
LAYOUT = " " | newline | BlockComment
CommentChar = "{", ? not followed by "-" ?
BlockComment = "{-" {InsideComment} "-}"
InsideComment = anything - "{"
| CommentChar
| BlockComment
LAYOUT = "--", anything - newline - BinOpChar, { anything - newline } NewLineEOF
NewLineEOF = newline
| ? End of file ?
(*
Some influence from SDF can be seen in the follow restrictions and exceptions used.
Most system should be able to reproduce this, it's a basic lookahead
*)
(*
From here on out, consider every comma (,) as denotation of
optional layout (,{LAYOUT},) unless specified otherwise:
*)
bind = ? No layout allowed between the things left and right of this sort ?
(* Common *)
Literal (* Int *) = INT
(* Float *) | FLOAT
(* String *) | STRING
(* Char *) | CHAR
Ref (* VarRef *) = ID
(* OpRef *) | "(", BINOP, ")"
BinOp (* BinOp *) = BINOP
(* InfixFun *) | "`", bind, ID-CF, bind, "`"
(* InfixTag *) | "`", bind, UPPERID-CF, bind, "`"
UpperIds = UPPERID, bind, {".", bind, UPPERID}
(* Types *)
Type (* bracket *) = "(", Type, ")"
(* TVar *) | ID
(* TTag *) | UPPERID, {Type}
(* TFun *) | Type, "->", Type (* right associative *)
(* TUnit *) | "(", ")"
(* TTuple *) | "(", Type, ",", Type, {",", Type}, ")"
(* TRecord *) | "{", {",", TRecBind}, "}"
(* TRecExt *) | "{", ID, "|", {",", TRecBind}, "}"
TRecBind (* TRecBind *) = ID, ":", Type
(* Patterns *)
Pattern (* bracket *) = "(", Pattern, ")"
(* PVar *) | ID
(* PADT *) | UPPERID, {Pattern}
(* PWld *) | "_"
(* PUnit *) | "(", ")"
(* PTuple *) | "(", Pattern, ",", Pattern, {",", Pattern}, ")"
(* PList *) | "[", [ Pattern, {",", Pattern} ], "]"
(* PBinOp *) | Pattern, CONSTROP, Pattern (* left associative *)
(* PRecord *) | "{", {",", Pattern}, "}"
| Literal
(* Definitions *)
Def (* AnnotatedDef *) = TypeDef, ValueDef
| ValueDef
TypeDef (* NameAnno *) = ID, ":", Type
(* OpAnno *) | "(", BINOP, ")", ":", Type
ValueDef (* PrefixOpDef *) = "(", BINOP, ")", {Pattern}, "=", Expr
(* InfixOpDef *) | Pattern, BINOP, {Pattern}, "=", Expr
(* NameDef *) | ID, {Pattern}, "=", Expr
(* Modules *)
Module (* Module *) = "module", UpperIds, Exports, "where"
, {Import}, TopLevelStatement, {TopLevelStatement}
(* Main *) | {Import}, TopLevelStatement, {TopLevelStatement}
Exports (* ExportAll *) = ""
(* Exports *) | "(", [ Export, {",", Export} ], ")"
Export (* ADT *) = UPPERID, "(", [ ADTExport, {",", ADTExport} ], ")"
(* ADTNone *) | UPPERID
(* ADTAll *) | UPPERID, "(", "..", ")"
| Ref
ADTExport (* All *) = ".."
| ID
Import (* Import *) = "import", UpperIds, ModAlias, Exposing
ModAlias (* ModAlias *) = "as", UPPERID
(* NoModAlias *) | ""
Exposing (* NoExposing *) = ""
(* Exposing *) | "[", "exposing", "(", [ Export {", " Export} ], ")"
TopLevelStatement (* AliasDef *) = "type", "alias", UPPERID, {ID}, "=" Type
(* ADTDef *) | "type", UPPERID, {ID}, "=", ADTDef, {"|", ADTDef}
(* Port *) | "port", TypeDef, "port", ValueDef
| Def
ADTDef (* ADTCons *) = UPPERID, Type, {Type}
(* NOTE: You can do a two-phase parse where you first find these to gain a
precedence information on operators *)
TopLevelStatement (* Fixity *) = "infix", bind, Fixity, INT, BinOp
Fixity (* Left *) = "l"
(* Right *) | "r"
(* Expressions *)
RecBind (* RecBind *) = ID, "=", Expr
MwIfBranch (* MwIfBr *) = "|", Expr, "->", Expr
CaseBranch.CaseBr = Pattern, "->", Expr
RecAdd (* RecAdd *) = ID, "=", Expr
RecUpd (* RecUpd *) = ID, "<-", Expr
Expr (* Unit *) = "(", ")"
(* Tuple *) | "(", Expr, ",", Expr, {",", Expr}, ")"
(* List *) | "[", [Expr, {",", Expr}], "]"
(* Range *) | "[", Expr, "..", Expr, "]"
(* Rec *) | "{", [RecBind, {",", RecBind}], "}"
(* ADT *) | UPPERID
(* PrefTOp *) | PREFIXTUPLEOP
(* RecRem *) | "{", ID, "-", ID, "}"
(* RecAdd *) | "{", ID, "|", RecAdd, "}"
(* RecRen *) | "{", ID, "-", ID, "|", RecAdd, "}"
(* RecUpd *) | "{", ID, "|", RecUpd, {",", RecUpd}, "}"
(* QualRef *) | UpperIds, bind, ".", bind, ID
(* RecGet *) | Expr, bind, ".", bind, ID
(* Getter *) | " .", bind, ID
(* bracket *) | "(", Expr, ")"
(* If *) | "if", Expr, "then", Expr, "else", Expr
(* MwIf *) | "if", MwIfBranch, {MwIfBranch}
(* Case *) | "case", Expr, "of", CaseBranch, {CaseBranch}
(* Lam *) | "\", Pattern, {Pattern}, "->", Expr
(* App *) | Expr, Expr (* left associative *)
(* Let *) | "let", Def, {Def}, "in", Expr
(* EBinOp *) | Expr, BinOp, Expr (* left associative *)
| Literal
| Ref
(* General precedence:
Expr.App >
Expr.EBinOp > {
Expr.If
Expr.MwIf
Expr.Case
Expr.Lam
Expr.Let
}
*)