diff options
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 57 |
1 files changed, 28 insertions, 29 deletions
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 { | |||
| 17 | what: what.to_string(), | 17 | what: what.to_string(), |
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | |||
| 21 | pub fn eos( context: &str ) -> Self { | ||
| 22 | ParseError { | ||
| 23 | position: Position::none(), | ||
| 24 | what: format!("Premature end of stream while looking for {}", context), | ||
| 25 | } | ||
| 26 | } | ||
| 20 | } | 27 | } |
| 21 | 28 | ||
| 22 | impl fmt::Display for ParseError { | 29 | impl fmt::Display for ParseError { |
| @@ -61,12 +68,9 @@ impl<'a> Context<'a> { | |||
| 61 | self.cur[(self.icur+1)%2] | 68 | self.cur[(self.icur+1)%2] |
| 62 | } | 69 | } |
| 63 | 70 | ||
| 64 | pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, f: T) -> ParseResult<bool> { | 71 | pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> ParseResult<bool> { |
| 65 | if self.cur().is_none() || self.peek().is_none() { | 72 | if self.cur().is_none() || self.peek().is_none() { |
| 66 | Err(ParseError{ | 73 | Err(ParseError::eos( context )) |
| 67 | position: Position::new(0,0), | ||
| 68 | what: "Unexpected end of stream.".to_string() | ||
| 69 | }) | ||
| 70 | } else { | 74 | } else { |
| 71 | Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) | 75 | Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) |
| 72 | } | 76 | } |
| @@ -74,19 +78,16 @@ impl<'a> Context<'a> { | |||
| 74 | } | 78 | } |
| 75 | 79 | ||
| 76 | trait SymbolHelper { | 80 | trait SymbolHelper { |
| 77 | fn is<T: Fn( &SymbolType ) -> bool>(&self, f: T ) -> ParseResult<bool>; | 81 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool>; |
| 78 | fn is_valid_tag_name(&self) -> ParseResult<bool>; | 82 | fn is_valid_tag_name(&self) -> ParseResult<bool>; |
| 79 | } | 83 | } |
| 80 | 84 | ||
| 81 | impl<'a> SymbolHelper for Option<Symbol<'a>> { | 85 | impl<'a> SymbolHelper for Option<Symbol<'a>> { |
| 82 | fn is<T: Fn( &SymbolType ) -> bool>(&self, f: T ) -> ParseResult<bool> { | 86 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool> { |
| 83 | if let Some(st) = self { | 87 | if let Some(st) = self { |
| 84 | Ok(f( &st.symbol() )) | 88 | Ok(f( &st.symbol() )) |
| 85 | } else { | 89 | } else { |
| 86 | Err(ParseError{ | 90 | Err(ParseError::eos( context )) |
| 87 | position: Position::new(0,0), | ||
| 88 | what: "Unexpected end of stream.".to_string() | ||
| 89 | }) | ||
| 90 | } | 91 | } |
| 91 | } | 92 | } |
| 92 | 93 | ||
| @@ -256,10 +257,7 @@ impl Parser { | |||
| 256 | //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); | 257 | //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); |
| 257 | loop { | 258 | loop { |
| 258 | if ctx.cur().is_none() { | 259 | if ctx.cur().is_none() { |
| 259 | return Err(ParseError{ | 260 | return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())) |
| 260 | position: Position::new(0,0), | ||
| 261 | what: "Unexpected end of stream.".to_string() | ||
| 262 | }); | ||
| 263 | } | 261 | } |
| 264 | match ctx.cur().unwrap().symbol() { | 262 | match ctx.cur().unwrap().symbol() { |
| 265 | SymbolType::Text(s) => { | 263 | SymbolType::Text(s) => { |
| @@ -282,7 +280,7 @@ impl Parser { | |||
| 282 | // Everything is either text or output | 280 | // Everything is either text or output |
| 283 | if !any_outputs { | 281 | if !any_outputs { |
| 284 | // Special case, if it's only text then we create an implicit output. | 282 | // Special case, if it's only text then we create an implicit output. |
| 285 | tb.add_child(Token::Output("content".to_string(), Properties::new(), children )); | 283 | tb.add_child(Token::Output("content".to_string(), /*Properties::new(),*/ children )); |
| 286 | } | 284 | } |
| 287 | else { | 285 | else { |
| 288 | // Standard case, outputs are included, text is | 286 | // Standard case, outputs are included, text is |
| @@ -303,7 +301,7 @@ impl Parser { | |||
| 303 | }); | 301 | }); |
| 304 | } else { | 302 | } else { |
| 305 | // No outputs at all, we create an implict output | 303 | // No outputs at all, we create an implict output |
| 306 | tb.add_child(Token::Output("content".to_string(), Properties::new(), children )); | 304 | tb.add_child(Token::Output("content".to_string(), /*Properties::new(), */children )); |
| 307 | } | 305 | } |
| 308 | } | 306 | } |
| 309 | 307 | ||
| @@ -339,11 +337,11 @@ impl Parser { | |||
| 339 | tb.set_name( name_sym ); | 337 | tb.set_name( name_sym ); |
| 340 | } | 338 | } |
| 341 | _ => { | 339 | _ => { |
| 342 | return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()}); | 340 | return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpected symbol".to_string()}); |
| 343 | } | 341 | } |
| 344 | } | 342 | } |
| 345 | } else { | 343 | } else { |
| 346 | return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); | 344 | return Err(ParseError::eos("tag type")); |
| 347 | } | 345 | } |
| 348 | 346 | ||
| 349 | self.parse_tag_params( ctx, &mut tb )?; | 347 | self.parse_tag_params( ctx, &mut tb )?; |
| @@ -358,7 +356,10 @@ impl Parser { | |||
| 358 | tb.set_type( TagType::Unary ); | 356 | tb.set_type( TagType::Unary ); |
| 359 | } | 357 | } |
| 360 | _ => { | 358 | _ => { |
| 361 | return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); | 359 | return Err(ParseError::new( |
| 360 | end_sym.start().clone(), | ||
| 361 | format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()).as_str() | ||
| 362 | )); | ||
| 362 | } | 363 | } |
| 363 | } | 364 | } |
| 364 | } | 365 | } |
| @@ -369,7 +370,7 @@ impl Parser { | |||
| 369 | } | 370 | } |
| 370 | 371 | ||
| 371 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<Symbol<'a>> { | 372 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<Symbol<'a>> { |
| 372 | if !ctx.cur().is(|s| *s == SymbolType::StartPoint )? { | 373 | if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { |
| 373 | return Err(ParseError{ | 374 | return Err(ParseError{ |
| 374 | position: *ctx.cur().unwrap().start(), | 375 | position: *ctx.cur().unwrap().start(), |
| 375 | what: "Invalid end tag?".to_string(), | 376 | what: "Invalid end tag?".to_string(), |
| @@ -382,7 +383,7 @@ impl Parser { | |||
| 382 | }); | 383 | }); |
| 383 | } | 384 | } |
| 384 | let name = ctx.cur().unwrap(); | 385 | let name = ctx.cur().unwrap(); |
| 385 | if !ctx.next().is(|s| *s == SymbolType::EndFlat )? { | 386 | if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { |
| 386 | return Err(ParseError{ | 387 | return Err(ParseError{ |
| 387 | position: *ctx.cur().unwrap().start(), | 388 | position: *ctx.cur().unwrap().start(), |
| 388 | what: "Tag should be <| |] style end tag.".to_string(), | 389 | what: "Tag should be <| |] style end tag.".to_string(), |
| @@ -399,7 +400,7 @@ impl Parser { | |||
| 399 | 400 | ||
| 400 | loop { | 401 | loop { |
| 401 | if ctx.cur().is_none() { | 402 | if ctx.cur().is_none() { |
| 402 | return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); | 403 | return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())); |
| 403 | } | 404 | } |
| 404 | match ctx.cur().unwrap().symbol() { | 405 | match ctx.cur().unwrap().symbol() { |
| 405 | SymbolType::Text(s) => { | 406 | SymbolType::Text(s) => { |
| @@ -435,8 +436,7 @@ impl Parser { | |||
| 435 | fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { | 436 | fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { |
| 436 | loop { | 437 | loop { |
| 437 | if ctx.cur().is_none() { | 438 | if ctx.cur().is_none() { |
| 438 | 439 | return Err(ParseError::eos("tag parameters")); | |
| 439 | return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); | ||
| 440 | } | 440 | } |
| 441 | match ctx.cur().unwrap().symbol() { | 441 | match ctx.cur().unwrap().symbol() { |
| 442 | SymbolType::Literal(s) => { | 442 | SymbolType::Literal(s) => { |
| @@ -454,7 +454,7 @@ impl Parser { | |||
| 454 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { | 454 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { |
| 455 | loop { | 455 | loop { |
| 456 | if ctx.cur().is_none() { | 456 | if ctx.cur().is_none() { |
| 457 | return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()}); | 457 | return Err(ParseError::eos("tag properties")); |
| 458 | } | 458 | } |
| 459 | if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { | 459 | if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { |
| 460 | if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { | 460 | if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { |
| @@ -466,7 +466,7 @@ impl Parser { | |||
| 466 | return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); | 466 | return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); |
| 467 | } | 467 | } |
| 468 | } else { | 468 | } else { |
| 469 | return Err(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()}); | 469 | break; |
| 470 | } | 470 | } |
| 471 | } else { | 471 | } else { |
| 472 | break; | 472 | break; |
| @@ -482,7 +482,6 @@ enum TagType { | |||
| 482 | Unknown, | 482 | Unknown, |
| 483 | Unary, | 483 | Unary, |
| 484 | BinaryOpen, | 484 | BinaryOpen, |
| 485 | BinaryClose, | ||
| 486 | } | 485 | } |
| 487 | 486 | ||
| 488 | struct TagBuilder<'a> { | 487 | struct TagBuilder<'a> { |
| @@ -573,7 +572,7 @@ impl<'a> TagBuilder<'a> { | |||
| 573 | Ok(Token::View(self.params.swap_remove(0), self.props, self.children)) | 572 | Ok(Token::View(self.params.swap_remove(0), self.props, self.children)) |
| 574 | } | 573 | } |
| 575 | SymbolType::Output => { | 574 | SymbolType::Output => { |
| 576 | Ok(Token::Output(self.params.swap_remove(0), self.props, self.children)) | 575 | Ok(Token::Output(self.params.swap_remove(0), /*self.props,*/ self.children)) |
| 577 | } | 576 | } |
| 578 | SymbolType::Show => { | 577 | SymbolType::Show => { |
| 579 | Ok(Token::Show(self.params.swap_remove(0), self.props)) | 578 | Ok(Token::Show(self.params.swap_remove(0), self.props)) |
