From 0f2bd09d269862105e603a9865201f521f49490b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 8 Jun 2026 21:45:30 -0700 Subject: It works again! and more! About to change a few things: - symbols and errors will have a range not a position - remove view/output token type, those should just be View and Output structs - Figure out some formatting stuff? (add a dep? I dunno) - Move to non-quoted dot-delimeted variable references. - Add loops. - Add conditionals? - Add more! --- src/parser.rs | 57 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'src/parser.rs') diff --git a/src/parser.rs b/src/parser.rs index 13e89aa..c7a8abe 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -17,6 +17,13 @@ impl ParseError { what: what.to_string(), } } + + pub fn eos( context: &str ) -> Self { + ParseError { + position: Position::none(), + what: format!("Premature end of stream while looking for {}", context), + } + } } impl fmt::Display for ParseError { @@ -61,12 +68,9 @@ impl<'a> Context<'a> { self.cur[(self.icur+1)%2] } - pub fn check_unwrapped bool>(&self, f: T) -> ParseResult { + pub fn check_unwrapped bool>(&self, context: &str, f: T) -> ParseResult { if self.cur().is_none() || self.peek().is_none() { - Err(ParseError{ - position: Position::new(0,0), - what: "Unexpected end of stream.".to_string() - }) + Err(ParseError::eos( context )) } else { Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) } @@ -74,19 +78,16 @@ impl<'a> Context<'a> { } trait SymbolHelper { - fn is bool>(&self, f: T ) -> ParseResult; + fn is bool>(&self, context: &str, f: T ) -> ParseResult; fn is_valid_tag_name(&self) -> ParseResult; } impl<'a> SymbolHelper for Option> { - fn is bool>(&self, f: T ) -> ParseResult { + fn is bool>(&self, context: &str, f: T ) -> ParseResult { if let Some(st) = self { Ok(f( &st.symbol() )) } else { - Err(ParseError{ - position: Position::new(0,0), - what: "Unexpected end of stream.".to_string() - }) + Err(ParseError::eos( context )) } } @@ -256,10 +257,7 @@ impl Parser { //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); loop { if ctx.cur().is_none() { - return Err(ParseError{ - position: Position::new(0,0), - what: "Unexpected end of stream.".to_string() - }); + return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())) } match ctx.cur().unwrap().symbol() { SymbolType::Text(s) => { @@ -282,7 +280,7 @@ impl Parser { // Everything is either text or output if !any_outputs { // Special case, if it's only text then we create an implicit output. - tb.add_child(Token::Output("content".to_string(), Properties::new(), children )); + tb.add_child(Token::Output("content".to_string(), /*Properties::new(),*/ children )); } else { // Standard case, outputs are included, text is @@ -303,7 +301,7 @@ impl Parser { }); } else { // No outputs at all, we create an implict output - tb.add_child(Token::Output("content".to_string(), Properties::new(), children )); + tb.add_child(Token::Output("content".to_string(), /*Properties::new(), */children )); } } @@ -339,11 +337,11 @@ impl Parser { tb.set_name( name_sym ); } _ => { - return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()}); + return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpected symbol".to_string()}); } } } else { - return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); + return Err(ParseError::eos("tag type")); } self.parse_tag_params( ctx, &mut tb )?; @@ -358,7 +356,10 @@ impl Parser { tb.set_type( TagType::Unary ); } _ => { - return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); + return Err(ParseError::new( + end_sym.start().clone(), + format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()).as_str() + )); } } } @@ -369,7 +370,7 @@ impl Parser { } fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult> { - if !ctx.cur().is(|s| *s == SymbolType::StartPoint )? { + if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { return Err(ParseError{ position: *ctx.cur().unwrap().start(), what: "Invalid end tag?".to_string(), @@ -382,7 +383,7 @@ impl Parser { }); } let name = ctx.cur().unwrap(); - if !ctx.next().is(|s| *s == SymbolType::EndFlat )? { + if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { return Err(ParseError{ position: *ctx.cur().unwrap().start(), what: "Tag should be <| |] style end tag.".to_string(), @@ -399,7 +400,7 @@ impl Parser { loop { if ctx.cur().is_none() { - return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); + return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())); } match ctx.cur().unwrap().symbol() { SymbolType::Text(s) => { @@ -435,8 +436,7 @@ impl Parser { fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { loop { if ctx.cur().is_none() { - - return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); + return Err(ParseError::eos("tag parameters")); } match ctx.cur().unwrap().symbol() { SymbolType::Literal(s) => { @@ -454,7 +454,7 @@ impl Parser { fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { loop { if ctx.cur().is_none() { - return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); + return Err(ParseError::eos("tag properties")); } if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { @@ -466,7 +466,7 @@ impl Parser { return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); } } else { - return Err(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()}); + break; } } else { break; @@ -482,7 +482,6 @@ enum TagType { Unknown, Unary, BinaryOpen, - BinaryClose, } struct TagBuilder<'a> { @@ -573,7 +572,7 @@ impl<'a> TagBuilder<'a> { Ok(Token::View(self.params.swap_remove(0), self.props, self.children)) } SymbolType::Output => { - Ok(Token::Output(self.params.swap_remove(0), self.props, self.children)) + Ok(Token::Output(self.params.swap_remove(0), /*self.props,*/ self.children)) } SymbolType::Show => { Ok(Token::Show(self.params.swap_remove(0), self.props)) -- cgit v1.2.3