From 83ab8c67beecfc05684c9400e29f7d77225d3af9 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 7 Jun 2026 16:37:28 -0700 Subject: Cleaned up a lot of parsing code. --- src/parser.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 32 deletions(-) (limited to 'src/parser.rs') diff --git a/src/parser.rs b/src/parser.rs index e5ea1f5..2d845cd 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -27,6 +27,7 @@ struct Context<'a> { impl<'a> Context<'a> { pub fn new( mut ll: Lexer<'a> ) -> Self { let cur = [ll.next(), ll.next()]; + //println!(" - cur: {:?}, peek: {:?}", cur[0], cur[1] ); Self { cur, icur: 0, @@ -37,7 +38,7 @@ impl<'a> Context<'a> { pub fn next(&mut self) -> Option> { self.cur[self.icur] = self.ll.next(); self.icur = (self.icur+1)%2; - println!(" - cur: {:?}, peek: {:?}", self.cur(), self.peek() ); + //println!(" - cur: {:?}, peek: {:?}", self.cur(), self.peek() ); self.cur[self.icur] } @@ -136,7 +137,7 @@ impl Parser { } } - fn lex_error(&self, error: &Symbol) -> Result<(),Box> { + fn lex_error(&self, error: &Symbol) -> Result> { if let SymbolType::Error{what} = error.symbol() { Err(Box::new(ParseError { position: error.start().clone(), @@ -150,17 +151,16 @@ impl Parser { } } - pub fn parse(&mut self, crim: &mut Crimtag, src: &str ) -> Result<(),Box> { + pub fn parse(&mut self, src: &str ) -> Result> { let mut ll = Lexer::new( src ); let mut ctx = Context::new( ll ); // Parse the root of the file, the input context - self.p_input( &mut ctx )?; - - Ok(()) + self.p_input( &mut ctx ) } - fn p_input(&mut self, ctx: &mut Context ) -> Result<(), Box> { + fn p_input(&mut self, ctx: &mut Context ) -> Result> { + let mut children = Vec::new(); loop { if ctx.cur().is_none() { break; @@ -168,7 +168,7 @@ impl Parser { match ctx.cur().unwrap().symbol() { SymbolType::Text(_) => { /* Skip top level text */ } SymbolType::StartFlat => { - self.parse_tag( ctx ); + children.push( self.parse_tag( ctx )? ); } SymbolType::Error{..} => { return self.lex_error( &ctx.cur().unwrap() ); @@ -179,28 +179,57 @@ impl Parser { } ctx.next(); } - Ok(()) + Ok(Token::Root(children)) } - fn parse_tag(&mut self, ctx: &mut Context) -> Result<(), Box> { + fn parse_tag(&mut self, ctx: &mut Context) -> Result> { let mut tb = TagBuilder::new(); + + println!("--> Begin parse_tag <--"); let start_sym = ctx.cur().unwrap(); + println!("--> Start sym: {:?}", start_sym ); + if ctx.next().is_some() { - if let SymbolType::Token(s) = ctx.next().unwrap().symbol() { - tb.set_name( s.to_string() ); - } else { - return Err(Box::new(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()})); + match ctx.cur().unwrap().symbol() { + SymbolType::Fragment | SymbolType::Section | + 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()})); + } } } else { return Err(Box::new(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 <--"); - Ok(()) + println!("---> {:?}", ctx.cur() ); + if let Some(end_sym) = ctx.cur() { + match end_sym.symbol() { + SymbolType::EndPoint => { + tb.set_type( TagType::BinaryOpen ); + } + SymbolType::EndFlat => { + tb.set_type( TagType::Unary ); + } + _ => { + return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); + } + } + } + + tb.build() } fn parse_tag_params(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<(), Box> { @@ -209,15 +238,13 @@ impl Parser { return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); } - if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { - if let Some(p) = ctx.peek() { - if p.check_type(|t| matches!(t, SymbolType::Equals)) { - break; - } - } - else { + match ctx.cur().unwrap().symbol() { + SymbolType::Literal(s) => { tb.add_param( s.to_string() ); } + _ => { + break; + } } ctx.next(); } @@ -250,6 +277,7 @@ impl Parser { } } +#[derive(PartialEq)] enum TagType { Unknown, Unary, @@ -257,36 +285,86 @@ enum TagType { BinaryClose, } -struct TagBuilder { - name: String, +struct TagBuilder<'a> { + name: Option>, params: Vec, - props: Vec<(String,String)>, + props: Properties, + children: Vec, tag_type: TagType, } -impl TagBuilder { - pub fn new() -> TagBuilder { +impl<'a> TagBuilder<'a> { + pub fn new() -> TagBuilder<'a> { TagBuilder { - name: String::new(), + name: None, params: Vec::new(), - props: Vec::new(), + props: Properties::new(), + children: Vec::new(), tag_type: TagType::Unknown, } } - pub fn set_name(&mut self, name: String) { - self.name = name; + pub fn has_children(&self) -> bool { + if self.tag_type == TagType::BinaryOpen { + true + } else { + false + } + } + + pub fn is_same_name(&self, name: Symbol<'a>) -> bool { + if let Some(a) = self.name { + a.symbol() == name.symbol() + } else { + false + } + } + + pub fn set_name(&mut self, name: Symbol<'a>) { + self.name = Some(name); + println!("Tag name: {:?}", self.name ); } pub fn add_param(&mut self, param: String) { + println!("Add param: {:?}", param ); self.params.push( param ); } pub fn add_prop(&mut self, key: String, value: String) { - self.props.push( (key, value) ); + println!("Add prop: {:?} = {:?}", key, value ); + self.props.insert( key, value ); + } + + pub fn add_child(&mut self, token: Token) { + self.children.push( token ); } pub fn set_type(&mut self, tag_type: TagType) { self.tag_type = tag_type; } + + pub fn build(mut self) -> Result> { + 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)) + } + _ => { + println!("Unkown tag type"); + Err(Box::new(ParseError { + position: Position::new(0,0), + what: "Bad tag type".to_string(), + })) + } + } + } else { + Err(Box::new(ParseError { + position: Position::new(0,0), + what: "Bad tag type".to_string(), + })) + } + } } -- cgit v1.2.3