mech_syntax/
structures.rs

1#[macro_use]
2use crate::*;
3use nom::{
4  multi::separated_list0,
5  sequence::tuple as nom_tuple,
6};
7use crate::nodes::Matrix;
8
9// #### Structures
10
11pub fn max_err<'a>(x: Option<ParseError<'a>>, y: ParseError<'a>) -> ParseError<'a> {
12  match (x,&y) {
13    (None, y) => y.clone(),
14    _ => y.clone(),
15  }
16}
17
18// structure := empty_set | empty_table | table | matrix | tuple | tuple_struct | record | map | set ;
19pub fn structure(input: ParseString) -> ParseResult<Structure> {
20  match empty_set(input.clone()) {
21    Ok((input, set)) => {return Ok((input, Structure::Set(set)));},
22    _ => (),
23  }
24  match empty_map(input.clone()) {
25    Ok((input, map)) => {return Ok((input, Structure::Map(map)));},
26    _ => (),
27  }
28  match table(input.clone()) {
29    Ok((input, tbl)) => {return Ok((input, Structure::Table(tbl)));},
30    //Err(Failure(err)) => { return Err(Failure(err)); }, 
31    _ => (),
32  }
33  match matrix(input.clone()) {
34    Ok((input, mtrx)) => {return Ok((input, Structure::Matrix(mtrx)));},
35    //Err(Failure(err)) => { return Err(Failure(err)); }, 
36    _ => (),
37  }
38  match tuple(input.clone()) {
39    Ok((input, tpl)) => {return Ok((input, Structure::Tuple(tpl)));},
40    _ => (),
41  }
42  match tuple_struct(input.clone()) {
43    Ok((input, tpl)) => {return Ok((input, Structure::TupleStruct(tpl)));},
44    _ => (),
45  }
46  match record(input.clone()) {
47    Ok((input, table)) => {return Ok((input, Structure::Record(table)));},
48    _ => (),
49  }
50  match map(input.clone()) {
51    Ok((input, map)) => {return Ok((input, Structure::Map(map)));},
52    _ => (),
53  }
54  match set(input.clone()) {
55    Ok((input, set)) => {return Ok((input, Structure::Set(set)));},
56    Err(err) => {return Err(err);}
57  }
58}
59
60// tuple := "(", list0(",", expression), ")" ;
61pub fn tuple(input: ParseString) -> ParseResult<Tuple> {
62  let (input, _) = left_parenthesis(input)?;
63  let (input, _) = whitespace0(input)?;
64  let (input, exprs) = separated_list0(list_separator, expression)(input)?;
65  let (input, _) = whitespace0(input)?;
66  let (input, _) = right_parenthesis(input)?;
67  Ok((input, Tuple{elements: exprs}))
68}
69
70// atom := "`", identifier ;
71pub fn atom(input: ParseString) -> ParseResult<Atom> {
72  let (input, _) = grave(input)?;
73  let (input, name) = identifier(input)?;
74  Ok((input, Atom{name}))
75}
76
77// tuple_struct = atom, "(", expression, ")" ;
78pub fn tuple_struct(input: ParseString) -> ParseResult<TupleStruct> {
79  let (input, _) = grave(input)?;
80  let (input, name) = identifier(input)?;
81  let (input, _) = left_parenthesis(input)?;
82  let (input, _) = whitespace0(input)?;
83  let (input, value) = expression(input)?;
84  let (input, _) = whitespace0(input)?;
85  let (input, _) = right_parenthesis(input)?;
86  Ok((input, TupleStruct{name, value: Box::new(value)}))
87}
88
89// binding := identifier, kind_annotation?, colon, expression, ","? ;
90
91pub fn binding(input: ParseString) -> ParseResult<Binding> {
92  let msg1 = "Unexpected space before colon ':'";
93  let msg2 = "Expects a value";
94  let msg3 = "Expects whitespace or comma followed by whitespace";
95  let msg4 = "Expects whitespace";
96  let (input, _) = whitespace0(input)?;
97  let (input, name) = identifier(input)?;
98  let (input, kind) = opt(kind_annotation)(input)?;
99  let (input, _) = whitespace0(input)?;
100  let (input, _) = colon(input)?;
101  let (input, _) = whitespace0(input)?;
102  let (input, value) = label!(expression, msg2)(input)?;
103  let (input, _) = whitespace0(input)?;
104  let (input, _) = opt(comma)(input)?;
105  let (input, _) = whitespace0(input)?;
106  Ok((input, Binding{name, kind, value}))
107}
108
109// table_column := (space | tab)*, expression, ((space | tab)*, ("," | table_separator)?, (space | tab)*) ;
110pub fn table_column(input: ParseString) -> ParseResult<TableColumn> {
111  let (input, _) = many0(space_tab)(input)?;
112  let (input, element) = match expression(input) {
113    Ok(result) => result,
114    Err(err) => {
115      return Err(err);
116    }
117  };
118  let (input, _) = nom_tuple((many0(space_tab),opt(alt((comma,table_separator))), many0(space_tab)))(input)?;
119  Ok((input, TableColumn{element}))
120}
121
122// matrix_column := (space | tab)*, expression, ((space | tab)*, ("," | table_separator)?, (space | tab)*) ;
123pub fn matrix_column(input: ParseString) -> ParseResult<MatrixColumn> {
124  let (input, _) = many0(space_tab)(input)?;
125  let (input, element) = match expression(input) {
126    Ok(result) => result,
127    Err(err) => {
128      return Err(err);
129    }
130  };
131  let (input, _) = nom_tuple((many0(space_tab),opt(alt((comma,table_separator))), many0(space_tab)))(input)?;
132  Ok((input, MatrixColumn{element}))
133}
134
135
136// table_row := table_separator?, (space | tab)*, table_column+, semicolon?, new_line?, (box_drawing_char+, new_line)? ;
137pub fn table_row(input: ParseString) -> ParseResult<TableRow> {
138  let (input, _) = opt(table_separator)(input)?;
139  let (input, _) = many0(space_tab)(input)?;
140  let (input, columns) = match many1(table_column)(input) {
141    Ok(result) => result,
142    Err(error) => {
143      return Err(error);
144    }
145  };
146  let (input, _) = nom_tuple((opt(semicolon), opt(new_line)))(input)?;
147  let (input, _) = opt(nom_tuple((many1(box_drawing_char),new_line)))(input)?;
148  Ok((input, TableRow{columns}))
149}
150
151// matrix_row := table_separator?, (space | tab)*, matrix_column+, semicolon?, new_line?, (box_drawing_char+, new_line)? ;
152pub fn matrix_row(input: ParseString) -> ParseResult<MatrixRow> {
153  let (input, _) = opt(table_separator)(input)?;
154  let (input, _) = many0(space_tab)(input)?;
155  let (input, columns) = match many1(matrix_column)(input) {
156    Ok(result) => result,
157    Err(error) => {
158      return Err(error);
159    }
160  };
161  let (input, _) = nom_tuple((opt(semicolon), opt(new_line)))(input)?;
162  let (input, _) = opt(nom_tuple((many1(box_drawing_char),new_line)))(input)?;
163  Ok((input, MatrixRow{columns}))
164}
165
166// table_header := list1(space_tab+, field), (space | tab)*, (bar| box_vert), whitespace* ;
167pub fn table_header(input: ParseString) -> ParseResult<Vec<Field>> {
168  let (input, fields) = separated_list1(many1(space_tab),field)(input)?;
169  let (input, _) = many0(space_tab)(input)?;
170  let (input, _) = alt((bar,box_vert,box_vert_bold))(input)?;
171  let (input, _) = whitespace0(input)?;
172  Ok((input, fields))
173}
174
175// field := identifier, kind_annotation? ;
176pub fn field(input: ParseString) -> ParseResult<Field> {
177  let (input, name) = identifier(input)?;
178  let (input, kind) = opt(kind_annotation)(input)?;
179  Ok((input, Field{name, kind}))
180}
181
182// box_drawing_char := box_tl | box_br | box_bl | box_tr | box_tr_round | box_bl_round | box_vert | box_cross | box_horz | box_t_left | box_t_right | box_t_top | box_t_bottom ;
183pub fn box_drawing_char(input: ParseString) -> ParseResult<Token> {
184  alt((box_tl, box_bl, box_tr, box_tl_bold, box_bl_bold, box_tr_bold, box_tr_round, box_bl_round, box_vert, box_cross, box_horz, box_t_left, box_t_right, box_t_top, box_t_bottom))(input)
185}
186
187// box_drawing_emoji := box_tl | box_br | box_bl | box_tr | box_tl_round | box_br_round | box_tr_round | box_bl_round | box_vert | box_cross | box_horz | box_t_left | box_t_right | box_t_top | box_t_bottom ;
188pub fn box_drawing_emoji(input: ParseString) -> ParseResult<Token> {
189  alt((box_tl, box_bl, box_tr, box_tl_bold, box_bl_bold, box_tr_bold, box_tl_round, box_br_round, box_tr_round, box_bl_round, box_vert, box_cross, box_horz, box_t_left, box_t_right, box_t_top, box_t_bottom))(input)
190}
191
192// matrix_start := box_tl_round | box_tl | left_bracket ;
193pub fn matrix_start(input: ParseString) -> ParseResult<Token> {
194  alt((box_tl_round, box_tl, box_tl_bold, left_bracket))(input)
195}
196
197// matrix_end := box_br_round | box_br | right_bracket ;
198pub fn matrix_end(input: ParseString) -> ParseResult<Token> {
199  let result = alt((box_br_round, box_br, box_br_bold, right_bracket))(input);
200  result
201}
202
203// table_start := box_tl_round | box_tl | left_brace ;
204pub fn table_start(input: ParseString) -> ParseResult<Token> {
205  alt((box_tl_round, box_tl, box_tl_bold, left_brace))(input)
206}
207
208// table_end := box_br_round | box_br | right_brace ;
209pub fn table_end(input: ParseString) -> ParseResult<Token> {
210  let result = alt((box_br_round, box_br, box_br_bold, right_brace))(input);
211  result
212}
213
214// table_separator := box_vert ;
215pub fn table_separator(input: ParseString) -> ParseResult<Token> {
216  let (input, token) = alt((box_vert,box_vert_bold))(input)?;
217  Ok((input, token))
218}
219
220// matrix := matrix_start, (box_drawing_char | whitespace)*, matrix_row*, box_drawing_char*, matrix_end ;
221pub fn matrix(input: ParseString) -> ParseResult<Matrix> {
222  let msg = "Expects right bracket ']' to finish the matrix";
223  let (input, (_, r)) = range(matrix_start)(input)?;
224  let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
225  let (input, rows) = many0(matrix_row)(input)?;
226  let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
227  let (input, _) = whitespace0(input)?;
228  let (input, _) = match label!(matrix_end, msg, r)(input) {
229    Ok(k) => k,
230    Err(err) => {
231      return Err(err);
232    }
233  };
234  Ok((input, Matrix{rows}))
235}
236
237// table := table_start, (box_drawing_char | whitespace)*, table_header, (box_drawing_char | whitespace)*, table_row+, box_drawing_char*, whitespace*, table_end ;
238pub fn table(input: ParseString) -> ParseResult<Table> {
239  let msg = "Expects right bracket '}' to finish the table";
240  let (input, (_, r)) = range(table_start)(input)?;
241  let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
242  let (input, header) = table_header(input)?;
243  let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
244  let (input, rows) = many1(table_row)(input)?;
245  let (input, _) = many0(box_drawing_char)(input)?;
246  let (input, _) = whitespace0(input)?;
247  let (input, _) = match label!(table_end, msg, r)(input) {
248    Ok(k) => k,
249    Err(err) => {
250      return Err(err);
251    }
252  };
253  Ok((input, Table{header,rows}))
254}
255
256// empty_table := table_start, whitespace*, table_end ;
257pub fn empty_map(input: ParseString) -> ParseResult<Map> {
258  let (input, _) = table_start(input)?;
259  let (input, _) = whitespace0(input)?;
260  let (input, _) = table_end(input)?;
261  Ok((input, Map{elements: vec![]}))
262}
263
264// empty_set := table_start, whitespace*, empty, whitespace*, table_end ;
265pub fn empty_set(input: ParseString) -> ParseResult<Set> {
266  let (input, _) = table_start(input)?;
267  let (input, _) = whitespace0(input)?;
268  let (input, _) = empty(input)?;
269  let (input, _) = whitespace0(input)?;
270  let (input, _) = table_end(input)?;
271  Ok((input,  Set{elements: vec![]}))
272}
273
274// record := table_start, whitespace*, binding+, whitespace*, table_end ;
275pub fn record(input: ParseString) -> ParseResult<Record> {
276  let msg = "Expects right bracket ']' to terminate inline table";
277  let (input, (_, r)) = range(table_start)(input)?;
278  let (input, _) = whitespace0(input)?;
279  let (input, bindings) = many1(binding)(input)?;
280  let (input, _) = whitespace0(input)?;
281  let (input, _) = label!(table_end, msg, r)(input)?;
282  Ok((input, Record{bindings}))
283}
284
285// map := "{", whitespace*, mapping*, whitespace*, "}" ;
286pub fn map(input: ParseString) -> ParseResult<Map> {
287  let msg = "Expects right bracket '}' to terminate inline table";
288  let (input, (_, r)) = range(left_brace)(input)?;
289  let (input, _) = whitespace0(input)?;
290  let (input, elements) = many0(mapping)(input)?;
291  let (input, _) = whitespace0(input)?;
292  let (input, _) = label!(right_brace, msg, r)(input)?;
293  Ok((input, Map{elements}))
294}
295
296// mapping :=  whitespace*, expression, whitespace*, ":", whitespace*, expression, comma?, whitespace* ;
297pub fn mapping(input: ParseString) -> ParseResult<Mapping> {
298  let msg1 = "Unexpected space before colon ':'";
299  let msg2 = "Expects a value";
300  let msg3 = "Expects whitespace or comma followed by whitespace";
301  let msg4 = "Expects whitespace";
302  let (input, _) = whitespace0(input)?;
303  let (input, key) = expression(input)?;
304  let (input, _) = whitespace0(input)?;
305  let (input, _) = colon(input)?;
306  let (input, _) = whitespace0(input)?;
307  let (input, value) = label!(expression, msg2)(input)?;
308  let (input, _) = whitespace0(input)?;
309  let (input, _) = opt(comma)(input)?;
310  let (input, _) = whitespace0(input)?;
311  Ok((input, Mapping{key, value}))
312}
313
314// set := "{", whitespace*, list0(("," | whitespace+), expression), whitespace*, "}" ;
315pub fn set(input: ParseString) -> ParseResult<Set> {
316  let msg = "Expects right bracket '}' to terminate inline table";
317  let (input, (_, r)) = range(left_brace)(input)?;
318  let (input, _) = whitespace0(input)?;
319  let (input, elements) = separated_list0(alt((list_separator,whitespace1)), expression)(input)?;
320  let (input, _) = whitespace0(input)?;
321  let (input, _) = label!(right_brace, msg, r)(input)?;
322  Ok((input, Set{elements}))
323}