OSDN Git Service

CommentLexerの内部を実装した。<lexeme>内の終端記号以外の実装を完了した。
[simplecms/utakata.git] / src / lexer / comment_lexer.cpp
index f76df95..f3cad0b 100755 (executable)
@@ -14,6 +14,34 @@ namespace term = utakata::lexer::term;
 namespace unicode = utakata::unicode;
 
 // 宣言のコメントを参照してください。
+bool lexer::detail::NestedLexer::Lex(reader::EncodingReader* reader) {
+  lexer::TermLexer<term::NestedCommentOpen> nested_open;
+  lexer::TermLexer<term::NestedCommentClose> nested_close;
+
+  if (!nested_open.CheckToken(reader)) {
+    return false;
+  }
+
+  reader->Read(nested_open.previous_read_size());
+  int nest_counter = 1;
+  while (!reader->IsEof() && nest_counter > 0) {
+    if (nested_open.CheckToken(reader)) {
+      reader->Read(nested_open.previous_read_size());
+      ++nest_counter;
+
+    } else if (nested_close.CheckToken(reader)) {
+      reader->Read(nested_close.previous_read_size());
+      --nest_counter;
+
+    } else {
+      reader->Read();
+    }
+  }
+
+  return true;
+}
+
+// 宣言のコメントを参照してください。
 lexer::Lexeme* lexer::CommentLexer::Lex(reader::EncodingReader* reader) {
   lexer::TermLexer<term::DatumComment> datum_comment;
   lexer::TermLexer<term::SpecialComment> special_comment;
@@ -23,13 +51,30 @@ lexer::Lexeme* lexer::CommentLexer::Lex(reader::EncodingReader* reader) {
     SkipByLineComment(reader);
 
   } else if (datum_comment.CheckToken(reader)) {
-    return lexer::Lexeme(unicode::UniString(), lexer::Lexeme::kDatumComment);
+    reader->Read(datum_comment.previous_read_size());
+    return new lexer::Lexeme(unicode::UniString(), lexer::Lexeme::kDatumComment);
+
   } else if (special_comment.CheckToken(reader)) {
-    reader->Read(special_comment.ReadToken(reader));
-    return lexer::Lexeme(unicode::UniString(), lexer::Lexeme::kSpecialComment);
+    reader->Read(special_comment.previous_read_size());
+    return new lexer::Lexeme(unicode::UniString(), lexer::Lexeme::kSpecialComment);
   } else {
     lexer::detail::NestedLexer().Lex(reader);
   }
 
   return NULL;
 }
+
+// ; の発見時点でこの関数が呼ばれるため、内部で先頭の一文字を
+// 読み飛ばしています。
+void lexer::CommentLexer::SkipByLineComment(reader::EncodingReader* reader) {
+  reader->Read();
+
+  lexer::TermLexer<term::LineEnding> line_ending;
+  while (!reader->IsEof()) {
+    if (line_ending.CheckToken(reader)) {
+      reader->Read(line_ending.previous_read_size());
+      break;
+    }
+    reader->Read();
+  }
+}