|
# EBNF Grammar for Xeph, a non-pure functional language based on Zephyr ASDL |
|
# Github.com/Chubek/Xeph |
|
# History: |
|
# Apr 19 - Revision Draft 1 |
|
# Apr 19 - Revision Draft 2 |
|
|
|
pattern ::= [ con-id ] factor "begin" expr-list "end" |
|
; |
|
|
|
factor ::= name-id |
|
| symbol-literal |
|
| long-name-id |
|
| numeric-literal |
|
| text-literal |
|
| list-literal |
|
| function-lambda |
|
| tacit-arg |
|
| '(' expr ')' |
|
; |
|
|
|
name-id ::= lowercase { letter | digit | '_' | "'" | '?' } |
|
; |
|
|
|
con-id ::= uppercase { letter | digit } |
|
; |
|
|
|
any-character ::= ? any character that the native system supports ? |
|
; |
|
|
|
operator-sym ::= ? up to 4 punctuation marks, except [?:;,'"] ? |
|
; |
|
|
|
uppercase ::= 'A' | 'B' | 'C' | ... | 'Z' |
|
; |
|
|
|
lowercase ::= 'a' | 'b' | 'c' | ... | 'z' |
|
; |
|
|
|
letter ::= uppercase | lowercase |
|
; |
|
|
|
digit ::= '0' | '1' | '2' | ... | '9' |
|
; |
|
|
|
long-name-id ::= name-id { '.' name-id | ".[" expr ']' } |
|
; |
|
|
|
numeric-literal ::= integer |
|
| float |
|
| scientific |
|
| complex |
|
; |
|
|
|
integer ::= digit { digit } |
|
; |
|
|
|
float ::= digit { digit } '.' { digit } |
|
; |
|
|
|
scientific ::= ( digit { digit } '.' { digit } | integer ) 'e' [ '+' | '-' ] digit { digit } |
|
; |
|
|
|
complex ::= ( integer | float ) 'i' |
|
; |
|
|
|
tacit-arg ::= '$' integer |
|
; |
|
|
|
text-literal ::= character-literal |
|
| string-literal |
|
| unescaped-string-literal |
|
| regex-literal |
|
; |
|
|
|
character-literal ::= "#\" ( any-character | name-id ) |
|
; |
|
|
|
string-literal ::= [ "u8" ] '"' { any-character } '"' |
|
; |
|
|
|
unescaped-literal ::= [ "u8" ] "'" { any-character } "'" |
|
; |
|
|
|
regex-literal ::= '/' { any-character - '/' } '/' |
|
; |
|
|
|
symbol-literal ::= ':' name-id |
|
; |
|
|
|
symbolic-id ::= name-id |
|
| symbol-literal |
|
; |
|
|
|
list-literal ::= basic-list | associative-list |
|
; |
|
|
|
basic-list ::= '[' [ expr { ';' expr } ] ']' |
|
; |
|
|
|
associative-list ::= '{' [ symbolic-id ':' expr { ';' symbolic-id ':' expr } ] '}' |
|
; |
|
|
|
function-lambda ::= "fn" [ name-id { ',' name-id } ] "begin" expr-list "end" |
|
; |
|
|
|
mk-exception ::= "exception" symbolic-id [ string-literal ] ';' |
|
; |
|
|
|
mk-infix ::= ( "infix" | "infixr" ) operator-sym |
|
; |
|
|
|
mk-postfix ::= "postfix" operator-sym |
|
; |
|
|
|
mk-prefix ::= "prefix" operator-sym |
|
; |
|
|
|
force-prefix ::= "<-" '(' operator-sym ')' |
|
; |
|
|
|
prefix-expr ::= ( force-prefix | operator-sym ) factor |
|
; |
|
|
|
postfix-expr ::= factor operator-sym |
|
; |
|
|
|
unary-expr ::= prefix-expr | postfix-expr |
|
; |
|
|
|
binary-expr ::= expr operator-sym expr |
|
; |
|
|
|
op-expr ::= unary-expr | binary-expr |
|
; |
|
|
|
concat-expr ::= op-expr { ( "<|" | "|>" ) op-expr } ';' |
|
; |
|
|
|
cond-expr ::= "if" expr "begin" expr-list "end" |
|
; |
|
|
|
|
|
loop-expr ::= "while" expr "begin" expr-list "end" |
|
; |
|
|
|
match-expr ::= "match" expr "with" "begin" alt-expr "end" |
|
|
|
|
|
alt-expr ::= pattern { '|' pattern } |
|
; |
|
|
|
call-expr ::= name-id { expr } |
|
; |
|
|
|
bind-expr ::= "let" name-id "in" "begin" expr-list "end" |
|
; |
|
|
|
function-expr ::= "fun" "begin" alt-expr "end" |
|
; |
|
|
|
local-expr ::= "local" expr "in" "begin" exp-list "end" |
|
; |
|
|
|
where-expr ::= "begin" expr-list "end" "where" expr |
|
; |
|
|
|
try-except-expr ::= "try" "begin" expr-list "end" "except" [ pattern ] "begin" expr-list "end" |
|
; |
|
|
|
failwith-expr ::= "failwith" name-id |
|
; |
|
|
|
runtime-eval-expr ::= "eval" concat-expr |
|
; |
|
|
|
compiletime-eval-expr ::= "eval!" concat-expr |
|
; |
|
|
|
eval-expr ::= runtime-eval-expr |
|
| compiletime-eval-expr |
|
; |
|
|
|
import-expr ::= "import" name-id [ "as" name-id ] { ',' name-id [ "as" name-id ] } [ "from" string-literal ] |
|
; |
|
|
|
export-expr ::= "export" name-id [ "as" name-id ] { ',' name-id [ "as" name-id ] } |
|
; |
|
|
|
module-expr ::= "module" name-id "begin" top-level "end" |
|
; |
|
|
|
expr ::= unary-expr |
|
| binary-expr |
|
| alt-expr |
|
| call-expr |
|
| bind-expr |
|
| function-expr |
|
| loop-expr |
|
| cond-expr |
|
| match-expr |
|
| local-expr |
|
| where-expr |
|
| concat-expr |
|
| try-except-expr |
|
| failwith-expr |
|
| eval-expr |
|
| import-expr |
|
| export-expr |
|
| module-expr |
|
; |
|
|
|
expr-list ::= expr { { "and" | "then" | "also" } expr } |
|
; |
|
|
|
builtin-type-int ::= "int" | "uint" |
|
| "int8" | "uint8" |
|
| "int16" | "uint16" |
|
| "int32" | "uint32" |
|
| "int64" | "uint64" |
|
| "size" | "usize" |
|
| "byte" | "ubyte" |
|
; |
|
|
|
builtin-type-float ::= "float" | "double" |
|
; |
|
|
|
builtin-type-txt ::= "char" | "uchar" | "string" |
|
; |
|
|
|
builtin-type-id ::= "symbol" | "exn" |
|
; |
|
|
|
builtin-type-coll ::= "map" | "list" | "array" |
|
; |
|
|
|
builtin-type ::= builtin-type-int |
|
| builtin-type-float |
|
| builtin-type-txt |
|
| builtin-type-coll |
|
; |
|
|
|
type-id ::= lower { lower | '_' } |
|
; |
|
|
|
type-name ::= type-id |
|
| builtin-type |
|
; |
|
|
|
type-name-ref ::= type-name |
|
| '[' type-name ']' |
|
; |
|
|
|
field-item ::= type-name-ref [ '*' | '?' ] name-id |
|
; |
|
|
|
field ::= '(' field-item { ',' field-item } ')' |
|
; |
|
|
|
variant ::= con-id [ field ] |
|
; |
|
|
|
sum-type ::= variant { '|' variant } |
|
; |
|
|
|
product-type ::= field |
|
; |
|
|
|
adt-body ::= sum-type |
|
| product-type |
|
; |
|
|
|
curry-sig ::= type-name-ref { "->" type-name-ref } |
|
; |
|
|
|
subscribes ::= ':' | ":>" sig-ref [ where-clause ] |
|
; |
|
|
|
where-clause ::= "where" clause-binding { ',' clause-binding } |
|
; |
|
|
|
clause-binding ::= name-id '=' name-id |
|
| type-name '=' type-name-ref |
|
; |
|
|
|
type-decl ::= "type" type-name ';' |
|
; |
|
|
|
value-decl ::= "val" name-id ':' curry-sig ';' |
|
; |
|
|
|
structure-decl ::= "struct" con-id [ subscribes ] ';' |
|
; |
|
|
|
declarations ::= type-decl |
|
| value-decl |
|
| structure-decl |
|
; |
|
|
|
type-defn ::= "type" type-name "::=" adt-body |
|
; |
|
|
|
value-defn ::= "val" name-id { factor } [ ':' curry-sig ] "::=" "begin" expr-list "end" |
|
; |
|
|
|
structure-defn-func ::= "struct" con-id "::=" cond-id '(' con-id ')' where-clause |
|
; |
|
|
|
structure-defn-mod ::= "struct" con-id [ subscribes ( con-id | sig-defn-inline ) ] "begin" { definitions } "end" |
|
; |
|
|
|
structure-defn-inline ::= "struct" { inline-definitions } "end" |
|
; |
|
|
|
signature-defn-inline ::= "sig" { inline-declarations } "end" |
|
; |
|
|
|
signature-defn-mod ::= "sig" con-id "begin" { declarations } "end" |
|
; |
|
|
|
definitions ::= struct-defn-mod |
|
| struct-defn-inline |
|
| sig-defn-mod |
|
| sig-defn-func |
|
| sig-defn-inline |
|
; |
|
|
|
inline-declarations ::= ? applying inline rules to 'declarations' ? |
|
; |
|
|
|
inline-definitions ::= ? applying inline rules to 'definitions' ? |
|
; |
|
|
|
top-level-non-meta ::= { definitions | declarations } |
|
; |
|
|
|
syntax-chunk-literal ::= ? a chunk of Xeph syntax, enclosed in "'''" or '`' ? |
|
; |
|
|
|
syntax-chunk ::= ? a syntax chunk, with optional string-only infix operators ? |
|
; |
|
|
|
meta-tacit ::= '#' integer |
|
; |
|
|
|
meta-quote ::= ( "quote'" | 'quote"' ) syntax-chunk |
|
; |
|
|
|
meta-expr ::= expr | meta-quote | meta-tacit |
|
; |
|
|
|
meta-expr-list ::= meta-expr { ';' meta-expr } |
|
; |
|
|
|
meta-id ::= letter { letter | digit | '_' } |
|
; |
|
|
|
runtime-macro ::= "macro" meta-id { meta-id } "::=" "begin" meta-expr-list "end" |
|
; |
|
|
|
compiletime-macro ::= "macro!" meta-id { meta-id } "::=" "begin" meta-expr-list "end" |
|
; |
|
|
|
runtime-alias ::= "alias" meta-id "begin" meta-expr-list "end" |
|
; |
|
|
|
compiletime-alias ::= "alias!" meta-id "begin" meta-expr-list "end" |
|
; |
|
|
|
macro ::= runtime-macro | compiletime-macro |
|
; |
|
|
|
alias ::= runtime-alias | compiletime-alias |
|
; |
|
|
|
top-level-meta ::= { macro | alias } |
|
; |
|
|
|
top-level ::= [ attrs ] { top-level-meta | top-level-non-meta | top-level-ffi } [ "fin." ] |
|
; |
|
|
|
|
|
|
|
|