1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| use std::io::{Read, Error, ErrorKind}; use std::fmt;
enum ParseError { SyntaxError, Parse(Error) }
impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ParseError::SyntaxError => write!(f, "syntax error"), ParseError::Parse(ref e) => e.fmt(f), } } }
struct Parser { lookahead: u8, }
impl Parser { pub fn new() -> Self { let ch = read_char().expect("Cannot read charactor from input!"); Self { lookahead: ch, } }
pub fn expr(&mut self) -> Result<(), ParseError> { if let Err(e) = self.term() { return Err(e); } loop { if self.lookahead == b'+' { if let Err(e) = self.pmatch(b'+') { return Err(e); } if let Err(e) = self.term() { return Err(e); } print!("+"); } else if self.lookahead == b'-' { if let Err(e) = self.pmatch(b'-') { return Err(e); } if let Err(e) = self.term() { return Err(e); } print!("-"); } else { return Ok(()); } } }
pub fn term(&mut self) -> Result<(), ParseError> { if self.lookahead.is_ascii_digit() { print!("{}", char::from(self.lookahead)); self.pmatch(self.lookahead) } else { Err(ParseError::SyntaxError) } }
pub fn pmatch(&mut self, t: u8) -> Result<(), ParseError> { if self.lookahead == t { let input = read_char(); match input { Ok(ch) => { self.lookahead = ch; Ok(()) }, Err(e) => Err(ParseError::Parse(e)), } } else { Err(ParseError::SyntaxError) } } }
fn read_char() -> Result<u8, Error> { std::io::stdin().bytes().next() .unwrap_or(Err(Error::new(ErrorKind::Other, "Cannot read from stdin!"))) }
fn main() { let mut parse = Parser::new(); match parse.expr() { Ok(_) => println!(""), Err(e) => println!("{}", e), }; }
|