--- /dev/null
+#include <iostream>
+
+#include "lexer.h"
+
+using namespace utakata;
+
+smart_ptr<lexer::CLexeme> lexer::CLexer::lex(smart_ptr<utf8::CUTF8InputStream>& stream)
+{
+ // 渡されたCUTF8InputStreamから、1文字ずつ読んでいき、各構文を解釈
+ // する。
+
+ // 何か一つの非終端記号、終端記号を読みだすたびにそれを返す。
+
+ // まずは何はなくとも1文字読みだす。
+ utf8_string::CUTF8Char ch(stream->read());
+
+ if (utf8_string::is_eof(ch))
+ {
+ // eofを示す値を返す。
+ return smart_ptr<lexer::CLexeme>();
+ }
+}
#define _LEXER_H_
#include "smart_ptr.h"
+#include "utf8.h"
+#include "utf8_string.h"
namespace utakata {
渡されたUTF8を解釈するstreamから、データを解釈して、結果を返す。
結果は、smart_ptr<CLexeme>で返される。
*/
- smart_ptr<CLexeme> lex(smart_ptr<CUTF8InputStream>& stream);
+ smart_ptr<CLexeme> lex(smart_ptr<utakata::utf8::CUTF8InputStream>& stream);
private:
};
- class ILexeme
+ class CLexeme
{
- // 非終端記号、及び終端記号を表すベースクラス。
+ // 非終端記号、及び終端記号を表すクラス。
+ // それぞれ分割しても問題なかったのだが、それぞれのデータが
+ // 互いに非可換であるが、それぞれ継承してもどうしようもないため、
+ // さしあたって必要となる全ての型を取得できるようにしておき、
+ // それをそのまま取得してもらう、という形にする。
+ // つまりは全体をpimplにしておき、データはそれらから取得するようにするということ。
+ // それぞれを取得するためのインターフェースはこれから作成される。
public:
ILexeme();
virtual ~ILexeme(){}
// 終端記号、非終端記号のIDを取得する。
- virtual int getID() const = 0;
+ int getID() const;
- // そのものを表す文字列を返す。
- virtual const CUTF8String getString() const = 0;
+ // stringのデータ型において、文字列を取得する。
+ smart_ptr<utakata::utf8_string::CUTF8String> getString() const;
+
+ private:
+ // 必要な型全てをまとめるための構造体。ただし、
+ // 内部のどれか一つだけが有効となっており、これを必要と
+ // しない終端記号のデータも存在する。
+ // 詳しくは各データを解釈する場所にて。
+ struct PImpl;
+ smart_ptr<PImpl> pimpl_;
};
};
// UTF-8の一文字を読みだして返す。
// UTF-8に該当しない場合、空のvectorを返す。
if (!strm_->good()) {
- return std::vector<unsigned char>(0);
+ throw CStreamException("not ready input stream");
}
// 最初に一文字だけ読みだして、チェックをかける。
}
}
- return std::vector<unsigned char>(0);
+ return std::vector<unsigned char>(0xff);
}
std::vector<unsigned char> CUTF8InputStream::read(int num)
#include <iostream>
#include <string>
#include <vector>
+#include <exception>
+
#include "smart_ptr.h"
#include "InputStream.h"
namespace utf8 {
+ // inputstreamの準備が出来ていない場合に送出される例外
+ class CStreamException : public std::exception
+ {
+ public:
+ CStreamException(const std::string& str) : str_(str) {}
+ virtual ~CStreamException() throw() {}
+
+ const char* what() throw() {
+ return str_.c_str();
+ }
+ private:
+
+ std::string str_;
+ };
+
class CUTF8InputStream : public IInputStream
{
/**
return tmp;
}
+bool utakata::utf8_string::is_ascii_char(const CUTF8Char& ch)
+{
+ // 0x7f >= ascii >= 0x00 がasciiなので、その範囲で判定を行う。
+ if (ch.toUTF16Code() >= 0 && ch.toUTF16Code() < 0x80
+ && ch.getBytes().size() == 1)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool utakata::utf8_string::is_eof(const CUTF8Char& ch)
+{
+ return ch.getBytes()[0] == 0xff ? true : false;
+}
+
//================================================================================
utakata::utf8_string::CUTF8String::CUTF8String() : chars_()
// 渡されたCUTF8Charがasciiコードの範囲内に収まっているかどうかを返す。
bool is_ascii_char(const CUTF8Char& ch);
+
+ // UTF8では先頭1バイトが0xffになることはありえないので、
+ // 先頭1バイトが0xffの場合には、これは終端記号であるとした。
+ bool is_eof(const CUTF8Char& ch);
+
//================================================================================
class CUTF8String