unsyntaxSplicing(12),
identifier(13),
number(14),
- charactor(15)
+ charactor(15),
+ boolean(16)
{
// 全てのIDをここで記述する。
// すべてconstなので、実際にはinitializerで初期化している。
const int identifier; // <identifier>
const int number; // <number>
const int charactor; // <charactor>
+ const int boolean; // <boolean>
};
};
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());
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)
{
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 //
/////////////
{
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_;
+}
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,
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);
////////////////////////////////////////////
};
+ class ByteVector : public ILexeme
+ {
+ public:
+ ByteVector(){}
+ virtual ~ByteVector(){}
+ int getID() const;
+ smart_ptr<utakata::utf8_string::UTF8String> toString() const;
+
+ };
+
+
class String : public ILexeme
{
public:
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_;
+ };
+
};
};
#include "parser.h"
+#include "lexeme.h"
+#include "lexeme_id.h"
+
using namespace utakata;
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;
}
{
// 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);
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() == '-')
{
//================================================================================
+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,
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_;
+ };
+
};
};