diff options
Diffstat (limited to 'src/lang/parser.rs')
-rw-r--r-- | src/lang/parser.rs | 284 |
1 files changed, 206 insertions, 78 deletions
diff --git a/src/lang/parser.rs b/src/lang/parser.rs index ec8ef40..ac7eccd 100644 --- a/src/lang/parser.rs +++ b/src/lang/parser.rs @@ -1,8 +1,11 @@ -use std::{mem, fmt}; -use std::error::Error; +use super::{TokType, Token, Tokenizer}; +use crate::synth::{ + all_factories, Environment, FactoryParameters, GenBox, GenFactoryErrorType, GeneratorFactory, + ParamValue, RelOp, +}; use std::collections::HashMap; -use super::*; -use synth::*; +use std::error::Error; +use std::{fmt, mem}; /* macro_rules! dprintln { @@ -36,8 +39,12 @@ impl ErrorType { }; ret.desc = match ret.kind { - ErrorKind::Unexpected(found, expected) => format!("Found {:?}, expected {:?}", found, expected), - ErrorKind::Unparseable(found, ref term) => format!("Cannot consume {:?} token in {}", found, term), + ErrorKind::Unexpected(found, expected) => { + format!("Found {:?}, expected {:?}", found, expected) + } + ErrorKind::Unparseable(found, ref term) => { + format!("Cannot consume {:?} token in {}", found, term) + } ErrorKind::ExpectedOp(c, found) => format!("Expected {:?}, found {:?}", c, found), ErrorKind::UnknownGen(ref s) => format!("Unknown generator name {}", s), }; @@ -61,20 +68,20 @@ impl Error for ErrorType { impl fmt::Display for ErrorType { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", self.description()) + write!(f, "{}", self.to_string()) } } -pub struct Parser<T: Iterator<Item=char>> { +pub struct Parser<T: Iterator<Item = char>> { tzr: Tokenizer<T>, env: Environment, token: Token, pushback: Option<Token>, - factories: HashMap<String, &'static GeneratorFactory>, + factories: HashMap<String, &'static dyn GeneratorFactory>, } -impl<T: Iterator<Item=char>> Parser<T> { - pub fn new(mut tzr: Tokenizer<T>, env: Environment) -> Result<Parser<T>, Box<Error>> { +impl<T: Iterator<Item = char>> Parser<T> { + pub fn new(mut tzr: Tokenizer<T>, env: Environment) -> Result<Parser<T>, Box<dyn Error>> { let token = tzr.next_token()?; Ok(Parser { tzr: tzr, @@ -89,7 +96,7 @@ impl<T: Iterator<Item=char>> Parser<T> { match self.pushback { None => { self.pushback = Some(tok); - }, + } Some(_) => panic!("too many pushbacks on Parser"), } } @@ -101,7 +108,7 @@ impl<T: Iterator<Item=char>> Parser<T> { } } - pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<Error>> { + pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<dyn Error>> { if ty != self.cur_token().to_type() { Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), ty)).into()) } else { @@ -112,18 +119,23 @@ impl<T: Iterator<Item=char>> Parser<T> { } } - pub fn expect_ident(&mut self) -> Result<String, Box<Error>> { + pub fn expect_ident(&mut self) -> Result<String, Box<dyn Error>> { match self.expect(TokType::Ident)? { Token::Ident(s) => Ok(s), _ => unreachable!(), } } - pub fn expect_op(&mut self, oper: char) -> Result<(), Box<Error>> { + pub fn expect_op(&mut self, oper: char) -> Result<(), Box<dyn Error>> { dprintln!("expect_op: {:?} ({})", self.cur_token(), oper); match *self.cur_token() { - Token::Oper(c) if c == oper => { self.expect(TokType::Oper)?; Ok(()) }, - _ => Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.cur_token().to_type())).into()), + Token::Oper(c) if c == oper => { + self.expect(TokType::Oper)?; + Ok(()) + } + _ => { + Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.cur_token().to_type())).into()) + } } } @@ -131,15 +143,14 @@ impl<T: Iterator<Item=char>> Parser<T> { dprintln!("peek_op: {:?} ({})", self.cur_token(), oper); match *self.cur_token() { Token::Oper(c) if c == oper => true, - _ => false + _ => false, } } - pub fn parse_gen_vec(&mut self) -> Result<Vec<GenBox>, Box<Error>> { + pub fn parse_gen_vec(&mut self) -> Result<Vec<GenBox>, Box<dyn Error>> { let mut ret: Vec<GenBox> = Vec::new(); self.expect_op('[')?; - loop { if self.expect_op(']').is_ok() { break; @@ -156,37 +167,70 @@ impl<T: Iterator<Item=char>> Parser<T> { Ok(ret) } - pub fn parse_gen_rel(&mut self) -> Result<GenBox, Box<Error>> { + pub fn parse_gen_rel(&mut self) -> Result<GenBox, Box<dyn Error>> { let left = self.parse_gen_terms()?; match *self.cur_token() { Token::Oper(c) => { - if c == '>' || c == '!' || c == '<' || c == '=' { // TODO: Conflict with param name + if c == '>' || c == '!' || c == '<' || c == '=' { + // TODO: Conflict with param name self.expect(TokType::Oper)?; let relop = match (c, self.cur_token()) { - ('<', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::LessEqual }, - ('=', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::Equal }, - ('>', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::Greater }, - ('!', &Token::Oper('=')) => { self.expect(TokType::Oper)?; RelOp::NotEqual }, + ('<', &Token::Oper('=')) => { + self.expect(TokType::Oper)?; + RelOp::LessEqual + } + ('=', &Token::Oper('=')) => { + self.expect(TokType::Oper)?; + RelOp::Equal + } + ('>', &Token::Oper('=')) => { + self.expect(TokType::Oper)?; + RelOp::Greater + } + ('!', &Token::Oper('=')) => { + self.expect(TokType::Oper)?; + RelOp::NotEqual + } ('<', _) => RelOp::Less, ('>', _) => RelOp::Greater, - _ => return Err(ErrorType::new(ErrorKind::Unparseable(TokType::Oper, "rel expr".to_string())).into()), + _ => { + return Err(ErrorType::new(ErrorKind::Unparseable( + TokType::Oper, + "rel expr".to_string(), + )) + .into()) + } + }; + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() }; - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::Generator(left)); - params.vars.insert("1".to_string(), ParamValue::String(relop.to_param_string().to_string())); - params.vars.insert("2".to_string(), ParamValue::Generator(self.parse_gen_rel()?)); - let factory = self.factories.get("rel").ok_or(ErrorType::new(ErrorKind::UnknownGen("rel".to_string())))?; + params + .vars + .insert("0".to_string(), ParamValue::Generator(left)); + params.vars.insert( + "1".to_string(), + ParamValue::String(relop.to_param_string().to_string()), + ); + params.vars.insert( + "2".to_string(), + ParamValue::Generator(self.parse_gen_rel()?), + ); + let factory = self + .factories + .get("rel") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("rel".to_string())))?; factory.new(&mut params).map_err(Into::into) } else { Ok(left) } - }, + } _ => Ok(left), } } - pub fn parse_gen_terms(&mut self) -> Result<GenBox, Box<Error>> { + pub fn parse_gen_terms(&mut self) -> Result<GenBox, Box<dyn Error>> { let mut gens: Vec<GenBox> = Vec::new(); gens.push(self.parse_gen_factors()?); @@ -195,14 +239,27 @@ impl<T: Iterator<Item=char>> Parser<T> { Token::Oper('+') => { self.expect_op('+')?; gens.push(self.parse_gen_factors()?); - }, + } Token::Oper('-') => { self.expect_op('-')?; - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::Generator(self.parse_gen_factors()?)); - let factory = self.factories.get("negate").ok_or(ErrorType::new(ErrorKind::UnknownGen("negate".to_string())))?; - gens.push(factory.new(&mut params).map_err(GenFactoryErrorType::from)?); - }, + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; + params.vars.insert( + "0".to_string(), + ParamValue::Generator(self.parse_gen_factors()?), + ); + let factory = self + .factories + .get("negate") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("negate".to_string())))?; + gens.push( + factory + .new(&mut params) + .map_err(GenFactoryErrorType::from)?, + ); + } _ => break, } } @@ -211,15 +268,23 @@ impl<T: Iterator<Item=char>> Parser<T> { return Ok(gens.pop().unwrap()); } - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; for (idx, gen) in gens.into_iter().enumerate() { - params.vars.insert(idx.to_string(), ParamValue::Generator(gen)); + params + .vars + .insert(idx.to_string(), ParamValue::Generator(gen)); } - let factory = self.factories.get("add").ok_or(ErrorType::new(ErrorKind::UnknownGen("add".to_string())))?; + let factory = self + .factories + .get("add") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("add".to_string())))?; factory.new(&mut params).map_err(Into::into) } - pub fn parse_gen_factors(&mut self) -> Result<GenBox, Box<Error>> { + pub fn parse_gen_factors(&mut self) -> Result<GenBox, Box<dyn Error>> { let mut gens: Vec<GenBox> = Vec::new(); gens.push(self.parse_gen()?); @@ -228,14 +293,25 @@ impl<T: Iterator<Item=char>> Parser<T> { Token::Oper('*') => { self.expect_op('*')?; gens.push(self.parse_gen()?); - }, + } Token::Oper('/') => { self.expect_op('/')?; - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::Generator(self.parse_gen()?)); - let factory = self.factories.get("reciprocate").ok_or(ErrorType::new(ErrorKind::UnknownGen("reciprocate".to_string())))?; - gens.push(factory.new(&mut params).map_err(GenFactoryErrorType::from)?); - }, + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; + params + .vars + .insert("0".to_string(), ParamValue::Generator(self.parse_gen()?)); + let factory = self.factories.get("reciprocate").ok_or(ErrorType::new( + ErrorKind::UnknownGen("reciprocate".to_string()), + ))?; + gens.push( + factory + .new(&mut params) + .map_err(GenFactoryErrorType::from)?, + ); + } _ => break, } } @@ -244,32 +320,56 @@ impl<T: Iterator<Item=char>> Parser<T> { return Ok(gens.pop().unwrap()); } - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; for (idx, gen) in gens.into_iter().enumerate() { - params.vars.insert(idx.to_string(), ParamValue::Generator(gen)); + params + .vars + .insert(idx.to_string(), ParamValue::Generator(gen)); } - let factory = self.factories.get("mul").ok_or(ErrorType::new(ErrorKind::UnknownGen("mul".to_string())))?; + let factory = self + .factories + .get("mul") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("mul".to_string())))?; factory.new(&mut params).map_err(Into::into) } - pub fn parse_gen(&mut self) -> Result<GenBox, Box<Error>> { + pub fn parse_gen(&mut self) -> Result<GenBox, Box<dyn Error>> { match *self.cur_token() { Token::Integer(v) => { self.expect(TokType::Integer)?; - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::String("_".to_string())); + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; + params + .vars + .insert("0".to_string(), ParamValue::String("_".to_string())); params.vars.insert("1".to_string(), ParamValue::Integer(v)); - let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; + let factory = self + .factories + .get("param") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; factory.new(&mut params).map_err(Into::into) - }, + } Token::Float(v) => { self.expect(TokType::Float)?; - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::String("_".to_string())); + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; + params + .vars + .insert("0".to_string(), ParamValue::String("_".to_string())); params.vars.insert("1".to_string(), ParamValue::Float(v)); - let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; + let factory = self + .factories + .get("param") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; factory.new(&mut params).map_err(Into::into) - }, + } Token::Ident(_) => { let name = self.expect_ident()?; if self.peek_op('(') { @@ -280,12 +380,20 @@ impl<T: Iterator<Item=char>> Parser<T> { }; factory.new(&mut params).map_err(Into::into) } else { - let mut params = FactoryParameters { env: self.env.clone(), ..Default::default() }; - params.vars.insert("0".to_string(), ParamValue::String(name)); - let factory = self.factories.get("param").ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; + let mut params = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; + params + .vars + .insert("0".to_string(), ParamValue::String(name)); + let factory = self + .factories + .get("param") + .ok_or(ErrorType::new(ErrorKind::UnknownGen("param".to_string())))?; factory.new(&mut params).map_err(Into::into) } - }, + } Token::Oper('(') => { dprintln!("consuming paren in parse_gen"); self.expect(TokType::Oper)?; @@ -293,16 +401,23 @@ impl<T: Iterator<Item=char>> Parser<T> { dprintln!("parenthesized generator is concluding"); self.expect_op(')')?; Ok(ret) - }, - _ => Err(ErrorType::new(ErrorKind::Unparseable(self.cur_token().to_type(), "gen".to_string())).into()), + } + _ => Err(ErrorType::new(ErrorKind::Unparseable( + self.cur_token().to_type(), + "gen".to_string(), + )) + .into()), } } - pub fn parse_factory_params(&mut self) -> Result<FactoryParameters, Box<Error>> { + pub fn parse_factory_params(&mut self) -> Result<FactoryParameters, Box<dyn Error>> { dprintln!("consuming paren in factory_params"); self.expect_op('(')?; - let mut params: FactoryParameters = FactoryParameters { env: self.env.clone(), ..Default::default() }; + let mut params: FactoryParameters = FactoryParameters { + env: self.env.clone(), + ..Default::default() + }; let mut ctr = 0; loop { if self.expect_op(')').is_ok() { @@ -313,7 +428,7 @@ impl<T: Iterator<Item=char>> Parser<T> { ctr = new_ctr; dprintln!("before factory_params comma, tok is {:?}", self.cur_token()); - if self.expect_op(',').map_err(|e| dprintln!("factory_params consume comma failed: {:?}", e)).is_err() { + if self.expect_op(',').map_err(|_e| dprintln!("factory_params consume comma failed: {:?}", e)).is_err() { dprintln!("factory_params is concluding"); self.expect_op(')')?; break; @@ -323,7 +438,10 @@ impl<T: Iterator<Item=char>> Parser<T> { Ok(params) } - pub fn parse_param(&mut self, pos: usize) -> Result<(String, ParamValue, usize), Box<Error>> { + pub fn parse_param( + &mut self, + pos: usize, + ) -> Result<(String, ParamValue, usize), Box<dyn Error>> { let mut ctr = pos; let name = match self.expect_ident() { Ok(nm) => { @@ -334,19 +452,29 @@ impl<T: Iterator<Item=char>> Parser<T> { ctr += 1; (ctr - 1).to_string() } - }, + } Err(_) => { ctr += 1; (ctr - 1).to_string() - }, + } }; dprintln!("about to consume param value, token is {:?}", self.cur_token()); - match self.cur_token().clone() { // FIXME: Does this really need to be cloned? - Token::String(ref v) => { self.expect(TokType::String)?; Ok((name, ParamValue::String(v.clone()), ctr)) }, - Token::Integer(_) | Token::Float(_) | Token::Ident(_) | Token::Oper('(') => Ok((name, ParamValue::Generator(self.parse_gen_rel()?), ctr)), - _ => Err(ErrorType::new(ErrorKind::Unparseable(self.cur_token().to_type(), "param value".to_string())).into()), + match self.cur_token().clone() { + // FIXME: Does this really need to be cloned? + Token::String(ref v) => { + self.expect(TokType::String)?; + Ok((name, ParamValue::String(v.clone()), ctr)) + } + Token::Integer(_) | Token::Float(_) | Token::Ident(_) | Token::Oper('(') => { + Ok((name, ParamValue::Generator(self.parse_gen_rel()?), ctr)) + } + _ => Err(ErrorType::new(ErrorKind::Unparseable( + self.cur_token().to_type(), + "param value".to_string(), + )) + .into()), } } } |