diff --git a/src/main.rs b/src/main.rs index deaba87..09575a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,10 +57,11 @@ impl ReplState for InterpreterState { fn repl_handler(input: &str, state: &mut InterpreterState) -> String { if state.show_tokens { - format!("Tokens: {:?}", tokenize(input)) - } else if state.show_parse{ - format!("Parse: {:?}", parse(tokenize(input))) - } else { - format!("{:?}", parse(tokenize(input))) + println!("Tokens: {:?}", tokenize(input)) } + + if state.show_parse { + println!("Parse: {:?}", parse(tokenize(input))) + } + format!("{:?}", parse(tokenize(input))) } diff --git a/src/parser.rs b/src/parser.rs index f9c57fa..24bf72f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,13 +1,8 @@ +use std::iter::Peekable; +use std::slice::Iter; + use tokenizer::Token; -/* grammar - - expr : term ((PLUS|MIMUS) term)* - term : factor ((MUL | DIV) factor)* - factor : NUM | LPAREN expr RPAREN - -*/ - #[derive(Debug)] enum AST { BinOp(Box, Box, Box), @@ -22,9 +17,56 @@ pub struct ParseError { pub type ParseResult = Result; -pub fn parse(input: Vec) -> ParseResult { - let mut current_token: Token; +/* grammar - return Err(ParseError { err: "error!".to_string() }); + expr : term ((PLUS|MIMUS) term)* + term : factor ((MUL | DIV) factor)* + factor : NUM | LPAREN expr RPAREN + +*/ + +struct Parser<'a> { + tokens: Peekable> +} + +impl<'a> Parser<'a> { + + fn parse(&mut self) -> ParseResult { + let r = self.expr(); + match self.expect(Token::Separator) { + None => (), + Some(err) => return Err(err) + } + match self.expect(Token::EOF) { + None => (), + Some(err) => return Err(err) + } + r + } + + fn expect(&mut self, expected: Token) -> Option { + match self.tokens.next() { + Some(next) if *next == expected => None, + Some(next) => { + let err = format!("Expected {:?} but got {:?}", expected, next); + Some(ParseError { err: err }) + } + None => { + let err = format!("Expected {:?} but got end of input", expected); + Some(ParseError { err: err }) + } + } + } + + fn expr(&mut self) -> ParseResult { + self.tokens.next(); + return Ok(AST::Number(5.0)); + } +} + +pub fn parse(input: Vec) -> ParseResult { + let mut iter = input.iter().peekable(); + let mut parser = Parser { tokens: iter }; + return parser.parse(); } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 16ee241..082b32f 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1,4 +1,4 @@ -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Token { EOF, Separator, @@ -36,7 +36,6 @@ pub fn tokenize(input: &str) -> Vec { ';' => true, '(' => true, ')' => true, - '.' => true, _ => false } }