Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.47 KB | None | 0 0
  1. #![feature(slice_patterns)]
  2.  
  3. #[derive(Debug, PartialEq)]
  4. pub enum AlgItem {
  5. R,
  6. U,
  7. Pair(Vec<AlgItem>, Vec<AlgItem>),
  8. }
  9.  
  10. fn parse_one(h: char, t: &[char]) -> Result<(AlgItem, &[char]), &'static str> {
  11. match h {
  12. 'R' => Ok((AlgItem::R, t)),
  13. 'U' => Ok((AlgItem::U, t)),
  14. '[' => parse_many(t, Some(';'))
  15. .and_then(|m1| parse_many(m1.1, Some(']')).map(|m2| (AlgItem::Pair(m1.0, m2.0), m2.1))),
  16. _ => Err("Expected R, U, or ["),
  17. }
  18. }
  19.  
  20. fn parse_many(s: &[char], exp: Option<char>) -> Result<(Vec<AlgItem>, &[char]), &'static str> {
  21. fn step(
  22. mut acc: Vec<AlgItem>,
  23. exp: Option<char>,
  24. input: &[char],
  25. ) -> Result<(Vec<AlgItem>, &[char]), &'static str> {
  26. match input {
  27. [h, t @ ..] if Some(h) == exp.as_ref() => Ok((acc, t)),
  28. [h, t @ ..] => parse_one(*h, t).and_then(|a| {
  29. acc.push(a.0);
  30. step(acc, exp, a.1)
  31. }),
  32. [] => Ok((acc, &[])),
  33. }
  34. }
  35. step(Vec::new(), exp, s)
  36. }
  37.  
  38. pub fn parse(input: &str) -> Result<Vec<AlgItem>, &'static str> {
  39. let input: Vec<char> = input.chars().collect();
  40. parse_many(&input, None).map(|m| m.0)
  41. }
  42.  
  43. #[test]
  44. fn basic() {
  45. assert_eq!(Ok(vec![AlgItem::R]), parse("R"));
  46. assert_eq!(Ok(vec![AlgItem::U]), parse("U"));
  47. assert_eq!(
  48. Ok(vec![AlgItem::Pair(vec![AlgItem::R], vec![AlgItem::U])]),
  49. parse("[R;U]")
  50. );
  51. assert_eq!(Err("Expected R, U, or ["), parse("O"));
  52. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement