17
17
18
18
// mods
19
19
mod legal_check_util;
20
+ mod parser_struct;
20
21
21
22
use regex:: Regex ;
22
23
use std:: string:: String ;
23
24
use std:: vec:: Vec ;
24
25
use std:: i32;
25
26
// inside uses
26
- use structs:: { ChemicalEquation , ElementStruct } ;
27
+ use structs:: ChemicalEquation ;
28
+ use self :: parser_struct:: { TableDesc , FormulaDesc , TokenDesc } ;
27
29
use self :: legal_check_util:: { legal_check, legal_check_brackets} ;
28
30
29
- struct FormulaDesc {
30
- formula_self : String ,
31
- times : i32 ,
32
- all : String ,
33
- }
34
-
35
- struct TokenDesc {
36
- token_name : String ,
37
- times : i32 ,
38
- }
39
-
40
- pub fn xch_parser ( equation : String ) -> Result < ( ChemicalEquation , Vec < ElementStruct > , Vec < Vec < i32 > > ) , String > {
31
+ pub fn xch_parser ( equation : String ) -> Result < ( ChemicalEquation , usize , Vec < Vec < i32 > > ) , String > {
41
32
legal_check ( & equation) ?;
42
33
let mut chemical_equation_struct = ChemicalEquation {
43
34
left_num : 0 ,
44
35
right_num : 0 ,
45
36
sum : 0 ,
46
37
} ;
47
- let mut elements_table: Vec < ElementStruct > = Vec :: new ( ) ; // store the index of elements
48
- let mut list: Vec < Vec < i32 > > = Vec :: new ( ) ;
49
- // Unicode slice safe
50
-
51
- // block to call parsers
52
- {
38
+ { // block to get chemical_equation_struct.sum
53
39
let v: Vec < & str > = equation. split ( '=' ) . collect ( ) ;
54
40
let equation_left: String = String :: from ( v[ 0 ] ) ;
55
41
let equation_right: String = String :: from ( v[ 1 ] ) ;
56
-
57
42
chemical_equation_struct. sum =
58
43
parser_get_sum ( & equation_left) ? + parser_get_sum ( & equation_right) ?;
59
- list. push ( generate_n_vec ( chemical_equation_struct. sum + 1 ) ) ; // first access will be like list[1][1]
44
+ }
45
+ let mut table = TableDesc :: new ( chemical_equation_struct. sum ) ;
46
+ table. update_list_vec ( ) ; // first access will be like list[1][1]
47
+
48
+ { // block to call parsers
49
+ let v: Vec < & str > = equation. split ( '=' ) . collect ( ) ;
50
+ let equation_left: String = String :: from ( v[ 0 ] ) ;
51
+ let equation_right: String = String :: from ( v[ 1 ] ) ;
52
+
60
53
chemical_equation_struct. left_num = part_parser (
61
54
& equation_left,
62
- & mut elements_table,
63
- & mut list,
55
+ & mut table,
64
56
0 ,
65
- chemical_equation_struct. sum ,
66
57
) ?;
67
58
chemical_equation_struct. right_num = part_parser (
68
59
& equation_right,
69
- & mut elements_table,
70
- & mut list,
60
+ & mut table,
71
61
chemical_equation_struct. left_num ,
72
- chemical_equation_struct. sum ,
73
62
) ?;
74
63
}
75
64
76
65
// return
77
- Ok ( ( chemical_equation_struct, elements_table , list ) )
66
+ Ok ( ( chemical_equation_struct, table . get_elements_table_len ( ) , table . get_list ( ) ) )
78
67
}
79
68
80
69
fn parser_get_sum ( equation : & String ) -> Result < i32 , String > {
@@ -90,34 +79,22 @@ fn parser_get_sum(equation: &String) -> Result<i32,String> {
90
79
91
80
fn part_parser (
92
81
equation : & String ,
93
- elements_table : & mut Vec < ElementStruct > ,
94
- list : & mut Vec < Vec < i32 > > ,
82
+ table : & mut TableDesc ,
95
83
begin : i32 ,
96
- equation_sum : i32 ,
97
84
) -> Result < i32 , String > {
98
85
let mut sum = begin;
99
86
for formula in equation. split ( '+' ) {
100
87
sum = sum + 1 ;
101
88
legal_check_brackets ( & formula. to_string ( ) ) ?;
102
89
parser_formula (
103
90
& formula. to_string ( ) ,
104
- elements_table ,
91
+ table ,
105
92
sum as usize ,
106
- list,
107
- equation_sum,
108
93
) ?;
109
94
}
110
95
Ok ( sum - begin)
111
96
}
112
97
113
- fn generate_n_vec ( n : i32 ) -> Vec < i32 > {
114
- let mut v: Vec < i32 > = Vec :: new ( ) ;
115
- for _ in 0 ..n {
116
- v. push ( 0 ) ;
117
- }
118
- v
119
- }
120
-
121
98
fn formula_spliter ( target : & str ) -> Result < Vec < FormulaDesc > , String > {
122
99
let mut v: Vec < FormulaDesc > = Vec :: new ( ) ;
123
100
lazy_static ! {
@@ -194,60 +171,20 @@ fn replace_phrase(target: &str, src: &str, des: &str) -> String {
194
171
str:: replace ( target, src, des)
195
172
}
196
173
197
- fn store_in_table (
198
- formula : & String ,
199
- elements_table : & mut Vec < ElementStruct > ,
200
- location : usize ,
201
- list : & mut Vec < Vec < i32 > > ,
202
- formula_sum : i32 ,
203
- ) -> Result < bool , String > {
204
- for t in get_token ( formula) ? {
205
- if find_element_in_table ( & t. token_name , elements_table) . is_ok ( ) == false {
206
- let len = elements_table. len ( ) ;
207
- elements_table. push ( ElementStruct {
208
- name : t. token_name . clone ( ) ,
209
- num : len + 1 , // WARN: the elements_table[0].num will be 1
210
- } ) ;
211
- list. push ( generate_n_vec ( formula_sum + 1 ) ) ;
212
- }
213
-
214
- {
215
- // store data in table
216
- let tmp = find_element_in_table ( & t. token_name , elements_table) . unwrap ( ) ;
217
- list[ tmp] [ location] = match list[ tmp] [ location] . checked_add ( t. times ) {
218
- Some ( s) => s,
219
- None => return Err ( "[ERROR] i32 overflow" . to_string ( ) ) ,
220
- }
221
- }
222
- }
223
- Ok ( true )
224
- }
225
-
226
174
fn parser_formula (
227
175
// parse the chemical formula
228
176
formula : & String ,
229
- elements_table : & mut Vec < ElementStruct > ,
177
+ table : & mut TableDesc ,
230
178
location : usize ,
231
- list : & mut Vec < Vec < i32 > > ,
232
- formula_sum : i32 ,
233
179
) -> Result < bool , String > {
234
180
let formula_backup = formula;
235
181
let mut formula = format ! ( "({})" , formula_backup) ;
236
182
237
183
while formula_spliter ( & formula) . is_ok ( ) == true {
238
- for p in formula_spliter ( & formula) . unwrap ( ) {
184
+ for p in formula_spliter ( & formula) ? {
239
185
formula = replace_phrase ( & formula, & p. all , & ( mul_phrase ( & p) ?) ) ;
240
186
}
241
187
}
242
- store_in_table ( & formula, elements_table , location, list , formula_sum ) ?;
188
+ table . store_in_table ( & formula, location) ?;
243
189
Ok ( true )
244
190
}
245
-
246
- fn find_element_in_table ( target : & String , e_t : & mut Vec < ElementStruct > ) -> Result < usize , String > {
247
- for i in e_t {
248
- if i. name == * target {
249
- return Ok ( i. num ) ;
250
- }
251
- }
252
- Err ( "[ERROR] Not found!" . to_string ( ) )
253
- }
0 commit comments