From 55750a223008b256fddd8636ff4d474f959c8a23 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 8 Jun 2026 09:56:20 -0700 Subject: Many little changes to parsing, getting better. --- src/lexer.rs | 2 +- src/lib.rs | 7 ++-- src/parser.rs | 113 ++++++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 87 insertions(+), 35 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 902bb64..4225b32 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -229,7 +229,7 @@ impl<'a> Lexer<'a> { } else { Some(Symbol::new( match s { "fragment" => SymbolType::Fragment, - "section" => SymbolType::Section, + "show" => SymbolType::Show, "output" => SymbolType::Output, _ => SymbolType::Token(s) }, start_pos, end_pos )) diff --git a/src/lib.rs b/src/lib.rs index 5e912cf..25d9be1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,10 +40,10 @@ enum FragmentSource { struct Fragment { name: String, source: usize, - sections: HashMap, + sections: HashMap, } -struct Section { +struct Output { name: String, ast_root: Token, } @@ -53,7 +53,8 @@ type Properties = HashMap; enum Token { Root(Vec), Fragment(String,Properties,Vec), - Section(String,Properties,Vec), + Output(String,Properties,Vec), + Show(String,Properties), Text(String), Literal(String), /* diff --git a/src/parser.rs b/src/parser.rs index 2d845cd..368a246 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,7 +5,7 @@ use core::error::Error; use std::fmt; #[derive(Debug)] -struct ParseError { +pub struct ParseError { position: Position, what: String, } @@ -18,6 +18,8 @@ impl fmt::Display for ParseError { impl Error for ParseError { } +pub type ParseResult = Result; + struct Context<'a> { cur: [Option>;2], icur: usize, @@ -51,6 +53,19 @@ impl<'a> Context<'a> { } } +impl Option { + pub fn is bool>(&self, f: T ) -> ParseError { + if let Some(st) = self { + Ok(f( &self.symbol )) + } else { + Err(ParseError{ + position: Position::new(0,0), + what: "Unexpeceted end of stream.".to_string() + }) + } + } +} + pub struct Parser { } @@ -137,21 +152,21 @@ impl Parser { } } - fn lex_error(&self, error: &Symbol) -> Result> { + fn lex_error(&self, error: &Symbol) -> ParseResult { if let SymbolType::Error{what} = error.symbol() { - Err(Box::new(ParseError { + Err(ParseError { position: error.start().clone(), what: format!("What: {:?}", *what) - })) + }) } else { - Err(Box::new(ParseError { + Err(ParseError { position: Position::new(0,0), what: "Not an error?".to_string(), - })) + }) } } - pub fn parse(&mut self, src: &str ) -> Result> { + pub fn parse(&mut self, src: &str ) -> ParseResult { let mut ll = Lexer::new( src ); let mut ctx = Context::new( ll ); @@ -159,7 +174,7 @@ impl Parser { self.p_input( &mut ctx ) } - fn p_input(&mut self, ctx: &mut Context ) -> Result> { + fn p_input(&mut self, ctx: &mut Context ) -> ParseResult { let mut children = Vec::new(); loop { if ctx.cur().is_none() { @@ -182,7 +197,7 @@ impl Parser { Ok(Token::Root(children)) } - fn parse_tag(&mut self, ctx: &mut Context) -> Result> { + fn parse_tag(&mut self, ctx: &mut Context) -> ParseResult { let mut tb = TagBuilder::new(); println!("--> Begin parse_tag <--"); @@ -193,28 +208,23 @@ impl Parser { if ctx.next().is_some() { match ctx.cur().unwrap().symbol() { - SymbolType::Fragment | SymbolType::Section | + SymbolType::Fragment | SymbolType::Show | SymbolType::Output => { let name_sym = ctx.cur().unwrap(); ctx.next(); tb.set_name( name_sym ); } _ => { - return Err(Box::new(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()})); + return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()}); } } } else { - return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); + return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); } - println!("--> Begin parse_tag_params <--"); self.parse_tag_params( ctx, &mut tb )?; - println!("--> End parse_tag_params <--"); - println!("--> Begin parse_tag_props <--"); self.parse_tag_props( ctx, &mut tb )?; - println!("--> End parse_tag_props <--"); - println!("---> {:?}", ctx.cur() ); if let Some(end_sym) = ctx.cur() { match end_sym.symbol() { SymbolType::EndPoint => { @@ -224,19 +234,57 @@ impl Parser { tb.set_type( TagType::Unary ); } _ => { - return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); + return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); } } } - tb.build() + Ok(tb) } - fn parse_tag_params(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<(), Box> { + fn parse_end_tag(&mut self, ctx: &mut Context ) -> &'a str { + if !ctx.cur().is(|s| matches!(s, Symbol::StartPoint))? { + return Err(ParseError{ + position: ctx.cur(). + }); + } + ctx.next() + } + + fn parse_tag_body(&mut 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()}); + } + match ctx.cur().unwrap().symbol() { + SymbolType::Text(s) => { + tb.add_child(Token:: Text(s.to_string())); + } + SymbolType::StartFlat => { + tb.add_child( self.parse_tag( ctx )? ); + } + SymbolType::StartPoint => { + let end_tag = self.parse_end_tag( ctx )?; - return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); + } + SymbolType::Error{..} => { + return self.lex_error( &ctx.cur().unwrap() ); + } + _ => { + + } + } + ctx.next(); + } + Ok(Token::Root(children)) + Ok(()) + } + + fn parse_tag_params(&mut 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()}); } match ctx.cur().unwrap().symbol() { SymbolType::Literal(s) => { @@ -251,10 +299,10 @@ impl Parser { Ok(()) } - fn parse_tag_props(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<(), Box> { + fn parse_tag_props(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { loop { if ctx.cur().is_none() { - return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); + return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); } if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { @@ -263,10 +311,10 @@ impl Parser { let SymbolType::Literal(lv) = sym.symbol() { tb.add_prop( s.to_string(), lv.to_string() ); } else { - return Err(Box::new(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()})); + return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); } } else { - return Err(Box::new(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()})); + return Err(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()}); } } else { break; @@ -343,28 +391,31 @@ impl<'a> TagBuilder<'a> { self.tag_type = tag_type; } - pub fn build(mut self) -> Result> { + pub fn build(mut self) -> ParseResult { if let Some(sym) = self.name { match sym.symbol() { SymbolType::Fragment => { Ok(Token::Fragment(self.params.swap_remove(0), self.props, self.children)) } SymbolType::Output => { - Ok(Token::Section(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)) } _ => { println!("Unkown tag type"); - Err(Box::new(ParseError { + Err(ParseError { position: Position::new(0,0), what: "Bad tag type".to_string(), - })) + }) } } } else { - Err(Box::new(ParseError { + Err(ParseError { position: Position::new(0,0), what: "Bad tag type".to_string(), - })) + }) } } } -- cgit v1.2.3