Start writing recursive descent parser

I think I get the idea now
This commit is contained in:
greg 2015-07-22 02:48:27 -07:00
parent 02b34ca105
commit fc3dcf792d
1 changed files with 39 additions and 15 deletions

View File

@ -29,12 +29,13 @@ enum Token {
enum ASTNode { enum ASTNode {
Name(String), Name(String),
Number(f64), Number(f64),
BinOp(Box<ASTNode>, Box<ASTNode>, Box<ASTNode>) BinOp(Box<ASTNode>, Box<ASTNode>, Box<ASTNode>),
Binding(String, Box<ASTNode>)
} }
enum ParseResult<'a> { enum ParseResult {
Ok(ASTNode, &'a [Token]), Ok(ASTNode),
Err(String, &'a [Token]) Err(String)
} }
fn repl() { fn repl() {
@ -55,8 +56,8 @@ fn repl() {
println!("Tokens: {:?}", tokens); println!("Tokens: {:?}", tokens);
match parse(tokens) { match parse(tokens) {
ParseResult::Ok(ast, _) => println!("AST: {:?}", ast), ParseResult::Ok(ast) => println!("AST: {:?}", ast),
ParseResult::Err(err, _) => println!("Error: {}", err) ParseResult::Err(err) => println!("Error: {}", err)
} }
/* /*
@ -136,16 +137,17 @@ fn tokenize(input: &str) -> Vec<Token> {
tokens tokens
} }
fn parse<'a>(input: Vec<Token>) -> ParseResult<'a> { fn parse(input: Vec<Token>) -> ParseResult {
let mut tokens = input.iter(); let mut tokens = input.iter();
/* if let ParseResult::Ok(ast) = let_expression(&mut tokens) {
let_expression(tokens); if expect(EOF, &mut tokens) {
expect(Token::EOF, 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<Token>) -> bool { fn expect(tok: Token, tokens: &mut Iter<Token>) -> bool {
@ -167,9 +169,31 @@ fn expect(tok: Token, tokens: &mut Iter<Token>) -> bool {
return false; return false;
} }
/* fn let_expression<'a>(input: &mut Iter<Token>) -> ParseResult {
fn let_expression<'a>(input: &mut Vec<Token>) -> ParseResult<'a> { 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());
} }
*/