Mercurial > lbo > hg > arithmetal
view src/old_manual_parsers.rs @ 6:ad77c2ad4853 draft default tip
Fix build breakage; move generic expression parser into own function
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 23 Nov 2016 21:36:09 +0100 |
parents | b02268b0d4b1 |
children |
line wrap: on
line source
fn expr<'a>(st: State<'a>) -> ParseResult { if st.len() == 0 { err("Empty", st) } else { // Test if addition or subtraction let mut paren_lvl = 0; let mut ix = 0; let mut op_pos: i32 = -1; for c in st.iter() { if c == '(' { paren_lvl += 1; } else if c == ')' { paren_lvl -= 1; } else if paren_lvl == 0 && (c == '+' || c == '-') { // yep! op_pos = ix; break; } ix += 1; } if op_pos > -1 { let left = pexpr(st.restrict(0, op_pos as usize)); let right = pexpr(st.restrict(op_pos as usize + 1, st.len())); if left.ok() && right.ok() { match (left, right) { (ParseResult::Ok(a1), ParseResult::Ok(a2)) => { if st.at(op_pos as usize) == '-' { ParseResult::Ok(Ast::Subtraction(Box::new(a1), Box::new(a2))) } else { ParseResult::Ok(Ast::Addition(Box::new(a1), Box::new(a2))) } } _ => panic!("Expected OK results"), } } else if !left.ok() { err("Left part of expr is bad", st) } else { err("Right or both parts of expr is|are bad", st) } } else { term(st) } } } fn term<'a>(st: State<'a>) -> ParseResult { if st.len() == 0 { err("Empty", st) } else { // Test if addition or subtraction let mut paren_lvl = 0; let mut ix = 0; let mut op_pos: i32 = -1; // Look for operator at top level for c in st.iter() { if c == '(' { paren_lvl += 1; } else if c == ')' { paren_lvl -= 1; } else if paren_lvl == 0 && (c == '*' || c == '/') { // yep! op_pos = ix; break; } ix += 1; } if op_pos > -1 { let left = pexpr(st.restrict(0, op_pos as usize)); let right = pexpr(st.restrict(op_pos as usize + 1, st.len())); if left.ok() && right.ok() { match (left, right) { (ParseResult::Ok(a1), ParseResult::Ok(a2)) => { if st.at(op_pos as usize) == '*' { ParseResult::Ok(Ast::Multiplication(Box::new(a1), Box::new(a2))) } else { ParseResult::Ok(Ast::Division(Box::new(a1), Box::new(a2))) } } _ => panic!("Expected OK results"), } } else if !left.ok() { err("Left part of term is bad", st) } else { err("Right or both parts of term is|are bad", st) } } else { sym(st) } } }