~ntietz/hurl-lang

hurl-lang/hurl_grammar.pest -rw-r--r-- 2.1 KiB
5c1b4984Nicole Tietz-Sokolskaya name 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
program = { SOI ~ stmt_list ~ EOI }

stmt_list = { COMMENT* ~ stmt ~ ";" ~ (stmt ~ ";")* | "" }

stmt = { import | declaration | assignment | exception_handling | exception | return_stmt | expr }

import = { "include" ~ expr }

return_stmt = { "return" }

declaration = { "let" ~ identifier ~ "=" ~ expr }

exception_handling = { "try" ~ "{" ~ stmt_list ~ "}" ~ catch_list }
catch_list = { catch+ }
catch = { catch_as | catch_expr | catch_into }
catch_as = { "catch" ~ "as" ~ identifier ~ "{" ~ stmt_list ~ "}" }
catch_expr = { "catch" ~ "(" ~ expr ~ ")" ~ "{" ~ stmt_list ~ "}" }
catch_into = { "catch" ~ "into" ~ identifier }

exception = { toss_how ~ expr }
toss_how = { "toss" | "hurl" }

assignment = { identifier ~ "=" ~ expr }


expr = _{ expr0 }
expr0 = { expr1 ~ (cmp ~ expr0)? }
expr1 = { expr2 ~ (bin1 ~ expr1)? }
expr2 = { term ~ (bin2  ~ expr2)? }

cmp = _{ eq | neq | lt | leq | gt | geq | and | or }
    eq = { "==" }
    neq = { "~=" }
    lt = { "<" }
    leq = { "<=" }
    gt = { ">" }
    geq = { ">=" }
    and = { "and" }
    or = { "or" }
bin1 = _{ add | sub }
    add = { "+" }
    sub = { "-" }
bin2 = _{ mul | div | modu | pow }
    mul = { "*" }
    div = { "/" }
    modu = { "%" }
    pow = { "^" }

term = { index_access | literal | paren_expr | func_expr | function_call | identifier | not_expr | list_expr }

literal = { string | number | boolean }

paren_expr = { "(" ~ expr ~ ")" }

func_expr = { "func" ~ "(" ~ params ~ ")" ~ "{" ~ stmt_list ~ "}" }
params = { identifier ~ ("," ~ identifier)* | identifier | "" }

function_call = { identifier ~ "(" ~ argument_list? ~ ")" }
argument_list = { expr ~ ("," ~ expr)* }

identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* }

not_expr = { "~" ~ expr }

list_expr = { "[" ~ (expr ~ ("," ~ expr)*)? ~ "]" }

index_access = { identifier ~ "." ~ integer }

boolean = { "true" | "false" }

number = { float | integer }
integer = @{ ASCII_DIGIT+ }
float = @{ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }

string = @{ "\"" ~ (!("\\" ~ ANY | "\"") ~ ANY | "\\\"" | "\\\\")* ~ "\"" }

COMMENT = { "#" ~ (!"\n" ~ ANY)* ~ "\n" }
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }