use std::io; use std::io::prelude::*; use std::iter; use std::str; // expr ::= term (('+'|'-') term)* // term ::= ('+'|'-')? (number | '(' expr ')') // number ::= \d fn number(chars: &mut iter::Peekable) -> i64 { let c = chars.next().unwrap(); c.to_digit(10).unwrap() as i64 } fn term(chars: &mut iter::Peekable) -> i64 { let mut sign = 1; let &c = chars.peek().unwrap(); match c { '+' => { chars.next(); }, '-' => { chars.next(); sign = -1; }, _ => {}, }; let &c = chars.peek().unwrap(); let mut res = if c == '(' { chars.next(); let res = expr(chars); assert_eq!(')', chars.next().unwrap()); res } else { number(chars) }; res *= sign; res } fn expr(chars: &mut iter::Peekable) -> i64 { let mut res = term(chars); while let Some(&c) = chars.peek() { match c { '+' => { chars.next(); res += term(chars); }, '-' => { chars.next(); res -= term(chars); }, _ => { break; }, } } res } fn eval(s: &str) -> i64 { let mut chars = s.chars().peekable(); expr(&mut chars) } #[test] fn test_eval() { assert_eq!( 0, eval("0")); assert_eq!( 1, eval("1")); assert_eq!( 1, eval("+1")); assert_eq!(-1, eval("-1")); assert_eq!( 3, eval("1+2")); assert_eq!( 4, eval("8-4")); assert_eq!(-5, eval("-9+4")); assert_eq!(-7, eval("-3-4")); assert_eq!( 1, eval("(1)")); assert_eq!( 5, eval("(2+3)")); assert_eq!( 6, eval("(9-3)")); assert_eq!( 7, eval("+(4+3)")); assert_eq!(-4, eval("-(2+2)")); assert_eq!( 1, eval("-(2-3)")); assert_eq!(15, eval("-(1+2+3)+(1+2+3+4+5+6)")); } fn main() { let mut line = String::new(); io::stdin().read_to_string(&mut line).unwrap(); let line = line.trim(); let ans = eval(&line); println!("{}", ans); }