[parser] Add subparser_completed() method to NodeParser and implementing Parsers
This commit is contained in:
parent
0a9f235836
commit
d3520be67e
4 changed files with 53 additions and 15 deletions
|
@ -9,13 +9,13 @@ use sym_parser::SymParser;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ListParser {
|
pub struct ListParser {
|
||||||
list: Obj
|
list: Option<Pair>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListParser {
|
impl ListParser {
|
||||||
pub fn new() -> ListParser {
|
pub fn new() -> ListParser {
|
||||||
ListParser {
|
ListParser {
|
||||||
list: Obj::Null
|
list: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,12 @@ impl NodeParser for ListParser {
|
||||||
match lex.token() {
|
match lex.token() {
|
||||||
Token::LeftParen => {
|
Token::LeftParen => {
|
||||||
match self.list {
|
match self.list {
|
||||||
Obj::Null => {
|
None => {
|
||||||
// Create our empty pair and proceed parsing this list.
|
// Create our empty pair and proceed parsing this list.
|
||||||
self.list = Obj::new(Pair::empty());
|
self.list = Some(Pair::empty());
|
||||||
NodeParseResult::Continue
|
NodeParseResult::Continue
|
||||||
},
|
},
|
||||||
Obj::Ptr(_) => {
|
Some(_) => {
|
||||||
// This is an embedded list. Create a new parser for it.
|
// This is an embedded list. Create a new parser for it.
|
||||||
let parser = ListParser::new();
|
let parser = ListParser::new();
|
||||||
NodeParseResult::Push { next: Box::new(parser) }
|
NodeParseResult::Push { next: Box::new(parser) }
|
||||||
|
@ -42,7 +42,17 @@ impl NodeParser for ListParser {
|
||||||
NodeParseResult::Push { next: Box::new(parser) }
|
NodeParseResult::Push { next: Box::new(parser) }
|
||||||
},
|
},
|
||||||
Token::RightParen => {
|
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");
|
let msg = format!("Unmatched paren, found EOF");
|
||||||
NodeParseResult::error(msg)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,9 @@ use sibiltypes::Obj;
|
||||||
pub enum NodeParseResult {
|
pub enum NodeParseResult {
|
||||||
/// Continue parsing with this NodeParser. The passed in Lex was consumed.
|
/// Continue parsing with this NodeParser. The passed in Lex was consumed.
|
||||||
Continue,
|
Continue,
|
||||||
/// This NodeParser has completed its work and has produced the given Object
|
/// This NodeParser has completed its work and has produced the given Object as a result.
|
||||||
/// as a result.
|
|
||||||
Complete { obj: Obj },
|
Complete { obj: Obj },
|
||||||
/// Push a new NodeParser onto the parsing stack and let that parser proceed
|
/// Push a new NodeParser onto the parsing stack and let that parser proceed with the current Lex.
|
||||||
/// with the current Lex.
|
|
||||||
Push { next: Box<NodeParser> },
|
Push { next: Box<NodeParser> },
|
||||||
/// There was an error parsing with the current Lex.
|
/// There was an error parsing with the current Lex.
|
||||||
Error { msg: String },
|
Error { msg: String },
|
||||||
|
@ -26,13 +24,16 @@ impl NodeParseResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `NodeParser` is responsible for parsing one particular thing in the Scheme
|
/// A `NodeParser` is responsible for parsing one particular thing in the Scheme parse tree.
|
||||||
/// parse tree. Roughly, there should be one `XParser` for each variant of the
|
/// Roughly, there should be one NodeParser for each type of object in `sibiltypes`. As the
|
||||||
/// `sibiltypes::Object` enum. As the top-level `Parser` object progresses
|
/// top-level `Parser` object progresses through the stream of tokens, new NodeParsers are created
|
||||||
/// through the stream of tokens, new NodeParsers are created to handle the
|
/// to handle the nodes it encounters.
|
||||||
/// nodes it encounters.
|
|
||||||
pub trait NodeParser: Debug {
|
pub trait NodeParser: Debug {
|
||||||
|
/// Called on a NodeParser when a Lex is encountered in the input.
|
||||||
fn parse(&mut self, lex: &Lex) -> NodeParseResult;
|
fn parse(&mut self, lex: &Lex) -> NodeParseResult;
|
||||||
/// Called on a NodeParser when None is encountered in the input.
|
/// Called on a NodeParser when None is encountered in the input.
|
||||||
fn none(&mut self) -> NodeParseResult;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,5 +40,9 @@ impl NodeParser for ProgramParser {
|
||||||
fn none(&mut self) -> NodeParseResult {
|
fn none(&mut self) -> NodeParseResult {
|
||||||
NodeParseResult::Complete { obj: Obj::Null }
|
NodeParseResult::Complete { obj: Obj::Null }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult {
|
||||||
|
NodeParseResult::Complete { obj: obj }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,4 +29,9 @@ impl NodeParser for SymParser {
|
||||||
let msg = format!("Expected symbol, found EOF");
|
let msg = format!("Expected symbol, found EOF");
|
||||||
NodeParseResult::error(msg)
|
NodeParseResult::error(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult {
|
||||||
|
let msg = format!("Unexpected parser result: {}", obj);
|
||||||
|
NodeParseResult::error(msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue