changeset 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
files src/lib.rs src/old_manual_parsers.rs
diffstat 2 files changed, 55 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib.rs	Wed Nov 23 21:13:05 2016 +0100
+++ b/src/lib.rs	Wed Nov 23 21:36:09 2016 +0100
@@ -172,23 +172,57 @@
 
             // Paren is closed somewhere
             if good {
-                expr(st)
+                // old expression parser:
+                // expr(st)
+                new_expr(st)
             } else {
                 err("Missing closing paren", st)
             }
         }
     } else {
+        // old expression parser:
         // expr(st)
-        parse_twohand_expr(expr_op_map(),
-                           |st2| {
-                               parse_twohand_expr(term_op_map(),
-                                                  |st3| parse_twohand_expr(pow_op_map(), sym, st3),
-                                                  st2)
-                           },
-                           st)
+        new_expr(st)
     }
 }
 
+/// Parses an expression based on the generic twohand expression parser.
+fn new_expr<'a>(st: State<'a>) -> ParseResult {
+    parse_twohand_expr(expr_op_map(),
+                       |st2| {
+                           parse_twohand_expr(term_op_map(),
+                                              |st3| parse_twohand_expr(pow_op_map(), sym, st3),
+                                              st2)
+                       },
+                       st)
+}
+
+fn sym<'a>(st: State<'a>) -> ParseResult {
+    if st.len() == 0 {
+        err("Empty", st)
+    } else if st.at(0) == '-' {
+        match num(st.restrict(1, st.len())) {
+            ParseResult::Ok(Ast::Num(n)) => ParseResult::Ok(Ast::Num(-n)),
+            x => x,
+        }
+    } else {
+        num(st)
+    }
+}
+
+fn num<'a>(st: State<'a>) -> ParseResult {
+    if st.len() == 0 {
+        err("Empty", st)
+    } else if st.iter().all(|c| c >= '0' && c <= '9') {
+        let s = String::from_iter(st.iter());
+        match i64::from_str(&s) {
+            Ok(n) => ParseResult::Ok(Ast::Num(n)),
+            Err(e) => err(&format!("int parse err: {}", e), st),
+        }
+    } else {
+        err("Not a number", st)
+    }
+}
 
 type TwoHandBuilder = fn(Box<Ast>, Box<Ast>) -> Ast;
 type OperatorMap = HashMap<char, TwoHandBuilder>;
@@ -213,7 +247,8 @@
     map
 }
 
-/// Parse any expression that has two sides and an infix operator (e.g. '4*5' or '6+7').
+/// Parse any expression that has two sides and an infix operator (e.g. '4*5' or '6+7'). Both sides
+/// of the expression are parsed using pexpr().
 ///
 /// opmap is a map from operator character to a function building an Ast fragment.
 ///
@@ -311,19 +346,19 @@
         let v = super::str_to_vec("2+4");
         let st = super::state(&v);
 
-        assert_eq!(super::expr(st),
+        assert_eq!(super::pexpr(st),
                    ParseResult::Ok(Ast::Addition(Box::new(Ast::Num(2)), Box::new(Ast::Num(4)))));
 
         let v = super::str_to_vec("2-4");
         let st = super::state(&v);
 
-        assert_eq!(super::expr(st),
+        assert_eq!(super::pexpr(st),
                    ParseResult::Ok(Ast::Subtraction(Box::new(Ast::Num(2)), Box::new(Ast::Num(4)))));
 
         let v = super::str_to_vec("2+4+5");
         let st = super::state(&v);
 
-        assert_eq!(super::expr(st),
+        assert_eq!(super::pexpr(st),
                    ParseResult::Ok(Ast::Addition(Box::new(Ast::Num(2)),
                                                  Box::new(Ast::Addition(Box::new(Ast::Num(4)),
                                                                         Box::new(Ast::Num(5)))))));
@@ -355,6 +390,14 @@
                    ParseResult::Ok(Ast::Multiplication(Box::new(Ast::Num(3)),
                                                        Box::new(Ast::Num(6)))));
 
+        let v = super::str_to_vec("(3*6");
+        let st = super::state(&v);
+
+        assert_eq!(super::pexpr(st),
+                   ParseResult::Err("Missing closing paren".to_string(),
+                                    "at 0-4: [(3*6]".to_string()));
+
+
         let v = super::str_to_vec("((3+6)*2)");
         let st = super::state(&v);
 
--- a/src/old_manual_parsers.rs	Wed Nov 23 21:13:05 2016 +0100
+++ b/src/old_manual_parsers.rs	Wed Nov 23 21:36:09 2016 +0100
@@ -94,29 +94,3 @@
         }
     }
 }
-fn sym<'a>(st: State<'a>) -> ParseResult {
-    if st.len() == 0 {
-        err("Empty", st)
-    } else if st.at(0) == '-' {
-        match num(st.restrict(1, st.len())) {
-            ParseResult::Ok(Ast::Num(n)) => ParseResult::Ok(Ast::Num(-n)),
-            x => x,
-        }
-    } else {
-        num(st)
-    }
-}
-
-fn num<'a>(st: State<'a>) -> ParseResult {
-    if st.len() == 0 {
-        err("Empty", st)
-    } else if st.iter().all(|c| c >= '0' && c <= '9') {
-        let s = String::from_iter(st.iter());
-        match i64::from_str(&s) {
-            Ok(n) => ParseResult::Ok(Ast::Num(n)),
-            Err(e) => err(&format!("int parse err: {}", e), st),
-        }
-    } else {
-        err("Not a number", st)
-    }
-}