From 10b91f6a312b9caf3fadd127c20a708c503d359d Mon Sep 17 00:00:00 2001 From: Yuheng Chen Date: Fri, 29 May 2015 02:57:41 +0800 Subject: [PATCH] Add scan_tag_directive_value --- parser/src/parser.rs | 9 ++++---- parser/src/scanner.rs | 49 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/parser/src/parser.rs b/parser/src/parser.rs index fcbf37c..b2a35cb 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -291,7 +291,7 @@ impl> Parser { return Ok(Event::StreamEnd); }, TokenType::VersionDirectiveToken(..) - | TokenType::TagDirectiveToken + | TokenType::TagDirectiveToken(..) | TokenType::DocumentStartToken => { // explicit document self._explict_document_start() @@ -320,8 +320,9 @@ impl> Parser { // "found incompatible YAML document")); //} }, - TokenType::TagDirectiveToken => { - unimplemented!(); + TokenType::TagDirectiveToken(..) => { + // unimplemented!(); + // TODO add tag directive }, _ => break } @@ -347,7 +348,7 @@ impl> Parser { let tok = try!(self.peek()); match tok.1 { TokenType::VersionDirectiveToken(..) - |TokenType::TagDirectiveToken + |TokenType::TagDirectiveToken(..) |TokenType::DocumentStartToken |TokenType::DocumentEndToken |TokenType::StreamEndToken => { diff --git a/parser/src/scanner.rs b/parser/src/scanner.rs index ddec711..94b2639 100644 --- a/parser/src/scanner.rs +++ b/parser/src/scanner.rs @@ -56,7 +56,8 @@ pub enum TokenType { StreamEndToken, /// major, minor VersionDirectiveToken(u32, u32), - TagDirectiveToken, + /// handle, prefix + TagDirectiveToken(String, String), DocumentStartToken, DocumentEndToken, BlockSequenceStartToken, @@ -72,7 +73,7 @@ pub enum TokenType { ValueToken, AliasToken(String), AnchorToken(String), - // handle, suffix + /// handle, suffix TagToken(String, String), ScalarToken(TScalarStyle, String) } @@ -497,6 +498,7 @@ impl> Scanner { "TAG" => { try!(self.scan_tag_directive_value(&start_mark)) }, + // XXX This should be a warning instead of an error _ => return Err(ScanError::new(start_mark, "while scanning a directive, found uknown directive name")) }; @@ -597,7 +599,32 @@ impl> Scanner { } fn scan_tag_directive_value(&mut self, mark: &Marker) -> Result { - unimplemented!(); + self.lookahead(1); + /* Eat whitespaces. */ + while is_blank(self.ch()) { + self.skip(); + self.lookahead(1); + } + let handle = try!(self.scan_tag_handle(true, mark)); + + self.lookahead(1); + /* Eat whitespaces. */ + while is_blank(self.ch()) { + self.skip(); + self.lookahead(1); + } + + let is_secondary = handle == "!!"; + let prefix = try!(self.scan_tag_uri(true, is_secondary, &String::new(), mark)); + + self.lookahead(1); + + if !is_blankz(self.ch()) { + Err(ScanError::new(*mark, + "while scanning TAG, did not find expected whitespace or line break")) + } else { + Ok(Token(*mark, TokenType::TagDirectiveToken(handle, prefix))) + } } fn fetch_tag(&mut self) -> ScanResult { @@ -612,7 +639,7 @@ impl> Scanner { fn scan_tag(&mut self) -> Result { let start_mark = self.mark; let mut handle = String::new(); - let mut suffix = String::new(); + let mut suffix; let mut secondary = false; // Check if the tag is in the canonical form (verbatim). @@ -715,8 +742,8 @@ impl> Scanner { * '%'. */ while match self.ch() { - ';' | '/' | '?' | ':' | '@' | '&' if !is_secondary => true, - '=' | '+' | '$' | ',' | '.' | '!' | '~' | '*' | '\'' | '(' | ')' | '[' | ']' if !is_secondary => true, + ';' | '/' | '?' | ':' | '@' | '&' => true, + '=' | '+' | '$' | ',' | '.' | '!' | '~' | '*' | '\'' | '(' | ')' | '[' | ']' => true, '%' => true, c if is_alpha(c) => true, _ => false @@ -1853,5 +1880,15 @@ key: next!(p, StreamEndToken); end!(p); } + + #[test] + fn test_uri() { + // TODO + } + + #[test] + fn test_uri_escapes() { + // TODO + } }