diff options
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/src/parser.rs b/src/parser.rs index 83144fb..be5492c 100644 --- a/src/parser.rs +++ b/src/parser.rs | |||
| @@ -76,7 +76,7 @@ impl<'a> SymbolHelper for Option<Symbol<'a>> { | |||
| 76 | _ => false | 76 | _ => false |
| 77 | }) | 77 | }) |
| 78 | } else { | 78 | } else { |
| 79 | Err(CrimError::new( | 79 | Err(CrimError::parse( |
| 80 | Position::none(), | 80 | Position::none(), |
| 81 | "Unexpeceted end of stream.".to_string() | 81 | "Unexpeceted end of stream.".to_string() |
| 82 | )) | 82 | )) |
| @@ -172,11 +172,11 @@ impl Parser { | |||
| 172 | 172 | ||
| 173 | fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> { | 173 | fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> { |
| 174 | if let SymbolType::Error{what} = error.symbol() { | 174 | if let SymbolType::Error{what} = error.symbol() { |
| 175 | Err(CrimError::new( *error.start(), | 175 | Err(CrimError::parse( *error.start(), |
| 176 | format!("What: {:?}", *what) | 176 | format!("What: {:?}", *what) |
| 177 | )) | 177 | )) |
| 178 | } else { | 178 | } else { |
| 179 | Err(CrimError::new( Position::none(), "Not an error?".into())) | 179 | Err(CrimError::parse( Position::none(), "Not an error?".into())) |
| 180 | } | 180 | } |
| 181 | } | 181 | } |
| 182 | 182 | ||
| @@ -214,7 +214,7 @@ impl Parser { | |||
| 214 | fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> { | 214 | fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> { |
| 215 | let tb = self.parse_open_tag( ctx )?; | 215 | let tb = self.parse_open_tag( ctx )?; |
| 216 | if !tb.is_name( &SymbolType::View ) { | 216 | if !tb.is_name( &SymbolType::View ) { |
| 217 | return Err(CrimError::new(tb.start_pos(), | 217 | return Err(CrimError::parse(tb.start_pos(), |
| 218 | "Unexpected tag type, only frament allowed at root".into() | 218 | "Unexpected tag type, only frament allowed at root".into() |
| 219 | )); | 219 | )); |
| 220 | } | 220 | } |
| @@ -260,7 +260,7 @@ impl Parser { | |||
| 260 | }); | 260 | }); |
| 261 | } else { | 261 | } else { |
| 262 | if !all_text { | 262 | if !all_text { |
| 263 | return Err(CrimError::new( | 263 | return Err(CrimError::parse( |
| 264 | *end.start(), | 264 | *end.start(), |
| 265 | "You cannot mix non-output and output tags in a view.".to_string() | 265 | "You cannot mix non-output and output tags in a view.".to_string() |
| 266 | )); | 266 | )); |
| @@ -269,7 +269,7 @@ impl Parser { | |||
| 269 | return tb.build_view(ctx,outputs); | 269 | return tb.build_view(ctx,outputs); |
| 270 | } else { | 270 | } else { |
| 271 | // They don't match, complain. | 271 | // They don't match, complain. |
| 272 | return Err(CrimError::new( | 272 | return Err(CrimError::parse( |
| 273 | *end.start(), | 273 | *end.start(), |
| 274 | "Mismatched open and closing tags.".to_string() | 274 | "Mismatched open and closing tags.".to_string() |
| 275 | )); | 275 | )); |
| @@ -279,7 +279,7 @@ impl Parser { | |||
| 279 | return self.lex_error( &ctx.cur().unwrap() ); | 279 | return self.lex_error( &ctx.cur().unwrap() ); |
| 280 | } | 280 | } |
| 281 | _ => { | 281 | _ => { |
| 282 | return Err(CrimError::new( | 282 | return Err(CrimError::parse( |
| 283 | *ctx.cur().unwrap().start(), | 283 | *ctx.cur().unwrap().start(), |
| 284 | format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) | 284 | format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) |
| 285 | )); | 285 | )); |
| @@ -302,7 +302,7 @@ impl Parser { | |||
| 302 | tb.set_name( name_sym ); | 302 | tb.set_name( name_sym ); |
| 303 | } | 303 | } |
| 304 | _ => { | 304 | _ => { |
| 305 | return Err(CrimError::new( | 305 | return Err(CrimError::parse( |
| 306 | *ctx.cur().unwrap().start(), | 306 | *ctx.cur().unwrap().start(), |
| 307 | "Unexpected symbol".to_string() | 307 | "Unexpected symbol".to_string() |
| 308 | )); | 308 | )); |
| @@ -318,13 +318,13 @@ impl Parser { | |||
| 318 | if let Some(end_sym) = ctx.cur() { | 318 | if let Some(end_sym) = ctx.cur() { |
| 319 | match end_sym.symbol() { | 319 | match end_sym.symbol() { |
| 320 | SymbolType::EndPoint => { | 320 | SymbolType::EndPoint => { |
| 321 | tb.set_type( TagType::BinaryOpen ); | 321 | tb.set_type( TagType::MultinaryOpen ); |
| 322 | } | 322 | } |
| 323 | SymbolType::EndFlat => { | 323 | SymbolType::EndFlat => { |
| 324 | tb.set_type( TagType::Unary ); | 324 | tb.set_type( TagType::Unary ); |
| 325 | } | 325 | } |
| 326 | _ => { | 326 | _ => { |
| 327 | return Err(CrimError::new( | 327 | return Err(CrimError::parse( |
| 328 | *end_sym.start(), | 328 | *end_sym.start(), |
| 329 | format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) | 329 | format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) |
| 330 | )); | 330 | )); |
| @@ -339,20 +339,20 @@ impl Parser { | |||
| 339 | 339 | ||
| 340 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> { | 340 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> { |
| 341 | if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { | 341 | if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { |
| 342 | return Err(CrimError::new( | 342 | return Err(CrimError::parse( |
| 343 | *ctx.cur().unwrap().start(), | 343 | *ctx.cur().unwrap().start(), |
| 344 | "Invalid end tag?".to_string() | 344 | "Invalid end tag?".to_string() |
| 345 | )); | 345 | )); |
| 346 | } | 346 | } |
| 347 | if !ctx.next().is_valid_tag_name()? { | 347 | if !ctx.next().is_valid_tag_name()? { |
| 348 | return Err(CrimError::new( | 348 | return Err(CrimError::parse( |
| 349 | *ctx.cur().unwrap().start(), | 349 | *ctx.cur().unwrap().start(), |
| 350 | "Invalid tag name".to_string() | 350 | "Invalid tag name".to_string() |
| 351 | )); | 351 | )); |
| 352 | } | 352 | } |
| 353 | let name = ctx.cur().unwrap(); | 353 | let name = ctx.cur().unwrap(); |
| 354 | if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { | 354 | if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { |
| 355 | return Err(CrimError::new( | 355 | return Err(CrimError::parse( |
| 356 | *ctx.cur().unwrap().start(), | 356 | *ctx.cur().unwrap().start(), |
| 357 | "Tag should be <| |] style end tag.".to_string(), | 357 | "Tag should be <| |] style end tag.".to_string(), |
| 358 | )); | 358 | )); |
| @@ -386,7 +386,7 @@ impl Parser { | |||
| 386 | return Ok(tb); | 386 | return Ok(tb); |
| 387 | } else { | 387 | } else { |
| 388 | // They don't match, complain. | 388 | // They don't match, complain. |
| 389 | return Err(CrimError::new( | 389 | return Err(CrimError::parse( |
| 390 | *end.start(), | 390 | *end.start(), |
| 391 | "Mismatched open and closing tags.".to_string() | 391 | "Mismatched open and closing tags.".to_string() |
| 392 | )); | 392 | )); |
| @@ -396,7 +396,7 @@ impl Parser { | |||
| 396 | return self.lex_error( &ctx.cur().unwrap() ); | 396 | return self.lex_error( &ctx.cur().unwrap() ); |
| 397 | } | 397 | } |
| 398 | _ => { | 398 | _ => { |
| 399 | return Err(CrimError::new( | 399 | return Err(CrimError::parse( |
| 400 | *ctx.cur().unwrap().start(), | 400 | *ctx.cur().unwrap().start(), |
| 401 | format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), | 401 | format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), |
| 402 | )); | 402 | )); |
| @@ -438,7 +438,7 @@ impl Parser { | |||
| 438 | id.push( IdentifierValue::Name(s.to_string()) ); | 438 | id.push( IdentifierValue::Name(s.to_string()) ); |
| 439 | } | 439 | } |
| 440 | } else { | 440 | } else { |
| 441 | return Err(CrimError::new( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); | 441 | return Err(CrimError::parse( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { | 444 | if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { |
| @@ -462,7 +462,7 @@ impl Parser { | |||
| 462 | let SymbolType::Literal(lv) = sym.symbol() { | 462 | let SymbolType::Literal(lv) = sym.symbol() { |
| 463 | tb.add_prop( s.to_string(), lv.to_string() ); | 463 | tb.add_prop( s.to_string(), lv.to_string() ); |
| 464 | } else { | 464 | } else { |
| 465 | return Err(CrimError::new(Position::none(),"Expected quoted literal string".to_string())); | 465 | return Err(CrimError::parse(Position::none(),"Expected quoted literal string".to_string())); |
| 466 | } | 466 | } |
| 467 | } else { | 467 | } else { |
| 468 | break; | 468 | break; |
| @@ -480,7 +480,8 @@ impl Parser { | |||
| 480 | enum TagType { | 480 | enum TagType { |
| 481 | Unknown, | 481 | Unknown, |
| 482 | Unary, | 482 | Unary, |
| 483 | BinaryOpen, | 483 | MultinaryOpen, |
| 484 | MultinaryMid, | ||
| 484 | } | 485 | } |
| 485 | 486 | ||
| 486 | struct TagBuilder<'a> { | 487 | struct TagBuilder<'a> { |
| @@ -523,7 +524,8 @@ impl<'a> TagBuilder<'a> { | |||
| 523 | } | 524 | } |
| 524 | 525 | ||
| 525 | pub fn can_have_children(&self) -> bool { | 526 | pub fn can_have_children(&self) -> bool { |
| 526 | if self.tag_type == TagType::BinaryOpen { | 527 | if self.tag_type == TagType::MultinaryOpen || |
| 528 | self.tag_type == TagType::MultinaryMid { | ||
| 527 | true | 529 | true |
| 528 | } else { | 530 | } else { |
| 529 | false | 531 | false |
| @@ -580,7 +582,7 @@ impl<'a> TagBuilder<'a> { | |||
| 580 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | 582 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { |
| 581 | s.to_string() | 583 | s.to_string() |
| 582 | } else { | 584 | } else { |
| 583 | return Err(CrimError::new(Position::none(), "Expected string literal for view name.".to_string())); | 585 | return Err(CrimError::parse(Position::none(), "Expected string literal for view name.".to_string())); |
| 584 | }; | 586 | }; |
| 585 | Ok(View { | 587 | Ok(View { |
| 586 | name: name, | 588 | name: name, |
| @@ -590,10 +592,10 @@ impl<'a> TagBuilder<'a> { | |||
| 590 | layout: self.props.get("layout").cloned(), | 592 | layout: self.props.get("layout").cloned(), |
| 591 | }) | 593 | }) |
| 592 | } else { | 594 | } else { |
| 593 | Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) | 595 | Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) |
| 594 | } | 596 | } |
| 595 | } else { | 597 | } else { |
| 596 | Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) | 598 | Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) |
| 597 | } | 599 | } |
| 598 | } | 600 | } |
| 599 | 601 | ||
| @@ -603,17 +605,17 @@ impl<'a> TagBuilder<'a> { | |||
| 603 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | 605 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { |
| 604 | s.to_string() | 606 | s.to_string() |
| 605 | } else { | 607 | } else { |
| 606 | return Err(CrimError::new(Position::none(), "Expected string literal for output name.".into())); | 608 | return Err(CrimError::parse(Position::none(), "Expected string literal for output name.".into())); |
| 607 | }; | 609 | }; |
| 608 | Ok(Output { | 610 | Ok(Output { |
| 609 | name: name, | 611 | name: name, |
| 610 | code: self.children, | 612 | code: self.children, |
| 611 | }) | 613 | }) |
| 612 | } else { | 614 | } else { |
| 613 | Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) | 615 | Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) |
| 614 | } | 616 | } |
| 615 | } else { | 617 | } else { |
| 616 | Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".into())) | 618 | Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".into())) |
| 617 | } | 619 | } |
| 618 | } | 620 | } |
| 619 | 621 | ||
| @@ -624,7 +626,7 @@ impl<'a> TagBuilder<'a> { | |||
| 624 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { | 626 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { |
| 625 | id | 627 | id |
| 626 | } else { | 628 | } else { |
| 627 | return Err(CrimError::new(Position::none(), "Identifier for loop variable name.".into())); | 629 | return Err(CrimError::parse(Position::none(), "Identifier for loop variable name.".into())); |
| 628 | }; | 630 | }; |
| 629 | Ok(Token::Loop(id, self.children)) | 631 | Ok(Token::Loop(id, self.children)) |
| 630 | } | 632 | } |
| @@ -632,16 +634,16 @@ impl<'a> TagBuilder<'a> { | |||
| 632 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { | 634 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { |
| 633 | id | 635 | id |
| 634 | } else { | 636 | } else { |
| 635 | return Err(CrimError::new(Position::none(), "Identifier for show variable name.".into())); | 637 | return Err(CrimError::parse(Position::none(), "Identifier for show variable name.".into())); |
| 636 | }; | 638 | }; |
| 637 | Ok(Token::Show(id, self.props)) | 639 | Ok(Token::Show(id, self.props)) |
| 638 | } | 640 | } |
| 639 | _ => { | 641 | _ => { |
| 640 | Err(CrimError::new( self.start_pos, "Bad tag type".into())) | 642 | Err(CrimError::parse( self.start_pos, "Bad tag type".into())) |
| 641 | } | 643 | } |
| 642 | } | 644 | } |
| 643 | } else { | 645 | } else { |
| 644 | Err(CrimError::new(self.start_pos, "Bad tag type".into())) | 646 | Err(CrimError::parse(self.start_pos, "Bad tag type".into())) |
| 645 | } | 647 | } |
| 646 | } | 648 | } |
| 647 | } | 649 | } |
