OSDN Git Service

-- delimiterの各実装の作成を開始。
authorderui <derutakayu@user.sourceforge.jp>
Sat, 13 Jun 2009 01:53:48 +0000 (10:53 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Sat, 13 Jun 2009 01:53:48 +0000 (10:53 +0900)
delimiter.h
delimiter_impl.cpp
delimiter_impl.h
sublexer_impl.cpp

index 132aa04..fcdd34e 100644 (file)
@@ -3,9 +3,9 @@
 
 namespace utakata {
 
-    namespace utf8_string {
+    namespace utf8 {
     
-        class UTF8Char;
+        class UTF8InputStream;
     
     };
 
@@ -18,8 +18,11 @@ namespace utakata {
         public:
             virtual ~IDelimiter() {}
 
-            // 渡した文字がデリミタであるかどうかを返す。
-            virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch) = 0;
+            // ストリームから一文字読みだし、読みだした文字がデリミタ
+            // であるかどうかを返す。
+            // デリミタである場合には、デリミタ分は捨てられる。
+            virtual bool isDelimiter(utakata::utf8::UTF8InputStream& strm) = 0;
+
         };
     
     };
index 0bcb4c4..d9ca5d4 100644 (file)
@@ -50,7 +50,21 @@ bool WhitespaceDelimiter::isDelimiter(const UTF8Char& ch)
 {
     // 渡された文字がデリミタかどうかを判別する。
     // ここで判別するのは空白文字か否かという点である。
-
+    switch (ch.toUTF16Code())
+    {
+        // 実際には、改行を判定するわけではない。
+        // 改行かどうかを見るためには、次の文字までを見なければ
+        // 不明であるため。
+    case '\r':                  // carriage return 復帰
+    case '\n':                  // linefeed  改行
+    case ' ':                   // space 空白
+    case '\t':                  // tab タブ
+    case '\v':                  // vertical tab 垂直タブ
+    case '\f':                  // page 改ページ
+    default:
+        return false;
+    }        
+        
     return true;
 }
 
index 76fc1d5..eac38ae 100644 (file)
@@ -4,12 +4,14 @@
 #include "delimiter.h"
 #include "smart_ptr.h"
 #include "utf8_string.h"
+#include "utf8.h"
 
 
 namespace utakata {
 
     namespace sublexer {
-    
+
+        class StreamPeeker;
         class NormalDelimiter : public IDelimiter
         {
         public:
@@ -34,7 +36,21 @@ namespace utakata {
 
             virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch);
         };
-    
+
+        //================================================================================
+
+        template<class T>
+        class StreamPeeker
+        {
+        public:
+            virtual ~StreamPeeker() {}
+
+            template<class S>
+            virtual T operator()(S strm) {
+                return strm->peek();
+            }
+        };
+        
     };
 
 };
index 96bba17..02a31f2 100644 (file)
@@ -26,46 +26,40 @@ smart_ptr<sublexer::ISubLexer> sublexer::FirstLexer::lex(smart_ptr<utf8::UTF8Inp
         // 読出した文字がデリミタであり、lexemeが確定していない場合に
         // は、そのまま続けて読出すことにする。
         UTF8Char ch(stream->read());
-        if (delimiter_->isDelimiter(ch)) {
+        if (str.size() == 0 && delimiter_->isDelimiter(ch)) {
             continue;
         }
         
-        str += stream->read();
+        str += ch;
         // ()[]`'が最初だった場合、さっさと消えることにする。
         if (str[0].toUTF16Code() == '(' || str[0].toUTF16Code() == '[')
         {
             lexeme_ = lexeme::makeOpenParen();
         }
-
-        if (str[0].toUTF16Code() == ')' || str[0].toUTF16Code() == ']')
+        else if (str[0].toUTF16Code() == ')' || str[0].toUTF16Code() == ']')
         {
             lexeme_ = lexeme::makeCloseParen();
         }
-
-        if (str[0].toUTF16Code() == '`')
+        else if (str[0].toUTF16Code() == '`')
         {
             lexeme_ = lexeme::makeBackQuote();
         }
-
-        if (str[0].toUTF16Code() == '\'')
+        else if (str[0].toUTF16Code() == '\'')
         {
             lexeme_ = lexeme::makeQuote();
         }
-
-        if (str[0].toUTF16Code() == '.')
+        else if (str[0].toUTF16Code() == '.')
         {
             // 次の文字がデリミタで終了していなければならない。
             lexeme_ = lexeme::makeDot();
         }
-
-        if (str[0].toUTF16Code() == ',' || str[0].toUTF16Code() == '#')
+        else if (str[0].toUTF16Code() == ',' || str[0].toUTF16Code() == '#')
         {
             // 最初の一文字だけでは判別できないため、一文字先読みして
             // から決定する。
             
         }
-
-        if (str[0].toUTF16Code() == '"')
+        else if (str[0].toUTF16Code() == '"')
         {
             // 先頭が"の場合、stringと判断される。
             ret.add(new sublexer::StringLexer());