OSDN Git Service

-boolean、およびバイトベクタについて足りなかったため、実装した。
authorderui <derutakayu@user.sourceforge.jp>
Thu, 16 Jul 2009 14:56:48 +0000 (23:56 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Thu, 16 Jul 2009 14:56:48 +0000 (23:56 +0900)
lexeme_id.cpp [changed mode: 0644->0755]
lexeme_id.h [changed mode: 0644->0755]
lexeme_impl.cpp [changed mode: 0644->0755]
lexeme_impl.h [changed mode: 0644->0755]
parser.cpp [changed mode: 0644->0755]
parser.h [changed mode: 0644->0755]
sublexer_impl.cpp
sublexer_impl.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index e21de04..8232260
@@ -19,7 +19,8 @@ LexemeID::LexemeID() : openParenthesis(1),
                        unsyntaxSplicing(12),
                        identifier(13),
                        number(14),
-                       charactor(15)
+                       charactor(15),
+                       boolean(16)
 {
     // 全てのIDをここで記述する。
     // すべてconstなので、実際にはinitializerで初期化している。
old mode 100644 (file)
new mode 100755 (executable)
index dcc3b9d..93e86f6
@@ -53,6 +53,7 @@ namespace utakata {
             const int identifier;       // <identifier>
             const int number;           // <number>
             const int charactor;        // <charactor>
+            const int boolean;          // <boolean>
         };
 
     };
old mode 100644 (file)
new mode 100755 (executable)
index 57f76d2..a73dc25
@@ -58,6 +58,11 @@ smart_ptr<ILexeme> utakata::lexeme::makeUnquote()
     return smart_ptr<ILexeme>(new Unquote());
 }
 
+smart_ptr<ILexeme> utakata::lexeme::makeByteVector()
+{
+    return smart_ptr<ILexeme>(new ByteVector());
+}
+
 smart_ptr<ILexeme> utakata::lexeme::makeSyntax()
 {
     return smart_ptr<ILexeme>(new Syntax());
@@ -83,6 +88,11 @@ smart_ptr<ILexeme> utakata::lexeme::makeCharactor(const utakata::utf8_string::UT
     return smart_ptr<ILexeme>(new Charactor(str));
 }
 
+smart_ptr<ILexeme> utakata::lexeme::makeBoolean(const smart_ptr<utakata::utf8_string::UTF8Char>& ch)
+{
+    return smart_ptr<ILexeme>(new Boolean(ch));
+}
+
 smart_ptr<ILexeme> utakata::lexeme::makeNanImaginary(const utakata::utf8_string::UTF8String& str,
                                                      bool exact)
 {
@@ -228,6 +238,23 @@ smart_ptr<utakata::utf8_string::UTF8String> UnquoteSplicing::toString() const
     return p;
 }
 
+////////////////
+// ByteVector //
+////////////////
+
+int ByteVector::getID() const
+{
+    return IDProxy()->unquoteSplicing;
+}
+
+smart_ptr<utakata::utf8_string::UTF8String> ByteVector::toString() const
+{
+    smart_ptr<utakata::utf8_string::UTF8String> p(new utf8_string::UTF8String);
+    *p += std::string("#vu8(");
+    return p;
+}
+
+
 /////////////
 // Unquote //
 /////////////
@@ -382,3 +409,22 @@ smart_ptr<utakata::utf8_string::UTF8String> Charactor::toString() const
 {
     return ch_;
 }
+
+/////////////
+// Boolean //
+/////////////
+
+Boolean::Boolean(const smart_ptr<UTF8Char>& ch) : str_(new UTF8String())
+{
+    *str_ += *ch;
+}
+
+int Boolean::getID() const
+{
+    return IDProxy()->boolean;
+}
+
+smart_ptr<utakata::utf8_string::UTF8String> Boolean::toString() const
+{
+    return str_;
+}
old mode 100644 (file)
new mode 100755 (executable)
index 3bef58b..5597353
@@ -23,6 +23,7 @@ namespace utakata {
         smart_ptr<ILexeme> makeQuasiSyntax();
         smart_ptr<ILexeme> makeUnsyntaxSplicing();
         smart_ptr<ILexeme> makeUnsyntax();
+        smart_ptr<ILexeme> makeByteVector();
         smart_ptr<ILexeme> makeIdentifier(const utakata::utf8_string::UTF8String& str);
         smart_ptr<ILexeme> makeString(const utakata::utf8_string::UTF8String& str);
         smart_ptr<ILexeme> makeNumber(const utakata::utf8_string::UTF8String& real,
@@ -35,6 +36,7 @@ namespace utakata {
                                             bool exact);
         smart_ptr<ILexeme> makeImaginaryOnly(const utakata::utf8_string::UTF8String& str,
                                              bool exact);
+        smart_ptr<ILexeme> makeBoolean(const smart_ptr<utakata::utf8_string::UTF8Char>& ch);
 
 
         ////////////////////////////////////////////
@@ -158,6 +160,17 @@ namespace utakata {
 
         };
 
+        class ByteVector : public ILexeme
+        {
+        public:
+            ByteVector(){}
+            virtual ~ByteVector(){}
+            int getID() const;
+            smart_ptr<utakata::utf8_string::UTF8String> toString() const;
+
+        };
+
+
         class String : public ILexeme
         {
         public:
@@ -216,6 +229,21 @@ namespace utakata {
 
             smart_ptr<utakata::utf8_string::UTF8String> ch_;
         };
+
+        class Boolean : public ILexeme
+        {
+        public:
+            Boolean(const smart_ptr<utf8_string::UTF8Char>& ch);
+            virtual ~Boolean(){}
+
+            int getID() const;
+            smart_ptr<utakata::utf8_string::UTF8String> toString() const;
+
+        private:
+
+            smart_ptr<utakata::utf8_string::UTF8String> str_;
+        };
+
     };
 
 };
old mode 100644 (file)
new mode 100755 (executable)
index 8c7fdaf..177cf17
@@ -1,5 +1,8 @@
 #include "parser.h"
 
+#include "lexeme.h"
+#include "lexeme_id.h"
+
 using namespace utakata;
 
 parser::Parser::Parser(const smart_ptr<lexer::Lexer>& l) : lexer_(l)
@@ -8,5 +11,37 @@ parser::Parser::Parser(const smart_ptr<lexer::Lexer>& l) : lexer_(l)
 
 bool parser::Parser::parse(smart_ptr<utf8::UTF8InputStream>& strm)
 {
+    int status = INIT;
+    lexeme::IDProxy prox;
+    smart_ptr<lexeme::ILexeme> lexm;
+    // lexeme\82ªNull\82Å\82 \82é\8fó\91Ô\82É\82È\82é\82Ü\82Å\90i\82Þ\81B
+    while (lexm = lexer_->lex(strm)) {
+        if (lexm.isNull())
+        {
+            break;
+        }
+
+        // lexeme\82ª\95Ô\82Á\82Ä\82«\82½\82ç\81A\8d\\95\92è\8b`\82É\8aY\93\96\82·\82é\82©\82Ç\82¤\82©\82ð\92²\82×\82é\81B
+        // scheme\82Ì\8d\\95\92è\8b`\82Í\83V\83\93\83v\83\8b\82©\82Â\97á\8aO\82Ì\82È\82¢\82à\82Ì\82É\82È\82Á\82Ä\82¢\82é\82½\82ß\81A
+        // \8ae\92è\8b`\82Æ\82·\82é\82Ì\82Í\8aÈ\92P\82Å\82 \82é\81B
+        if (status == INIT)
+        {
+            if (lexm->getID() == prox->openParenthesis)
+            {
+                // \8aJ\82«\8a\87\8cÊ\82Å\82 \82é\8fê\8d\87
+                status = LIST_BEGIN;
+            }
+            else if (lexm->getID() == prox->string ||
+                     lexm->getID() == prox->number ||
+                     lexm->getID() == prox->identifier ||
+                     lexm->getID() == prox->charactor ||
+                     lexm->getID() == prox->boolean)
+            {
+                // \82»\82ê\82¼\82ê\82Ì\8fê\8d\87\81Alexeme_datum\82Æ\82µ\82Ä\88µ\82í\82ê\82é\81B
+                status = LEXEME_DATUM;
+            }
+            else if
+        }
+    }
     return true;
 }
old mode 100644 (file)
new mode 100755 (executable)
index 71375ee..bfe538f
--- a/parser.h
+++ b/parser.h
@@ -13,6 +13,26 @@ namespace utakata {
         {
             // lexerを受け取り、lexerが保持する全体を解析しつつ、
             // 処理を行なう。
+            enum {
+                INIT                = 0,  /* 初期時点 */
+                DATUM               = 1,  /* detumであるかどうか */
+                LEXEME_DATUM        = 2,  /* lexeme_detumのどれかであるか */
+                LIST_BEGIN          = 4,  /* リストの開始 - (,[ */
+                LIST_END            = 5,  /* リストの終了 - (,[と対応する),] */
+                LIST_INNER_DOT      = 6,  /* リスト中に出現した . */
+                LIST_ABB_QUOTE      = 7,  /* リスト中に出現したabbrev prefix ' */
+                LIST_ABB_QQUOTE     = 8,  /* リスト中に出現したabbrev prefix ` */
+                LIST_ABB_UQUOTE     = 9,  /* リスト中に出現したabbrev prefix , */
+                LIST_ABB_UQUOTE_SP  = 10, /* リスト中に出現したabbrev prefix ,@ */
+                LIST_ABB_SYNTAX     = 11, /* リスト中に出現したabbrev prefix #' */
+                LIST_ABB_QSYNTAX    = 12, /* リスト中に出現したabbrev prefix #` */
+                LIST_ABB_USYNTAX    = 13, /* リスト中に出現したabbrev prefix #, */
+                LIST_ABB_USYNTAX_SP = 14, /* リスト中に出現したabbrev prefix #,@ */
+                VECTOR_START        = 15, /* #( */
+                VECTOR_END          = 16, /* #(と対応した) */
+                BYTEVECTOR_START    = 17, /* #vu8( */
+                BYTEVECTOR_END      = 18, /* #vu8(と対応した) */
+            };
         public:
             
             Parser(const smart_ptr<utakata::lexer::Lexer>& l);
index 166454d..2f21bc0 100755 (executable)
@@ -189,6 +189,18 @@ smart_ptr<lexeme::ILexeme> sublexer::FirstLexer::lex_(const utakata::utf8_string
             stream->read();
             next.add(new sublexer::CharactorLexer());
         }
+        else if (ch.toUTF16Code() == 't' || ch.toUTF16Code() == 'f' ||
+                 ch.toUTF16Code() == 'T' || ch.toUTF16Code() == 'F')
+        {
+            stream->read();
+            next.add(new sublexer::BooleanLexer(ch));
+        }
+        else if (ch.toUTF16Code() == 'v')
+        {
+            // この場合、bytevectorとなる可能性がある。
+            stream->read();
+            next.add(new sublexer::ByteVectorLexer(ch));
+        }
     }
     else if (str[0].toUTF16Code() == '-')
     {
@@ -481,6 +493,60 @@ smart_ptr<lexeme::ILexeme> sublexer::CharactorLexer::lex(smart_ptr<utf8::UTF8Inp
 
 //================================================================================
 
+sublexer::BooleanLexer::BooleanLexer(const utf8_string::UTF8Char& ch) : ch_(new utf8_string::UTF8Char(ch))
+{
+}
+
+smart_ptr<lexeme::ILexeme> sublexer::BooleanLexer::lex(smart_ptr<utf8::UTF8InputStream> stream,
+                                                         smart_ptr<sublexer::ISubLexer>& next)
+{
+    // true/falseを判別する必要は特に無いため、次の文字が区切り文字だかどうか
+    // だけを気にする。
+
+    if (!stream->isEOF())
+    {
+        UTF8Char ch(stream->read());
+
+        lexer_delimiter::Normal nor;
+        if (!nor(ch))
+        {
+            // hex valueではなかった場合には、これはエラーであると
+            // して返す。
+            std::stringstream ss;
+            ss << ch.toStr() << "はbooleanの直後では認識されません";
+            throw sublexer::LexException(stream->pos(), ch.toStr());
+        }
+    }
+
+    return lexeme::makeBoolean(ch_);
+}
+
+//================================================================================
+
+sublexer::ByteVectorLexer::ByteVectorLexer(const utf8_string::UTF8Char& ch) : ch_(new utf8_string::UTF8Char(ch))
+{
+}
+
+smart_ptr<lexeme::ILexeme> sublexer::ByteVectorLexer::lex(smart_ptr<utf8::UTF8InputStream> stream,
+                                                         smart_ptr<sublexer::ISubLexer>& next)
+{
+    // この時点で#vまでは読まれているため、以降2文字がvu(であるかどうかを
+    // 調べる。
+
+    UTF8String str(stream->read(3));
+    if (str.toStr() == "u8(")
+    {
+        std::stringstream ss;
+        ss << "バイトベクタとして認識できません";
+        throw sublexer::LexException(stream->pos(), "");
+    }
+
+    return lexeme::makeByteVector();
+}
+
+
+//================================================================================
+
 
 smart_ptr<lexeme::ILexeme> sublexer::OneLineCommentLexer::lex(
     smart_ptr<utf8::UTF8InputStream> stream,
old mode 100644 (file)
new mode 100755 (executable)
index 0979eec..4bb47f8
@@ -156,6 +156,40 @@ namespace utakata {
             smart_ptr<utakata::utf8_string::UTF8String> str_;
         };
 
+        class BooleanLexer : public ISubLexer
+        {
+            // #t、または#fを返す。
+            // いずれかの次には、必ず区切り文字がなければならない。
+        public:
+
+            BooleanLexer(const utakata::utf8_string::UTF8Char& ch);
+            virtual ~BooleanLexer(){}
+
+            smart_ptr<lexeme::ILexeme> lex(smart_ptr<utakata::utf8::UTF8InputStream> stream,
+                                           smart_ptr<ISubLexer>& next);
+
+        private:
+
+            smart_ptr<utakata::utf8_string::UTF8Char> ch_;
+        };
+
+        class ByteVectorLexer : public ISubLexer
+        {
+            // #vu8であるかどうかを検査する。
+            // vu8ではない場合には、エラーとなる。
+        public:
+
+            ByteVectorLexer(const utakata::utf8_string::UTF8Char& ch);
+            virtual ~ByteVectorLexer(){}
+
+            smart_ptr<lexeme::ILexeme> lex(smart_ptr<utakata::utf8::UTF8InputStream> stream,
+                                           smart_ptr<ISubLexer>& next);
+
+        private:
+
+            smart_ptr<utakata::utf8_string::UTF8Char> ch_;
+        };
+
     };
 
 };