From fc3dcf792db12d6938f3a0cd5a23ea0c4d6dae9b Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 22 Jul 2015 02:48:27 -0700 Subject: [PATCH] Start writing recursive descent parser I think I get the idea now --- src/main.rs | 54 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index c973b93..1edefca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,12 +29,13 @@ enum Token { enum ASTNode { Name(String), Number(f64), - BinOp(Box, Box, Box) + BinOp(Box, Box, Box), + Binding(String, Box) } -enum ParseResult<'a> { - Ok(ASTNode, &'a [Token]), - Err(String, &'a [Token]) +enum ParseResult { + Ok(ASTNode), + Err(String) } fn repl() { @@ -55,8 +56,8 @@ fn repl() { println!("Tokens: {:?}", tokens); match parse(tokens) { - ParseResult::Ok(ast, _) => println!("AST: {:?}", ast), - ParseResult::Err(err, _) => println!("Error: {}", err) + ParseResult::Ok(ast) => println!("AST: {:?}", ast), + ParseResult::Err(err) => println!("Error: {}", err) } /* @@ -136,16 +137,17 @@ fn tokenize(input: &str) -> Vec { tokens } -fn parse<'a>(input: Vec) -> ParseResult<'a> { +fn parse(input: Vec) -> ParseResult { let mut tokens = input.iter(); - /* - let_expression(tokens); - expect(Token::EOF, tokens); - */ + if let ParseResult::Ok(ast) = let_expression(&mut tokens) { + if expect(EOF, &mut tokens) { + return ParseResult::Ok(ast); + } + } - return ParseResult::Ok(ASTNode::Name("Hella".to_string()), &[]); + return ParseResult::Err("Bad parse".to_string()); } fn expect(tok: Token, tokens: &mut Iter) -> bool { @@ -167,9 +169,31 @@ fn expect(tok: Token, tokens: &mut Iter) -> bool { return false; } -/* -fn let_expression<'a>(input: &mut Vec) -> ParseResult<'a> { +fn let_expression<'a>(input: &mut Iter) -> ParseResult { + if expect(Identifier("let".to_string()), input) { + if let Some(&Identifier(ref name)) = input.next() { + if let Some(&Identifier(ref s)) = input.next() { + if s == "=" { + let next = input.next(); + if let Some(&Identifier(ref value)) = next { + let ast = ASTNode::Binding(name.clone(), Box::new(ASTNode::Name(value.clone()))); + return ParseResult::Ok(ast); + } + if let Some(&StrLiteral(ref value)) = next { + let ast = ASTNode::Binding(name.clone(), Box::new(ASTNode::Name(value.clone()))); + return ParseResult::Ok(ast); + } + + if let Some(&NumLiteral(n)) = next { + let ast = ASTNode::Binding(name.clone(), Box::new(ASTNode::Number(n))); + return ParseResult::Ok(ast); + } + } + } + } + } + + return ParseResult::Err("Bad parse".to_string()); } -*/