namespace utakata {
- namespace utf8_string {
+ namespace utf8 {
- class UTF8Char;
+ class UTF8InputStream;
};
public:
virtual ~IDelimiter() {}
- // 渡した文字がデリミタであるかどうかを返す。
- virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch) = 0;
+ // ストリームから一文字読みだし、読みだした文字がデリミタ
+ // であるかどうかを返す。
+ // デリミタである場合には、デリミタ分は捨てられる。
+ virtual bool isDelimiter(utakata::utf8::UTF8InputStream& strm) = 0;
+
};
};
{
// 渡された文字がデリミタかどうかを判別する。
// ここで判別するのは空白文字か否かという点である。
-
+ 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;
}
#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:
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();
+ }
+ };
+
};
};
// 読出した文字がデリミタであり、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());