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