write expect
and also make the ParseResult type more general so it can be used for more things.
This commit is contained in:
parent
186c900920
commit
32a90b8103
@ -4,7 +4,7 @@ use std::slice::Iter;
|
|||||||
use tokenizer::Token;
|
use tokenizer::Token;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum AST {
|
pub enum AST {
|
||||||
BinOp(Box<AST>, Box<AST>, Box<AST>),
|
BinOp(Box<AST>, Box<AST>, Box<AST>),
|
||||||
Number(f64),
|
Number(f64),
|
||||||
Name(String),
|
Name(String),
|
||||||
@ -15,7 +15,7 @@ pub struct ParseError {
|
|||||||
err: String
|
err: String
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ParseResult = Result<AST, ParseError>;
|
pub type ParseResult<T> = Result<T, ParseError>;
|
||||||
|
|
||||||
/* grammar
|
/* grammar
|
||||||
|
|
||||||
@ -29,38 +29,36 @@ struct Parser<'a> {
|
|||||||
tokens: Peekable<Iter<'a, Token>>
|
tokens: Peekable<Iter<'a, Token>>
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! expect {
|
impl<'a> Parser<'a> {
|
||||||
($tok:expr, $self_:ident) => {
|
|
||||||
match $self_.tokens.next() {
|
fn expect(&mut self, expected: Token) -> ParseResult<()> {
|
||||||
Some(next) if *next == $tok => (),
|
match self.tokens.next() {
|
||||||
|
Some(next) if *next == expected => Ok(()),
|
||||||
Some(next) => {
|
Some(next) => {
|
||||||
let err = format!("Expected {:?} but got {:?}", $tok, next);
|
let err = format!("Expected {:?} but got {:?}", expected, next);
|
||||||
return Err(ParseError { err: err });
|
return Err(ParseError { err: err });
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let err = format!("Expected {:?} but got end of input", $tok);
|
let err = format!("Expected {:?} but got end of input", expected);
|
||||||
return Err(ParseError { err: err });
|
return Err(ParseError { err: err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
fn parse(&mut self) -> ParseResult<AST> {
|
||||||
|
|
||||||
fn parse(&mut self) -> ParseResult {
|
|
||||||
let r = self.expr();
|
let r = self.expr();
|
||||||
expect!(Token::Separator, self);
|
try!(self.expect(Token::Separator));
|
||||||
expect!(Token::EOF, self);
|
try!(self.expect(Token::EOF));
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr(&mut self) -> ParseResult {
|
fn expr(&mut self) -> ParseResult<AST> {
|
||||||
self.tokens.next();
|
self.tokens.next();
|
||||||
return Ok(AST::Number(5.0));
|
return Ok(AST::Number(5.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(input: Vec<Token>) -> ParseResult {
|
pub fn parse(input: Vec<Token>) -> ParseResult<AST> {
|
||||||
let mut iter = input.iter().peekable();
|
let mut iter = input.iter().peekable();
|
||||||
let mut parser = Parser { tokens: iter };
|
let mut parser = Parser { tokens: iter };
|
||||||
return parser.parse();
|
return parser.parse();
|
||||||
|
Loading…
Reference in New Issue
Block a user