-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.rs
178 lines (141 loc) · 8.37 KB
/
grammar.rs
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
use bnf_rules::bnf_rules_macro::bnf_rules;
use proc_macro_regex::regex;
// This is an LR(1) parser generator, used for maintain quality.
// If the specified grammar is ambiguous, compilation is aborted with conflict.
// Usage : https://github.com/bea4dev/bnf_rules
bnf_rules!{
#[generate_code = false]
source ::= program
program ::= [ statement ] { end_of_statement [ statement ] }
statement ::= assignment
| exchange_statement
| import_statement
| define_with_attr
| drop_statement
| expression
| impl_interface
| type_define
define_with_attr ::= statement_attribute ( function_define | user_type_define | variable_define )
function_define ::= "function" [ generics_define ] ( literal | memory_manage_attr ) function_arguments
[ function_type_tag ] [ line_feed ] [ where_clause ] ( block | ";" )
function_arguments ::= "(" [ line_feed ] [ ( this_mutability | function_argument) [ line_feed ] ] { "," [ line_feed ] [ function_argument ] } ")"
this_mutability ::= ( "var" | "let" ) "this"
function_argument ::= variable_binding type_tag
where_clause ::= "where" [ line_feed ] [ where_element ] { "," [ line_feed ] [ where_element ] }
where_element ::= type_info [ line_feed ] [ ":" [ line_feed ] type_info [ line_feed ] { "+" [ line_feed ] type_info [ line_feed ] } ]
memory_manage_attr ::= "new" | "drop" | "mutex"
statement_attribute ::= { "static" | "private" | "suspend" | "native" | "acyclic" | "open" | "override" }
user_type_define ::= ( "class" | "struct" | "interface" ) literal [ generics_define [ line_feed ] ]
[ super_type_info ] [ where_clause ] block
super_type_info ::= ":" [ line_feed ] type_info [ line_feed ] { "," [ type_info [ line_feed ] ] }
impl_interface ::= "implements" [ generics_define ] type_info [ line_feed ] "for" [ line_feed ] type_info
[ line_feed ] [ where_clause ] block
type_define ::= "type" literal [ generics_define ] "=" type_info
generics_define ::= "<" [ line_feed ] [ generics_element ] { "," [ line_feed ] [ generics_element ] } ">"
generics_element ::= literal [ line_feed ] [ ":" [ line_feed ] type_info [ line_feed ] { "+" [ line_feed ] type_info [ line_feed ] } ]
import_statement ::= "import" literal { "::" [ line_feed ] ( literal | import_elements ) }
import_elements ::= "{" [ line_feed ] ( [ literal [ line_feed ] ] { "," [ line_feed ] [ literal [ line_feed ] ] } | "*" ) "}"
drop_statement ::= "drop" [ "acyclic" ] expression
block ::= "{" program "}"
variable_define ::= ( "let" | "var" ) variable_binding [ type_tag ] [ "=" [ line_feed ] expression ]
variable_binding ::= literal
| "(" [ line_feed ] variable_binding [ line_feed ]
{ "," [ line_feed ] [ variable_binding [ line_feed ] ] } ")"
assignment ::= expression "=" [ line_feed ] expression
exchange_statement ::= expression "<=>" [ line_feed ] expression
expression ::= return_expression | closure | or_expr
or_expr ::= and_expr { "or" [ line_feed ] and_expr }
and_expr ::= equ_or_ine_expr { "and" [ line_feed ] equ_or_ine_expr }
equ_or_ine_expr ::= les_or_gre_expr [ ( "==" | "!=" ) [ line_feed ] les_or_gre_expr ]
les_or_gre_expr ::= add_or_sub_expr [ ( "<" | ">" | "<=" | ">=" ) [ line_feed ] add_or_sub_expr ]
add_or_sub_expr ::= mul_or_div_expr { ( "+" | "-" ) [ line_feed ] mul_or_div_expr }
mul_or_div_expr ::= factor { ( "*" | "/" ) [ line_feed ] factor }
factor ::= "-" [ line_feed ] primary | primary
primary ::= primary_left { primary_right }
primary_left ::= (
simple_primary [ ":" generics_info ] [ function_call ]
| new_array_init_expr
| new_array_expr
| new_expression
| if_expression
| loop_expression
)
[ mapping_operator ]
primary_right ::= ( "." | "::" ) [ line_feed ] ( literal [ ":" generics_info ] [ function_call ] | mapping_operator )
simple_primary ::= "(" [ line_feed ] expression [ line_feed ] { "," [ line_feed ] [ expression [ line_feed ] ] } ")"
| literal
| "null"
| "true"
| "false"
| "this"
| "This"
mapping_operator ::= "?"
| "?" "!"
| "!"
| "!" "!"
| ( "?" | "!" ) ":" block
if_expression ::= if_statement { "else" ( if_statement | block ) }
if_statement ::= "if" expression block
loop_expression ::= "loop" block
closure ::= ( closure_args | literal ) "=>" ( expression | block )
closure_args ::= "|"
[ [ line_feed ] ( function_argument | literal ) [ line_feed ] ]
{ "," [ line_feed ] [ ( function_argument | literal ) [ line_feed ] ] }
"|"
function_call ::= "(" [ [ line_feed ] expression [ line_feed ] ] { "," [ line_feed ] [ expression [ line_feed ] ] } ")"
new_expression ::= "new" [ "acyclic" ] ( literal | "This" ) { "::" [ line_feed ] literal } field_assign
field_assign ::= "{"
[ [ line_feed ] literal ":" [ line_feed ] expression [ line_feed ] ]
{ "," [ line_feed ] [ literal ":" [ line_feed ] expression [ line_feed ] ] }
"}"
new_array_expr ::= "new" [ "acyclic" ] "{"
[ [ line_feed ] expression [ line_feed ] ]
{ "," [ line_feed ] [ expression [ line_feed ] ] }
"}"
new_array_init_expr ::= "new" [ "acyclic" ] "[" [ line_feed ] [ "for" ] expression [ line_feed ] ";" [ line_feed ] expression [ line_feed ] "]"
return_expression ::= "return" [ expression ]
type_tag ::= ":" type_info
function_type_tag ::= "->" type_info
type_info ::= array_type_info | base_type_info | tuple_type_info
tuple_type_info ::= "(" [ line_feed ] type_info [ line_feed ] { "," [ line_feed ] [ type_info [ line_feed ] ] } ")"
array_type_info ::= "[" [ line_feed ] type_info [ line_feed ] "]"
base_type_info ::= ( literal | "This" ) { "::" [ line_feed ] literal } [ generics_info ] { type_attribute }
type_attribute ::= "?" | ( "!" [ generics_info ] )
generics_info ::= "<" [ line_feed ] [ type_info [ line_feed ] ] { "," [ line_feed ] [ type_info [ line_feed ] ] } ">"
literal ::= fn (literal_tokenizer) // r"\w+"
end_of_statement ::= line_feed | ";"
line_feed ::= fn (line_feed_tokenizer) // r"\n+"
}
regex!(pub number_literal_regex r"^\d+(\.\d+)?$");
#[allow(dead_code)]
fn literal_tokenizer(source: &Vec<char>, mut current_position: usize) -> usize {
let mut iteration_count = 0;
loop {
let current_char = match source.get(current_position) {
Some(ch) => ch.clone(),
_ => break
};
if !(current_char == '_' || current_char.is_alphanumeric()) {
break;
}
iteration_count += 1;
current_position += 1;
}
return iteration_count;
}
#[allow(dead_code)]
fn line_feed_tokenizer(source: &Vec<char>, mut current_position: usize) -> usize {
let mut iteration_count = 0;
loop {
let current_char = match source.get(current_position) {
Some(ch) => ch.clone(),
_ => break
};
if !(current_char == '\n' || current_char == '\r' ) {
break;
}
iteration_count += 1;
current_position += 1;
}
return iteration_count;
}