[parser] Add subparser_completed() method to NodeParser and implementing Parsers

This commit is contained in:
Eryn Wells 2018-08-24 21:06:24 -07:00
parent 0a9f235836
commit d3520be67e
4 changed files with 53 additions and 15 deletions

View file

@ -9,13 +9,13 @@ use sym_parser::SymParser;
#[derive(Debug)]
pub struct ListParser {
list: Obj
list: Option<Pair>
}
impl ListParser {
pub fn new() -> ListParser {
ListParser {
list: Obj::Null
list: None
}
}
}
@ -25,12 +25,12 @@ impl NodeParser for ListParser {
match lex.token() {
Token::LeftParen => {
match self.list {
Obj::Null => {
None => {
// Create our empty pair and proceed parsing this list.
self.list = Obj::new(Pair::empty());
self.list = Some(Pair::empty());
NodeParseResult::Continue
},
Obj::Ptr(_) => {
Some(_) => {
// This is an embedded list. Create a new parser for it.
let parser = ListParser::new();
NodeParseResult::Push { next: Box::new(parser) }
@ -42,7 +42,17 @@ impl NodeParser for ListParser {
NodeParseResult::Push { next: Box::new(parser) }
},
Token::RightParen => {
NodeParseResult::Complete { obj: self.list.take() }
match self.list {
None => {
let msg = format!("Found right paren without matching left paren");
NodeParseResult::error(msg)
},
Some(_) => {
let taken = self.list.take().unwrap();
// TODO: If the cdr is Null, fill it in with an empty pair.
NodeParseResult::Complete { obj: Obj::new(taken) }
}
}
}
}
}
@ -51,4 +61,22 @@ impl NodeParser for ListParser {
let msg = format!("Unmatched paren, found EOF");
NodeParseResult::error(msg)
}
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult {
if let Some(ref mut list) = self.list {
match list.car {
Obj::Null => {
list.car = obj;
},
Obj::Ptr(_) => {
let pair = Pair::with_car(obj);
list.cdr = Obj::new(pair);
}
}
NodeParseResult::Continue
} else {
let msg = format!("what happened here???");
NodeParseResult::error(msg)
}
}
}

View file

@ -10,11 +10,9 @@ use sibiltypes::Obj;
pub enum NodeParseResult {
/// Continue parsing with this NodeParser. The passed in Lex was consumed.
Continue,
/// This NodeParser has completed its work and has produced the given Object
/// as a result.
/// This NodeParser has completed its work and has produced the given Object as a result.
Complete { obj: Obj },
/// Push a new NodeParser onto the parsing stack and let that parser proceed
/// with the current Lex.
/// Push a new NodeParser onto the parsing stack and let that parser proceed with the current Lex.
Push { next: Box<NodeParser> },
/// There was an error parsing with the current Lex.
Error { msg: String },
@ -26,13 +24,16 @@ impl NodeParseResult {
}
}
/// A `NodeParser` is responsible for parsing one particular thing in the Scheme
/// parse tree. Roughly, there should be one `XParser` for each variant of the
/// `sibiltypes::Object` enum. As the top-level `Parser` object progresses
/// through the stream of tokens, new NodeParsers are created to handle the
/// nodes it encounters.
/// A `NodeParser` is responsible for parsing one particular thing in the Scheme parse tree.
/// Roughly, there should be one NodeParser for each type of object in `sibiltypes`. As the
/// top-level `Parser` object progresses through the stream of tokens, new NodeParsers are created
/// to handle the nodes it encounters.
pub trait NodeParser: Debug {
/// Called on a NodeParser when a Lex is encountered in the input.
fn parse(&mut self, lex: &Lex) -> NodeParseResult;
/// Called on a NodeParser when None is encountered in the input.
fn none(&mut self) -> NodeParseResult;
/// Called on a NodeParser when a NodeParser created by this one returns an object via
/// `NodeParseResult::Complete`.
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult;
}

View file

@ -40,5 +40,9 @@ impl NodeParser for ProgramParser {
fn none(&mut self) -> NodeParseResult {
NodeParseResult::Complete { obj: Obj::Null }
}
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult {
NodeParseResult::Complete { obj: obj }
}
}

View file

@ -29,4 +29,9 @@ impl NodeParser for SymParser {
let msg = format!("Expected symbol, found EOF");
NodeParseResult::error(msg)
}
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult {
let msg = format!("Unexpected parser result: {}", obj);
NodeParseResult::error(msg)
}
}