Heather Grammar
Heather uses PEG grammar.
Grammar features
- Grammar on
program.
- Each aggregatable definition has its own grammar.
- Some portions of the grammar are common between them.
- Whitespaces are:
\t\n,; (space, tab, new line, comma, semi-colon). Those are completely ignored throughout the code.
- Comments are:
// text for single line comments; /- block ... -/ for multi-line comments.
1. Group functions
Grammar for main file (main.hat) as well as functions, meta-functions, casts, super-types and modifiers:
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 | program = imports* group_fns* main? EOF
imports = "use" "(" ( type_import | fn_import | metafn_import | modifier_import | supertype_import | const_import )+ ")"
type_import = "type" ":" ( single_import | many_imports )
fn_import = "fn" ":" ( single_import | many_imports )
metafn_import = "metafn" ":" ( single_import | many_imports )
modifier_import = "modifier" ":" ( single_import | many_imports )
supertype_import = "super-type" ":" ( single_import | many_imports )
const_import = "const" ":" ( single_import | many_imports )
single_import = composite_id_with_closure | full_id
many_imports = "[" single_import+ "]"
composite_id_with_closure = full_id "." "{" ( composite_id_with_closure | composite_id | full_id )+ "}"
composite_id = simple_id ( "." simple_id )+
full_id = ( composite_id | simple_id ) modifier?
simple_id = r"(\#\!\%\@)?[a-zA-Z][a-zA-Z0-9\-_]*"
modifier = "<" ( ref | pointer | variadic | (callargs | simple_id)+ ) ">"
ref = "&"
pointer = "*"
variadic = "..."
callargs = full_id "=" valonly
valonly = array | full_id | literal
array = "[" ( literal | composite_id_with_closure | full_id )* "]"
literal = (bool_t | int_t | float_t | str_t ) modifier?
bool_t = r"(\#\!\%\@)?(true|false)"
int_t = r"(\#\!\%\@)?(-)?([1-9][0-9]*|0)"
float_t = r"(\#\!\%\@)?(-)?(0|[1-9][0-9]*[.][0-9]+)"
str_t = r"(\#\!\%\@)?\"([^]*)\""
main = "main" body
body = "{" ( declareassign | declareassign_ds | declare | assign | expr )* "}"
declareassign = simple_id modifier? ":" type_id "=" expr
declareassign_ds = simple modifier? ":" type_id "=" "." "{" assign+ "}"
declare = simple_id modifier? ":" type_id
assign = full_id "=" expr
assign_ds = full_id "." "{" ( assign+ | expr+ ) "}"
expr = cast | assign_ds | call_optn | call_optbdn | call_bdn | call | array | full_id | literal
cast = ( call | literal | full_id ) "*" type_id
call_optn = full_id "(" option+ ")"
call_optbdn = full_id "(" args* ")" "{" option+ "}"
call_bdn = full_id "(" args* ")" body
call = full_id "(" args* ")" modifier?
args = ( callargs | cast | call | valonly )
group_fns = fn_def | metafn_def | modifier_def | supertype_def
fn_def = "fn" ( simple_id | pointer ) fn_args type_id? fn_body
fn_args = "(" argtype* ")"
argtype = full_id ":" type_id
type_id = ( "[" full_id "]" ) | full_id
fn_body = "{" ( fn_return | declareassign | declareassign_ds | declare | assign_s | assign | expr )* "}"
fn_return = "::" expr
metafn_def = "metafn" simple_id fn_args type_id? metafn_body
metafn_body = "{" ( fn_return | option | declareassign | declareassign_ds | declare | assign_ds | assign | expr )* "}"
modifier_def = "modifier" ( simple_id | pointer | ref | variadic ) modifier_args type_id metafn_body
modifier_args = "(" "self" argtype* ")"
supertype_def = "super-type" simple_id supertype_body
supertype_body = "{" full_id* "}"
|
2. Types
Grammar for types:
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 | program = imports* type_def* EOF
imports = "use" "(" ( type_import | fn_import | metafn_import | modifier_import | supertype_import | const_import )+ ")"
type_import = "type" ":" ( single_import | many_imports )
fn_import = "fn" ":" ( single_import | many_imports )
metafn_import = "metafn" ":" ( single_import | many_imports )
modifier_import = "modifier" ":" ( single_import | many_imports )
supertype_import = "super-type" ":" ( single_import | many_imports )
const_import = "const" ":" ( single_import | many_imports )
single_import = composite_id_with_closure | full_id
many_imports = "[" single_import+ "]"
composite_id_with_closure = full_id "." "{" ( composite_id_with_closure | composite_id | full_id )+ "}"
composite_id = simple_id ( "." simple_id )+
full_id = ( composite_id | simple_id ) modifier?
simple_id = r"(\#\!\%\@)?[a-zA-Z][a-zA-Z0-9\-_]*"
modifier = "<" ( ref | pointer | variadic | (callargs | simple_id)+ ) ">"
ref = "&"
pointer = "*"
variadic = "..."
callargs = full_id "=" valonly
valonly = array | full_id | literal
array = "[" ( literal | composite_id_with_closure | full_id )* "]"
literal = (bool_t | int_t | float_t | str_t ) modifier?
bool_t = r"(\#\!\%\@)?(true|false)"
int_t = r"(\#\!\%\@)?(-)?([1-9][0-9]*|0)"
float_t = r"(\#\!\%\@)?(-)?(0|[1-9][0-9]*[.][0-9]+)"
str_t = r"(\#\!\%\@)?\"([^]*)\""
type_def = "type" ( type_struct | type_enum )
type_struct = simple_id "{" struct_member+ "}"
struct_member = simple_id ":" type_id
type_enum = simple_id "{" enum_member+ "}"
enum_member = simple_id | type_struct
type_id = ( "[" full_id "]" ) | full_id
|
3. Constants
Grammar for constants:
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 | program = imports* consts* EOF
imports = "use" "(" ( type_import | fn_import | metafn_import | modifier_import | supertype_import | const_import )+ ")"
type_import = "type" ":" ( single_import | many_imports )
fn_import = "fn" ":" ( single_import | many_imports )
metafn_import = "metafn" ":" ( single_import | many_imports )
modifier_import = "modifier" ":" ( single_import | many_imports )
supertype_import = "super-type" ":" ( single_import | many_imports )
const_import = "const" ":" ( single_import | many_imports )
single_import = composite_id_with_closure | full_id
many_imports = "[" single_import+ "]"
composite_id_with_closure = full_id "." "{" ( composite_id_with_closure | composite_id | full_id )+ "}"
composite_id = simple_id ( "." simple_id )+
full_id = ( composite_id | simple_id ) modifier?
simple_id = r"(\#\!\%\@)?[a-zA-Z][a-zA-Z0-9\-_]*"
modifier = "<" ( ref | pointer | variadic | (callargs | simple_id)+ ) ">"
ref = "&"
pointer = "*"
variadic = "..."
callargs = full_id "=" valonly
valonly = array | full_id | literal
array = "[" ( literal | composite_id_with_closure | full_id )* "]"
literal = (bool_t | int_t | float_t | str_t ) modifier?
bool_t = r"(\#\!\%\@)?(true|false)"
int_t = r"(\#\!\%\@)?(-)?([1-9][0-9]*|0)"
float_t = r"(\#\!\%\@)?(-)?(0|[1-9][0-9]*[.][0-9]+)"
str_t = r"(\#\!\%\@)?\"([^]*)\""
consts = "const" simple_id ":" type_id "=" expr
expr = cast | assign_ds | call_optn | call_optbdn | call_bdn | call | array | full_id | literal
cast = ( call | literal | full_id ) "*" type_id
call_optn = full_id "(" option+ ")"
call_optbdn = full_id "(" args* ")" "{" option+ "}"
call_bdn = full_id "(" args* ")" body
call = full_id "(" args* ")" modifier?
args = ( callargs | cast | call | valonly )
assign = full_id "=" expr
assign_ds = full_id "." "{" ( assign+ | expr+ ) "}"
type_id = ( "[" full_id "]" ) | full_id
|