mech_syntax/
expressions.rs

1#[macro_use]
2use crate::*;
3use crate::structures::tuple;
4
5#[cfg(not(feature = "no-std"))] use core::fmt;
6#[cfg(feature = "no-std")] use alloc::fmt;
7#[cfg(feature = "no-std")] use alloc::string::String;
8#[cfg(feature = "no-std")] use alloc::vec::Vec;
9use nom::{
10  IResult,
11  branch::alt,
12  sequence::tuple as nom_tuple,
13  combinator::{opt, eof},
14  multi::{many1, many_till, many0, separated_list1,separated_list0},
15  Err,
16  Err::Failure
17};
18
19use std::collections::HashMap;
20use colored::*;
21
22use crate::*;
23
24// Expressions
25// ============================================================================
26
27/*
28Defines how expressions are parsed using a recursive structure hat reflects 
29operator precedence. Parsing begins at the top-level (`formula`) and proceeds 
30through increasingly tightly-binding operations, down to the basic elements 
31like literals and variables.
32
33- `formula`: entry point
34- `l1`: addition and subtraction (`+`, `-`)
35- `l2`: multiplication, division, matrix operations
36- `l3`: exponentiation (`^`)
37- `l4`: logical operators (e.g., `and`, `or`)
38- `l5`: comparisons (e.g., `==`, `<`, `>`)
39- `l6`: table operations (e.g., joins)
40- `l7`: set operations (e.g., union, intersection)
41- `factor`: atomic units (literals, function calls, variables, etc.)
42*/
43
44// expression := range-expression | formula ;
45pub fn expression(input: ParseString) -> ParseResult<Expression> {
46  let (input, expr) = match range_expression(input.clone()) {
47    Ok((input, rng)) => (input, Expression::Range(Box::new(rng))),
48    Err(_) => match formula(input.clone()) {
49      Ok((input, Factor::Expression(expr))) => (input, *expr),
50      Ok((input, fctr)) => (input, Expression::Formula(fctr)),
51      Err(err) => {return Err(err);},
52    } 
53  };
54  Ok((input, expr))
55}
56
57// formula := l1, (range-operator, l1)* ;
58pub fn formula(input: ParseString) -> ParseResult<Factor> {
59  let (input, factor) = l1(input)?;
60  Ok((input, factor))
61}
62
63// l1 := l2, (add-sub-operator, l2)* ;
64pub fn l1(input: ParseString) -> ParseResult<Factor> {
65  let (input, lhs) = l2(input)?;
66  let (input, rhs) = many0(nom_tuple((add_sub_operator,l2)))(input)?;
67  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
68  Ok((input, factor))
69}
70
71// l2 := l3, (mul-div-operator | matrix-operator, l3)* ;
72pub fn l2(input: ParseString) -> ParseResult<Factor> {
73  let (input, lhs) = l3(input)?;
74  let (input, rhs) = many0(nom_tuple((alt((mul_div_operator, matrix_operator)),l3)))(input)?;
75  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
76  Ok((input, factor))
77}
78
79// l3 := l4, (exponent-operator, l4)* ;
80pub fn l3(input: ParseString) -> ParseResult<Factor> {
81  let (input, lhs) = l4(input)?;
82  let (input, rhs) = many0(nom_tuple((exponent_operator,l4)))(input)?;
83  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
84  Ok((input, factor))
85}
86
87// l4 := l5, (logic-operator, l5)* ;
88pub fn l4(input: ParseString) -> ParseResult<Factor> {
89  let (input, lhs) = l5(input)?;
90  let (input, rhs) = many0(nom_tuple((logic_operator,l5)))(input)?;
91  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
92  Ok((input, factor))
93}
94
95// l5 := factor, (comparison-operator, factor)* ;
96pub fn l5(input: ParseString) -> ParseResult<Factor> {
97  let (input, lhs) = l6(input)?;
98  let (input, rhs) = many0(nom_tuple((comparison_operator,l6)))(input)?;
99  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
100  Ok((input, factor))
101}
102
103// l6 := factor, (table-operator, factor)* ;
104pub fn l6(input: ParseString) -> ParseResult<Factor> {
105  let (input, lhs) = l7(input)?;
106  let (input, rhs) = many0(nom_tuple((table_operator,l7)))(input)?;
107  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
108  Ok((input, factor))
109}
110
111// l7 := factor, (set-operator, factor)* ;
112pub fn l7(input: ParseString) -> ParseResult<Factor> {
113  let (input, lhs) = factor(input)?;
114  let (input, rhs) = many0(nom_tuple((set_operator,factor)))(input)?;
115  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
116  Ok((input, factor))
117}
118
119// factor := (structure| parenthetical-term | fsm-pipe | function-call | literal | slice | var), ?transpose ;
120pub fn factor(input: ParseString) -> ParseResult<Factor> {
121  let (input, fctr) = match parenthetical_term(input.clone()) {
122    Ok((input, term)) => (input, term),
123    Err(_) => match negate_factor(input.clone()) {
124      Ok((input, neg)) => (input, neg),
125      Err(_) => match not_factor(input.clone()) {
126        Ok((input, neg)) => (input, neg),
127        Err(_) => match structure(input.clone()) {
128          Ok((input, strct)) => (input, Factor::Expression(Box::new(Expression::Structure(strct)))),
129          Err(_) => match function_call(input.clone()) {
130            Ok((input, fxn)) => (input, Factor::Expression(Box::new(Expression::FunctionCall(fxn)))),
131            Err(_) => match literal(input.clone()) {
132              Ok((input, ltrl)) => (input, Factor::Expression(Box::new(Expression::Literal(ltrl)))),
133              Err(_) => match slice(input.clone()) {
134                Ok((input, slc)) => (input, Factor::Expression(Box::new(Expression::Slice(slc)))),
135                Err(_) => match var(input.clone()) {
136                  Ok((input, var)) => (input, Factor::Expression(Box::new(Expression::Var(var)))),
137                  Err(err) => { return Err(err); },
138                },
139              },
140            },
141          },
142        },
143      },
144    },
145  };
146  let (input, transpose) = opt(transpose)(input)?;
147  let fctr = match transpose {
148    Some(_) => Factor::Transpose(Box::new(fctr)),
149    None => fctr,
150  };
151  Ok((input, fctr))
152}
153
154// parenthetical-term := left-parenthesis, formula, right-parenthesis ;
155pub fn parenthetical_term(input: ParseString) -> ParseResult<Factor> {
156  let msg1 = "Expects expression";
157  let msg2 = "Expects right parenthesis ')'";
158  let (input, (_, r)) = range(left_parenthesis)(input)?;
159  let (input, frmla) = label!(formula, msg1)(input)?;
160  let (input, _) = label!(right_parenthesis, msg2, r)(input)?;
161  Ok((input, Factor::Parenthetical(Box::new(frmla))))
162}
163
164// var := identifier, ?kind-annotation ;
165pub fn var(input: ParseString) -> ParseResult<Var> {
166  let ((input, name)) = identifier(input)?;
167  let ((input, kind)) = opt(kind_annotation)(input)?;
168  Ok((input, Var{ name, kind }))
169}
170
171// statement-separator := ";" ;
172pub fn statement_separator(input: ParseString) -> ParseResult<()> {
173  let (input,_) = nom_tuple((whitespace0,semicolon,whitespace0))(input)?;
174  Ok((input, ()))
175}
176
177// Math Expressions
178// ----------------------------------------------------------------------------
179
180// add-sub-operator := add | subtract ;
181pub fn add_sub_operator(input: ParseString) -> ParseResult<FormulaOperator> {
182  let (input, op) = alt((add, subtract))(input)?;
183  Ok((input, FormulaOperator::AddSub(op)))
184}
185
186
187// mul-div-operator := multiply | divide | modulus ;
188pub fn mul_div_operator(input: ParseString) -> ParseResult<FormulaOperator> {
189  let (input, op) = alt((multiply, divide, modulus))(input)?;
190  Ok((input, FormulaOperator::MulDiv(op)))
191}
192
193// exponent-operator := exponent ;
194pub fn exponent_operator(input: ParseString) -> ParseResult<FormulaOperator> {
195  let (input, op) = exponent(input)?;
196  Ok((input, FormulaOperator::Exponent(op)))
197}
198
199// negate-factor := "-", factor ;
200pub fn negate_factor(input: ParseString) -> ParseResult<Factor> {
201  let (input, _) = dash(input)?;
202  let (input, expr) = factor(input)?;
203  Ok((input, Factor::Negate(Box::new(expr))))
204}
205
206// not-factor := not, factor ;
207pub fn not_factor(input: ParseString) -> ParseResult<Factor> {
208  let (input, _) = not(input)?;
209  let (input, expr) = factor(input)?;
210  Ok((input, Factor::Not(Box::new(expr))))
211}
212
213// add := "+" ;
214pub fn add(input: ParseString) -> ParseResult<AddSubOp> {
215  let (input, _) = ws1e(input)?;
216  let (input, _) = tag("+")(input)?;
217  let (input, _) = ws1e(input)?;
218  Ok((input, AddSubOp::Add))
219}
220
221// subtract := "-" ;
222pub fn subtract(input: ParseString) -> ParseResult<AddSubOp> {
223  let (input, _) = ws1e(input)?;
224  let (input, _) = tag("-")(input)?;
225  let (input, _) = ws1e(input)?;
226  Ok((input, AddSubOp::Sub))
227}
228
229// multiply := "*" | "×" ;
230pub fn multiply(input: ParseString) -> ParseResult<MulDivOp> {
231  let (input, _) = ws1e(input)?;
232  let (input, _) = alt((tag("*"), tag("×")))(input)?;
233  let (input, _) = ws1e(input)?;
234  Ok((input, MulDivOp::Mul))
235}
236
237// divide := "/" | "÷" ;
238pub fn divide(input: ParseString) -> ParseResult<MulDivOp> {
239  let (input, _) = ws1e(input)?;
240  let (input, _) = alt((tag("/"),tag("÷")))(input)?;
241  let (input, _) = ws1e(input)?;
242  Ok((input, MulDivOp::Div))
243}
244
245// modulus := "%" ;
246pub fn modulus(input: ParseString) -> ParseResult<MulDivOp> {
247  let (input, _) = ws1e(input)?;
248  let (input, _) = tag("%")(input)?;
249  let (input, _) = ws1e(input)?;
250  Ok((input, MulDivOp::Mod))
251}
252
253// exponent := "^" ;
254pub fn exponent(input: ParseString) -> ParseResult<ExponentOp> {
255  let (input, _) = ws1e(input)?;
256  let (input, _) = tag("^")(input)?;
257  let (input, _) = ws1e(input)?;
258  Ok((input, ExponentOp::Exp))
259}
260
261// Matrix Operations
262// ----------------------------------------------------------------------------
263
264// matrix-operator := matrix-multiply | multiply | divide | matrix-solve ;
265pub fn matrix_operator(input: ParseString) -> ParseResult<FormulaOperator> {
266  let (input, op) = alt((matrix_multiply, matrix_solve, dot_product, cross_product))(input)?;
267  Ok((input, FormulaOperator::Vec(op)))
268}
269
270// matrix-multiply := "**" ;
271pub fn matrix_multiply(input: ParseString) -> ParseResult<VecOp> {
272  let (input, _) = ws1e(input)?;
273  let (input, _) = tag("**")(input)?;
274  let (input, _) = ws1e(input)?;
275  Ok((input, VecOp::MatMul))
276}
277
278// matrix-solve := "\" ;
279pub fn matrix_solve(input: ParseString) -> ParseResult<VecOp> {
280  let (input, _) = ws1e(input)?;
281  let (input, _) = tag("\\")(input)?;
282  let (input, _) = ws1e(input)?;
283  Ok((input, VecOp::Solve))
284}
285
286// dot-product := "·" | "•" ;
287pub fn dot_product(input: ParseString) -> ParseResult<VecOp> {
288  let (input, _) = ws1e(input)?;
289  let (input, _) = alt((tag("·"),tag("•")))(input)?;
290  let (input, _) = ws1e(input)?;
291  Ok((input, VecOp::Dot))
292}
293
294// cross-product := "⨯" ;
295pub fn cross_product(input: ParseString) -> ParseResult<VecOp> {
296  let (input, _) = ws1e(input)?;
297  let (input, _) = tag("⨯")(input)?;
298  let (input, _) = ws1e(input)?;
299  Ok((input, VecOp::Cross))
300}
301
302// transpose := "'" ;
303pub fn transpose(input: ParseString) -> ParseResult<()> {
304  let (input, _) = tag("'")(input)?;
305  Ok((input, ()))
306}
307
308// Range Expressions
309// ----------------------------------------------------------------------------
310
311// range := formula, range-operator, formula, (range-operator, formula)? ;
312pub fn range_expression(input: ParseString) -> ParseResult<RangeExpression> {
313  let (input, start) = formula(input)?;
314  let (input, op) = range_operator(input)?;
315  let (input, x) = formula(input)?;
316  let (input, y) = opt(nom_tuple((range_operator,formula)))(input)?;
317  let range = match y {
318    Some((op2,terminal)) => RangeExpression{start, increment: Some((op,x)), operator: op2, terminal},
319    None => RangeExpression{start, increment: None, operator: op, terminal: x},
320  };
321  Ok((input, range))
322}
323
324// range-inclusive := "..=" ;
325pub fn range_inclusive(input: ParseString) -> ParseResult<RangeOp> {
326  let (input, _) = tag("..=")(input)?;
327  Ok((input, RangeOp::Inclusive))
328}
329
330// range-exclusive := ".." ;
331pub fn range_exclusive(input: ParseString) -> ParseResult<RangeOp> {
332  let (input, _) = tag("..")(input)?;
333  Ok((input, RangeOp::Exclusive))
334}
335
336// range-operator := range-inclusive | range-exclusive ;
337pub fn range_operator(input: ParseString) -> ParseResult<RangeOp> {
338  let (input, op) = alt((range_inclusive,range_exclusive))(input)?;
339  Ok((input, op))
340}
341
342// Comparison expressions
343// ----------------------------------------------------------------------------
344
345// comparison-operator := strict-equal | strict-not-equal | not-equal | equal-to | greater-than-equal | greater-than | less-than-equal | less-than ;
346pub fn comparison_operator(input: ParseString) -> ParseResult<FormulaOperator> {
347  let (input, op) = alt((strict_equal, strict_not_equal, not_equal, equal_to, greater_than_equal, greater_than, less_than_equal, less_than))(input)?;
348  Ok((input, FormulaOperator::Comparison(op)))
349}
350
351// not-equal := "!=" | "¬=" | "≠" ;
352pub fn not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
353  let (input, _) = ws1e(input)?;
354  let (input, _) = alt((tag("!="),tag("¬="),tag("≠")))(input)?;
355  let (input, _) = ws1e(input)?;
356  Ok((input, ComparisonOp::NotEqual))
357}
358
359// equal-to := "==" ;
360pub fn equal_to(input: ParseString) -> ParseResult<ComparisonOp> {
361  let (input, _) = ws1e(input)?;
362  let (input, _) = tag("==")(input)?;
363  let (input, _) = ws1e(input)?;
364  Ok((input, ComparisonOp::Equal))
365}
366
367// strict-not-equal := "=!=" | "=¬=" ;
368pub fn strict_not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
369  let (input, _) = ws1e(input)?;
370  let (input, _) = alt((tag("=!="),tag("=¬=")))(input)?;
371  let (input, _) = ws1e(input)?;
372  Ok((input, ComparisonOp::StrictNotEqual))
373}
374
375// strict-equal := "=:=" | "≡" ;
376pub fn strict_equal(input: ParseString) -> ParseResult<ComparisonOp> {
377  let (input, _) = ws1e(input)?;
378  let (input, _) = alt((tag("=:="),tag("≡")))(input)?;
379  let (input, _) = ws1e(input)?;
380  Ok((input, ComparisonOp::StrictEqual))
381}
382
383// greater-than := ">" ;
384pub fn greater_than(input: ParseString) -> ParseResult<ComparisonOp> {
385  let (input, _) = ws1e(input)?;
386  let (input, _) = tag(">")(input)?;
387  let (input, _) = ws1e(input)?;
388  Ok((input, ComparisonOp::GreaterThan))
389}
390
391// less_than := "<" ;
392pub fn less_than(input: ParseString) -> ParseResult<ComparisonOp> {
393  let (input, _) = ws1e(input)?;
394  let (input, _) = tag("<")(input)?;
395  let (input, _) = ws1e(input)?;
396  Ok((input, ComparisonOp::LessThan))
397}
398
399// greater-than-equal := ">=" | "≥" ;
400pub fn greater_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
401  let (input, _) = ws1e(input)?;
402  let (input, _) = alt((tag(">="),tag("≥")))(input)?;
403  let (input, _) = ws1e(input)?;
404  Ok((input, ComparisonOp::GreaterThanEqual))
405}
406
407// less-than-equal := "<=" | "≤" ;
408pub fn less_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
409  let (input, _) = ws1e(input)?;
410  let (input, _) = alt((tag("<="),tag("≤")))(input)?;
411  let (input, _) = ws1e(input)?;
412  Ok((input, ComparisonOp::LessThanEqual))
413}
414
415// Logic expressions
416// ----------------------------------------------------------------------------
417
418// logic-operator := and | or | xor ;
419pub fn logic_operator(input: ParseString) -> ParseResult<FormulaOperator> {
420  let (input, op) = alt((and, or, xor))(input)?;
421  Ok((input, FormulaOperator::Logic(op)))
422}
423
424// or := "|" ;
425pub fn or(input: ParseString) -> ParseResult<LogicOp> {
426  let (input, _) = ws1e(input)?;
427  let (input, _) = alt((tag("||"), tag("∨"), tag("⋁")))(input)?;
428  let (input, _) = ws1e(input)?;
429  Ok((input, LogicOp::Or))
430}
431
432// and := "&" ;
433pub fn and(input: ParseString) -> ParseResult<LogicOp> {
434  let (input, _) = ws1e(input)?;
435  let (input, _) = alt((tag("&&"), tag("∧"), tag("⋀")))(input)?;
436  let (input, _) = ws1e(input)?;
437  Ok((input, LogicOp::And))
438}
439
440// not := "!" | "¬" ;
441pub fn not(input: ParseString) -> ParseResult<LogicOp> {
442  let (input, _) = alt((tag("!"), tag("¬")))(input)?;
443  Ok((input, LogicOp::Not))
444}
445
446// xor := "xor" | "⊕" | "⊻" ;
447pub fn xor(input: ParseString) -> ParseResult<LogicOp> {
448  let (input, _) = ws1e(input)?;
449  let (input, _) = alt((tag("^^"), tag("⊕"), tag("⊻")))(input)?;
450  let (input, _) = ws1e(input)?;
451  Ok((input, LogicOp::Xor))
452}
453
454// Table Operations
455// ----------------------------------------------------------------------------
456
457// table-operator := join | left-join | right-join | full-join | left-semi-join | left-anti-join ;
458fn table_operator(input: ParseString) -> ParseResult<FormulaOperator> {
459  let (input, op) = alt((join,left_join,right_join,full_join,left_semi_join,left_anti_join))(input)?;
460  Ok((input, FormulaOperator::Table(op)))
461}
462
463// join := "⋈" ;
464fn join(input: ParseString) -> ParseResult<TableOp> {
465  let (input, _) = ws1e(input)?;
466  let (input, _) = tag("⋈")(input)?;
467  let (input, _) = ws1e(input)?;
468  Ok((input, TableOp::InnerJoin))
469}
470
471// left-join := "⟕" ;
472fn left_join(input: ParseString) -> ParseResult<TableOp> {
473  let (input, _) = ws1e(input)?;
474  let (input, _) = tag("⟕")(input)?;
475  let (input, _) = ws1e(input)?;
476  Ok((input, TableOp::LeftOuterJoin))
477}
478
479// right-join := "⟖" ;
480fn right_join(input: ParseString) -> ParseResult<TableOp> {
481  let (input, _) = ws1e(input)?;
482  let (input, _) = tag("⟖")(input)?;
483  let (input, _) = ws1e(input)?;
484  Ok((input, TableOp::RightOuterJoin))
485}
486
487// full-join := "⟗" ;
488fn full_join(input: ParseString) -> ParseResult<TableOp> {
489  let (input, _) = ws1e(input)?;
490  let (input, _) = tag("⟗")(input)?;
491  let (input, _) = ws1e(input)?;
492  Ok((input, TableOp::FullOuterJoin))
493}
494
495// left-semi-join := "⋉" ;
496fn left_semi_join(input: ParseString) -> ParseResult<TableOp> {
497  let (input, _) = ws1e(input)?;
498  let (input, _) = tag("⋉")(input)?;
499  let (input, _) = ws1e(input)?;
500  Ok((input, TableOp::LeftSemiJoin))
501}
502
503// left-anti-join := "▷" ;
504fn left_anti_join(input: ParseString) -> ParseResult<TableOp> {
505  let (input, _) = ws1e(input)?;
506  let (input, _) = tag("▷")(input)?;
507  let (input, _) = ws1e(input)?;
508  Ok((input, TableOp::LeftAntiJoin))
509}
510
511
512// Set Operations
513// ----------------------------------------------------------------------------
514
515// set-operator := union | intersection | difference | complement | subset | superset | proper-subset | proper-superset | element-of | not-element-of ;
516pub fn set_operator(input: ParseString) -> ParseResult<FormulaOperator> {
517  let (input, op) = alt((union_op,intersection,difference,complement,subset,superset,proper_subset,proper_superset,element_of,not_element_of))(input)?;
518  Ok((input, FormulaOperator::Set(op)))
519}
520
521// union := "∪" ;
522pub fn union_op(input: ParseString) -> ParseResult<SetOp> {
523  let (input, _) = ws1e(input)?;
524  let (input, _) = tag("∪")(input)?;
525  let (input, _) = ws1e(input)?;
526  Ok((input, SetOp::Union))
527}
528
529// intersection := "∩" ;
530pub fn intersection(input: ParseString) -> ParseResult<SetOp> {
531  let (input, _) = ws1e(input)?;
532  let (input, _) = tag("∩")(input)?;
533  let (input, _) = ws1e(input)?;
534  Ok((input, SetOp::Intersection))
535}
536
537// difference := "∖" ;
538pub fn difference(input: ParseString) -> ParseResult<SetOp> {
539  let (input, _) = ws1e(input)?;
540  let (input, _) = tag("∖")(input)?;
541  let (input, _) = ws1e(input)?;
542  Ok((input, SetOp::Difference))
543}
544
545// complement := "∁" ;
546pub fn complement(input: ParseString) -> ParseResult<SetOp> {
547  let (input, _) = ws1e(input)?;
548  let (input, _) = tag("∁")(input)?;
549  let (input, _) = ws1e(input)?;
550  Ok((input, SetOp::Complement))
551}
552
553// subset := "⊆" ;
554pub fn subset(input: ParseString) -> ParseResult<SetOp> { 
555  let (input, _) = ws1e(input)?;
556  let (input, _) = tag("⊆")(input)?;
557  let (input, _) = ws1e(input)?;
558  Ok((input, SetOp::Subset))
559}
560
561// superset := "⊇" ;
562pub fn superset(input: ParseString) -> ParseResult<SetOp> {
563  let (input, _) = ws1e(input)?;
564  let (input, _) = tag("⊇")(input)?;
565  let (input, _) = ws1e(input)?;
566  Ok((input, SetOp::Superset))
567}
568
569// proper-subset := "⊊" ;
570pub fn proper_subset(input: ParseString) -> ParseResult<SetOp> {
571  let (input, _) = ws1e(input)?;
572  let (input, _) = alt((tag("⊊"), tag("⊂")))(input)?;
573  let (input, _) = ws1e(input)?;
574  Ok((input, SetOp::ProperSubset))
575}
576
577// proper-superset := "⊋" ;
578pub fn proper_superset(input: ParseString) -> ParseResult<SetOp> {
579  let (input, _) = ws1e(input)?;
580  let (input, _) = alt((tag("⊋"), tag("⊃")))(input)?;
581  let (input, _) = ws1e(input)?;
582  Ok((input, SetOp::ProperSuperset))
583}
584
585// element-of := "∈" ;
586pub fn element_of(input: ParseString) -> ParseResult<SetOp> { 
587  let (input, _) = ws1e(input)?;
588  let (input, _) = tag("∈")(input)?;
589  let (input, _) = ws1e(input)?;
590  Ok((input, SetOp::ElementOf))
591}
592
593// not-element-of := "∉" ;
594pub fn not_element_of(input: ParseString) -> ParseResult<SetOp> {
595  let (input, _) = ws1e(input)?;
596  let (input, _) = tag("∉")(input)?;
597  let (input, _) = ws1e(input)?;
598  Ok((input, SetOp::NotElementOf))
599}
600
601// Subscript Operations
602// ----------------------------------------------------------------------------
603
604// subscript := (swizzle-subscript | dot-subscript-int | dot-subscript | bracket-subscript | brace-subscript)+ ; 
605pub fn subscript(input: ParseString) -> ParseResult<Vec<Subscript>> {
606  let (input, subscripts) = many1(alt((swizzle_subscript,dot_subscript,dot_subscript_int,bracket_subscript,brace_subscript)))(input)?;
607  Ok((input, subscripts))
608}
609
610// slice := identifier, subscript ;
611pub fn slice(input: ParseString) -> ParseResult<Slice> {
612  let (input, name) = identifier(input)?;
613  let (input, ixes) = subscript(input)?;
614  Ok((input, Slice{name, subscript: ixes}))
615}
616
617// slice-ref := identifier, subscript? ;
618pub fn slice_ref(input: ParseString) -> ParseResult<SliceRef> {
619  let (input, name) = identifier(input)?;
620  let (input, ixes) = opt(subscript)(input)?;
621  Ok((input, SliceRef{name, subscript: ixes}))
622}
623
624// swizzle-subscript := ".", identifier, ",", list1(",", identifier) ;
625pub fn swizzle_subscript(input: ParseString) -> ParseResult<Subscript> {
626  let (input, _) = period(input)?;
627  let (input, first) = identifier(input)?;
628  let (input, _) = comma(input)?;
629  let (input, mut name) = separated_list1(tag(","),identifier)(input)?;
630  let mut subscripts = vec![first];
631  subscripts.append(&mut name);
632  Ok((input, Subscript::Swizzle(subscripts)))
633}
634
635// dot-subscript := ".", identifier ;
636pub fn dot_subscript(input: ParseString) -> ParseResult<Subscript> {
637  let (input, _) = period(input)?;
638  let (input, name) = identifier(input)?;
639  Ok((input, Subscript::Dot(name)))
640}
641
642// dot-subscript-int := ".", integer-literal ;
643pub fn dot_subscript_int(input: ParseString) -> ParseResult<Subscript> {
644  let (input, _) = period(input)?;
645  let (input, name) = integer_literal(input)?;
646  Ok((input, Subscript::DotInt(name)))
647}
648
649// bracket-subscript := "[", list1(",", select-all | range-subscript | formula-subscript), "]" ;
650pub fn bracket_subscript(input: ParseString) -> ParseResult<Subscript> {
651  let (input, _) = left_bracket(input)?;
652  let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
653  let (input, _) = right_bracket(input)?;
654  Ok((input, Subscript::Bracket(subscripts)))
655}
656
657// brace-subscript := "{", list1(",", select-all | range-subscript | formula-subscript), "}" ;
658pub fn brace_subscript(input: ParseString) -> ParseResult<Subscript> {
659  let (input, _) = left_brace(input)?;
660  let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
661  let (input, _) = right_brace(input)?;
662  Ok((input, Subscript::Brace(subscripts)))
663}
664
665// select-all := ":" ;
666pub fn select_all(input: ParseString) -> ParseResult<Subscript> {
667  let (input, lhs) = colon(input)?;
668  Ok((input, Subscript::All))
669}
670
671// formula-subscript := formula ;
672pub fn formula_subscript(input: ParseString) -> ParseResult<Subscript> {
673  let (input, factor) = formula(input)?;
674  Ok((input, Subscript::Formula(factor)))
675}
676
677// range-subscript := range-expression ;
678pub fn range_subscript(input: ParseString) -> ParseResult<Subscript> {
679  let (input, rng) = range_expression(input)?;
680  Ok((input, Subscript::Range(rng)))
681}