using namespace std;
-textarrayformat::CTextArrayReader::CTextArrayReader(std::istream& is) :
+textarrayformat::TextArrayReader::TextArrayReader(std::istream& is) :
splitter_(), blocks_()
{
// openを利用して読出す。
open(is);
}
-void textarrayformat::CTextArrayReader::open(std::istream& is)
+void textarrayformat::TextArrayReader::open(std::istream& is)
{
// isより行単位での読み出しを行う。
}
}
-std::string textarrayformat::CTextArrayReader::get(int num)
+std::string textarrayformat::TextArrayReader::get(int num)
{
// ここはassertではなく、通常の例外によるチェックを行う。
if (num < 0)
{
- throw textarrayformat::COutOfIndexException("Argument must be greater than zero");
+ throw textarrayformat::OutOfIndexException("Argument must be greater than zero");
}
if (static_cast<size_t>(num) >= blocks_.size())
ss << "Argument must be less than blocks num : size [" << blocks_.size()
<< "] and receive value is [" << num << "]" << endl;
- throw textarrayformat::COutOfIndexException(ss.str());
+ throw textarrayformat::OutOfIndexException(ss.str());
}
// 本当はここでatにしておけば、事前のチェックは必要無いはず。
return blocks_[num];
}
-textarrayformat::COutOfIndexException::COutOfIndexException(const std::string& str) :
+textarrayformat::OutOfIndexException::OutOfIndexException(const std::string& str) :
str_(str)
{
}
-const char* textarrayformat::COutOfIndexException::what() const throw()
+const char* textarrayformat::OutOfIndexException::what() const throw()
{
return str_.c_str();
}
namespace textarrayformat {
- class COutOfIndexException : public std::exception
+ class OutOfIndexException : public std::exception
{
public:
- COutOfIndexException(const std::string& str);
- virtual ~COutOfIndexException() throw() {}
+ OutOfIndexException(const std::string& str);
+ virtual ~OutOfIndexException() throw() {}
virtual const char* what() const throw();
const std::string str_;
};
- class CTextArrayReader
+ class TextArrayReader
{
public:
- CTextArrayReader(std::istream& is);
- virtual ~CTextArrayReader() {}
+ TextArrayReader(std::istream& is);
+ virtual ~TextArrayReader() {}
// 指定したストリームの先頭からフォーマットに従ってブロック単位
// への切り出しを行う。
--- /dev/null
+#ifndef _DELIMITER_H_
+#define _DELIMITER_H_
+
+namespace utakata {
+
+ namespace utf8_string {
+
+ class UTF8Char;
+
+ };
+
+ namespace sublexer {
+
+ // sublexer内で利用されるdelimiterのインターフェース。
+
+ class IDelimiter
+ {
+ public:
+ virtual ~IDelimiter() {}
+
+ // 渡した文字がデリミタであるかどうかを返す。
+ virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch) = 0;
+ };
+
+ };
+
+};
+
+#endif /* _DELIMITER_H_ */
--- /dev/null
+#include "utf8_string.h"
+#include "delimiter_impl.h"
+
+using namespace utakata::utf8_string;
+using namespace utakata::sublexer;
+
+NormalDelimiter::NormalDelimiter() : delimiter_()
+{
+ smart_ptr<IDelimiter> tmp(new WhitespaceDelimiter);
+ delimiter_ = tmp;
+}
+
+bool NormalDelimiter::isDelimiter(const UTF8Char& ch)
+{
+ // 渡された文字がデリミタかどうかを判別する。
+ // このクラスガ判別するデリミタは、
+ // <delimiter> - ( | ) | [ | ] | " | ; | #
+ // | <whitespace>
+ // <whitespace> - <character tabulation>
+ // | <linefeed> | <line tabulation> | <form feed>
+ // | <carriage return> | <next line>
+ // | <any character whose category is Zs, Zl, or Zp>
+ // に該当するデリミタ。
+ // このデリミタは、<boolean>,<string>,<number>, .<character>
+ // を解析している間に出現するものであり、それ以外の場合は、
+ // デリミタとして読み飛ばしてはならない。
+
+ switch (ch.toUTF16Code())
+ {
+ case '(':
+ case '[':
+ case ')':
+ case ']':
+ case '"':
+ case ';':
+ case '#':
+ return true;
+ default:
+ return delimiter_->isDelimiter(ch);
+ }
+}
+
+//================================================================================
+
+WhitespaceDelimiter::WhitespaceDelimiter()
+{
+}
+
+bool WhitespaceDelimiter::isDelimiter(const UTF8Char& ch)
+{
+ // 渡された文字がデリミタかどうかを判別する。
+ // ここで判別するのは空白文字か否かという点である。
+
+ return true;
+}
+
--- /dev/null
+#ifndef _DELIMITER_IMPL_H_
+#define _DELIMITER_IMPL_H_
+
+#include "delimiter.h"
+#include "smart_ptr.h"
+#include "utf8_string.h"
+
+
+namespace utakata {
+
+ namespace sublexer {
+
+ class NormalDelimiter : public IDelimiter
+ {
+ public:
+ NormalDelimiter();
+ virtual ~NormalDelimiter() {}
+
+ virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch);
+
+ private:
+
+ smart_ptr<IDelimiter> delimiter_;
+ };
+
+ class WhitespaceDelimiter : public IDelimiter
+ {
+ // デリミタ中で、空白スペースを表す文字を判別する。
+ // Schemeでは、空白スペースが幅広いため、個別に分割しておいた
+ // 方がよい。
+ public:
+ WhitespaceDelimiter();
+ virtual ~WhitespaceDelimiter() {}
+
+ virtual bool isDelimiter(const utakata::utf8_string::UTF8Char& ch);
+ };
+
+ };
+
+};
+
+#endif /* _DELIMITER_IMPL_H_ */
namespace utakata {
namespace utf8_string {
- class CUTF8String;
+ class UTF8String;
};
namespace lexeme {
virtual int getID() const = 0;
// stringのデータ型において、文字列を取得する。
- virtual smart_ptr<utakata::utf8_string::CUTF8String> toString() const = 0;
+ virtual smart_ptr<utakata::utf8_string::UTF8String> toString() const = 0;
// 内部が保持している実体をコンパイルする。
virtual void compile() = 0;
using namespace utakata;
-smart_ptr<lexeme::ILexeme> lexer::CLexer::lex(smart_ptr<utf8::CUTF8InputStream>& stream)
+smart_ptr<lexeme::ILexeme> lexer::Lexer::lex(smart_ptr<utf8::UTF8InputStream>& stream)
{
// 渡されたCUTF8InputStreamから、1文字ずつ読んでいき、各構文を解釈
// する。
// まずは何はなくとも1文字読みだす。
// EOF以外の値の場合には、通常の字句解析を行っていく。
- utf8_string::CUTF8String str;
-
- smart_ptr<sublexer::ISubLexer> sublex(new sublexer::CFirstLex());
+ smart_ptr<sublexer::ISubLexer> sublex(new sublexer::FirstLexer());
while (!stream->isEOF() && !sublex.isNull()) {
- // 意味のある文字のみで構成していく。
-
- utf8_string::CUTF8Char ch = stream->peek();
- smart_ptr<sublexer::ISubLexer> next = sublex->lex(ch, str, stream);
+ // 基本的に、sublexerに全処理を委譲する形になる。
+ // sublexerはそれぞれ別々のデリミタfunctorを持っており
+ // それぞれのデリミタfunctorで、各デリミタを判別する。
+ // 最初を含む構文チェックはFirstLexerが行ない、それ以外なら
+ // そのまま行なう。
+
+ smart_ptr<sublexer::ISubLexer> next = sublex->lex(stream);
if (next.isNull())
{
return sublex->getLexeme();
}
// 次に移れるようにしておく。
sublex = next;
- str += utf8_string::CUTF8Char(stream->read());
}
// 何もなく終了してしまった場合、これはエラーとなる。
namespace lexer {
- class CLexer
+ class Lexer
{
/**
scheme構文の字句解析器。
でも基本的にこれひとつで済むようにした方が楽かもしんない。
*/
public:
- CLexer(){}
- virtual ~CLexer(){}
+ Lexer(){}
+ virtual ~Lexer(){}
/**
渡されたUTF8を解釈するstreamから、データを解釈して、結果を返す。
結果は、smart_ptr<CLexeme>で返される。
*/
- smart_ptr<utakata::lexeme::ILexeme> lex(smart_ptr<utakata::utf8::CUTF8InputStream>& stream);
+ smart_ptr<utakata::lexeme::ILexeme> lex(smart_ptr<utakata::utf8::UTF8InputStream>& stream);
};
// vm::UKVirtualMachine vm;
// std::vector<smart_ptr<vm::IOperand> > vec;
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CPushOp(vm::data(1))));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CPushOp(vm::data(2))));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CAddOp()));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CPushOp(vm::data(4))));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CMulOp()));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CPushOp(vm::data(2))));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CDivOp()));
-// vec.push_back(smart_ptr<vm::IOperand>(new vm::CPopOp()));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::PushOp(vm::data(1))));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::PushOp(vm::data(2))));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::AddOp()));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::PushOp(vm::data(4))));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::MulOp()));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::PushOp(vm::data(2))));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::DivOp()));
+// vec.push_back(smart_ptr<vm::IOperand>(new vm::PopOp()));
// vm.run(vec);
namespace vm {
- class CNumber
+ class Number
{
/**
Schemeの数階層の最上位となるクラス。
};
- class CComplex : public CNumber
+ class Complex : public CNumber
{
/**
複素数を扱うクラス。
virtual ~CComplex(){}
};
- class CReal : public CComplex
+ class Real : public CComplex
{
/**
schemeの実数を表現するクラス。
virtual ~CReal() {}
};
- class CRational : public CReal
+ class Rational : public CReal
{
/**
schemeの有理数を表現するクラス。
virtual ~CRational() {}
};
- class CInteger : public CRational
+ class Integer : public CRational
{
/**
schemeの整数を表現するクラス。
#include "cpu.h"
-int vm::CAddOp::operator()(vm::vcpu& cpu)
+int vm::AddOp::operator()(vm::vcpu& cpu)
{
vm::data d1 = cpu.top(); cpu.pop();
vm::data d2 = cpu.top(); cpu.pop();
return 0;
}
-int vm::CSubOp::operator()(vm::vcpu& cpu)
+int vm::SubOp::operator()(vm::vcpu& cpu)
{
vm::data d1 = cpu.top(); cpu.pop();
vm::data d2 = cpu.top(); cpu.pop();
return 0;
}
-int vm::CMulOp::operator()(vm::vcpu& cpu)
+int vm::MulOp::operator()(vm::vcpu& cpu)
{
vm::data d1 = cpu.top(); cpu.pop();
vm::data d2 = cpu.top(); cpu.pop();
return 0;
}
-int vm::CDivOp::operator()(vm::vcpu& cpu)
+int vm::DivOp::operator()(vm::vcpu& cpu)
{
vm::data d1 = cpu.top(); cpu.pop();
vm::data d2 = cpu.top(); cpu.pop();
return 0;
}
-vm::CPushOp::CPushOp(const vm::data& data) : IOperand(1), data_(new vm::data(data))
+vm::PushOp::PushOp(const vm::data& data) : IOperand(1), data_(new vm::data(data))
{
}
-int vm::CPushOp::operator()(vm::vcpu& cpu)
+int vm::PushOp::operator()(vm::vcpu& cpu)
{
cpu.push(*this->data_);
return 0;
}
-int vm::CPopOp::operator()(vm::vcpu& cpu)
+int vm::PopOp::operator()(vm::vcpu& cpu)
{
std::cout << cpu.top().value();
cpu.pop();
スタックの頂上にあるデータを、ひとつ下のスタックのデータに加算
し、スタックの頂上に積む。
*/
- class CAddOp : public IOperand
+ class AddOp : public IOperand
{
public:
- CAddOp() : IOperand(2) {}
- virtual ~CAddOp() {}
-
+ AddOp() : IOperand(2) {}
+ virtual ~AddOp() {}
virtual int operator()(vcpu&);
};
スタックの頂上にあるデータを、ひとつ下のスタックのデータに減算
し、スタックの頂上に積む。
*/
- class CSubOp : public IOperand
+ class SubOp : public IOperand
{
public:
- CSubOp() : IOperand(2) {}
- virtual ~CSubOp() {}
+ SubOp() : IOperand(2) {}
+ virtual ~SubOp() {}
virtual int operator()(vcpu&);
};
スタックの頂上にあるデータを、ひとつ下のスタックのデータに乗算
し、スタックの頂上に積む。
*/
- class CMulOp : public IOperand
+ class MulOp : public IOperand
{
public:
- CMulOp() : IOperand(2) {}
- virtual ~CMulOp() {}
+ MulOp() : IOperand(2) {}
+ virtual ~MulOp() {}
virtual int operator()(vcpu&);
};
スタックの頂上にあるデータを、ひとつ下のスタックのデータに除算
し、スタックの頂上に積む。
*/
- class CDivOp : public IOperand
+ class DivOp : public IOperand
{
public:
- CDivOp() : IOperand(2) {}
- virtual ~CDivOp() {}
+ DivOp() : IOperand(2) {}
+ virtual ~DivOp() {}
virtual int operator()(vcpu&);
};
/**
指定したデータをスタックの頂上に積む。
*/
- class CPushOp : public IOperand
+ class PushOp : public IOperand
{
public:
- CPushOp(const data& data);
- virtual ~CPushOp() {}
+ PushOp(const data& data);
+ virtual ~PushOp() {}
virtual int operator()(vcpu&);
/**
スタックの頂上のデータを取り除く。
*/
- class CPopOp : public IOperand
+ class PopOp : public IOperand
{
public:
- CPopOp() : IOperand(0) {}
- virtual ~CPopOp() {}
+ PopOp() : IOperand(0) {}
+ virtual ~PopOp() {}
virtual int operator()(vcpu&);
};
using namespace simpletest;
-CSimpleTestSuite::CSimpleTestSuite(const std::string& name) :
+SimpleTestSuite::SimpleTestSuite(const std::string& name) :
name_("[" + name + "]"), prefix_("- "), testers_(), strm_(std::cout),
runner_()
{
- runner_.add(new CSimpleTestRunner(strm_, prefix_));
+ runner_.add(new SimpleTestRunner(strm_, prefix_));
}
-CSimpleTestSuite::CSimpleTestSuite(const std::string& name,
+SimpleTestSuite::SimpleTestSuite(const std::string& name,
std::ostream& strm) :
name_("[" + name + "]"), prefix_("- "), testers_(), strm_(strm)
{
- runner_.add(new CSimpleTestRunner(strm_, prefix_));
+ runner_.add(new SimpleTestRunner(strm_, prefix_));
}
-bool CSimpleTestSuite::addTester(const sfcr::sfc_r<bool>::type& func)
+bool SimpleTestSuite::addTester(const sfcr::sfc_r<bool>::type& func)
{
// テストを追加する。中身がNULLの場合には触らない。
if (func.isNull())
return true;
}
-void CSimpleTestSuite::run()
+void SimpleTestSuite::run()
{
// この場合、標準出力される、std::coutが利用される。
// 現在保持しているテストをまとめて実行する。
printBeginMessage();
- CSimpleTestRunner runner(strm_, prefix_);
+ SimpleTestRunner runner(strm_, prefix_);
std::for_each(testers_.begin(), testers_.end(),
*runner_);
printEndMessage();
}
-void simpletest::CSimpleTestSuite::printBeginMessage()
+void simpletest::SimpleTestSuite::printBeginMessage()
{
// 開始メッセージを、指定されたストリームに出力する。
strm_ << separates << std::endl;
}
-void simpletest::CSimpleTestSuite::printEndMessage()
+void simpletest::SimpleTestSuite::printEndMessage()
{
// テストの終了メッセージを、指定されたストリームに出力する。
const std::string separates("==================================================");
strm_ << separates << std::endl;
}
-smart_ptr<CSimpleTestAsserter> simpletest::CSimpleTestSuite::getAsserter()
+smart_ptr<SimpleTestAsserter> simpletest::SimpleTestSuite::getAsserter()
{
- return smart_ptr<simpletest::CSimpleTestAsserter>(new
- simpletest::CSimpleTestAsserter(strm_, prefix_));
+ return smart_ptr<simpletest::SimpleTestAsserter>(new
+ simpletest::SimpleTestAsserter(strm_, prefix_));
}
-simpletest::CSimpleTestRunner::CSimpleTestRunner(std::ostream& strm,
+simpletest::SimpleTestRunner::SimpleTestRunner(std::ostream& strm,
const std::string& prefix) :
- strm_(strm), prefix_(prefix), pImpl(new simpletest::CSimpleTestRunner::PImpl)
+ strm_(strm), prefix_(prefix), pImpl(new simpletest::SimpleTestRunner::PImpl)
{}
-void simpletest::CSimpleTestRunner::innerCheck(bool b)
+void simpletest::SimpleTestRunner::innerCheck(bool b)
{
// 関数が例外を返さなかった場合に実行されるチェック関数
pImpl->count++;
}
}
-void simpletest::CSimpleTestRunner::innerCheck(std::exception& e) {
+void simpletest::SimpleTestRunner::innerCheck(std::exception& e) {
// 例外が発行された場合、とりあえずはe.whatsを
// std::stringとして保持しておく。
pImpl->exception++;
printException(e);
}
-void simpletest::CSimpleTestRunner::printSuccess()
+void simpletest::SimpleTestRunner::printSuccess()
{
// 成功した場合のメッセージを出力する。
int count = pImpl->success + pImpl->fail + pImpl->exception;
strm_ << count << " is success." << std::endl;
}
-void simpletest::CSimpleTestRunner::printFail()
+void simpletest::SimpleTestRunner::printFail()
{
// 成功した場合のメッセージを出力する。
int count = pImpl->success + pImpl->fail + pImpl->exception;
strm_ << count << " is fail." << std::endl;
}
-void simpletest::CSimpleTestRunner::printException(const std::exception& e)
+void simpletest::SimpleTestRunner::printException(const std::exception& e)
{
// 成功した場合のメッセージを出力する。
int count = pImpl->success + pImpl->fail + pImpl->exception;
//================================================================================
-simpletest::CSimpleTestAsserter::CSimpleTestAsserter(std::ostream& strm,
+simpletest::SimpleTestAsserter::SimpleTestAsserter(std::ostream& strm,
const std::string& prefix) :
strm_(strm), prefix_(prefix), count_(0)
{
}
-simpletest::CSimpleTestAsserter::CSimpleTestAsserter(const CSimpleTestAsserter& asserter) :
+simpletest::SimpleTestAsserter::SimpleTestAsserter(const SimpleTestAsserter& asserter) :
strm_(asserter.strm_), prefix_(asserter.prefix_), count_(asserter.count_)
{
}
-CSimpleTestAsserter& simpletest::CSimpleTestAsserter::operator=(const CSimpleTestAsserter& asserter)
+SimpleTestAsserter& simpletest::SimpleTestAsserter::operator=(const SimpleTestAsserter& asserter)
{
// 代入によってコピーを作成するための処理
- CSimpleTestAsserter a(asserter);
+ SimpleTestAsserter a(asserter);
std::swap(*this, a);
return *this;
}
-bool simpletest::CSimpleTestAsserter::isOk() const
+bool simpletest::SimpleTestAsserter::isOk() const
{
// count_は、checkの比較関数が失敗する度にこれが実行されることに
// なっている。
// 一応例外が実行されたかどうかをチェックし、例外が投げられたことで関数が
// 終了している場合、それも記述される。
- class CSimpleTestRunner;
+ class SimpleTestRunner;
- class CSimpleTestAsserter;
+ class SimpleTestAsserter;
- class CSimpleTestSuite
+ class SimpleTestSuite
{
// セパレータ以外の文字列の表記時に利用されるprefix
const std::string name_;
public:
- CSimpleTestSuite(const std::string& name);
- CSimpleTestSuite(const std::string& name, std::ostream& strm);
- virtual ~CSimpleTestSuite(){}
+ SimpleTestSuite(const std::string& name);
+ SimpleTestSuite(const std::string& name, std::ostream& strm);
+ virtual ~SimpleTestSuite(){}
// 指定された形式の関数コールバックを渡す。
// 返り値以外は指定されてりない。
void run();
// assertを行う部分を切り出したクラスを返す。
- smart_ptr<CSimpleTestAsserter> getAsserter();
+ smart_ptr<SimpleTestAsserter> getAsserter();
private:
std::vector<sfcr::sfc_r<bool>::type> testers_;
std::ostream& strm_;
- smart_ptr<CSimpleTestRunner> runner_;
+ smart_ptr<SimpleTestRunner> runner_;
};
//================================================================================
- class CSimpleTestRunner
+ class SimpleTestRunner
{
/**
テスト結果をシンプルに表示するだけの機能を持つ。
*/
public:
- CSimpleTestRunner(std::ostream& strm,
+ SimpleTestRunner(std::ostream& strm,
const std::string& prefix);
void printSuccess();
}
};
- class CSimpleTestAsserter
+ class SimpleTestAsserter
{
public:
- CSimpleTestAsserter(std::ostream& strm,
+ SimpleTestAsserter(std::ostream& strm,
const std::string& prefix);
- CSimpleTestAsserter(const CSimpleTestAsserter& asserter);
- virtual ~CSimpleTestAsserter() {}
+ SimpleTestAsserter(const SimpleTestAsserter& asserter);
+ virtual ~SimpleTestAsserter() {}
- CSimpleTestAsserter& operator=(const CSimpleTestAsserter& asserter);
+ SimpleTestAsserter& operator=(const SimpleTestAsserter& asserter);
// 外部から利用される簡単なassert。
// 基本的にはstd::equal_toを利用することになっている。
#define _SUBLEXER_H_
#include "smart_ptr.h"
-//#include "utf8.h"
-//#include "utf8_string.h"
-//#include "lexeme.h"
-
// これはあくまで抽象なので、定義に依存させる。
namespace utakata {
};
namespace utf8 {
- class CUTF8InputStream;
+ class UTF8InputStream;
};
- namespace utf8_string {
- class CUTF8Char;
- class CUTF8String;
- };
};
// strは前回のsublexが返した文字列であり、前のsublexによって更新される。
// streamは文字通りストリームとなる。sublex中で文字の取得などを
// 自由に行う必要があるために渡している。
- virtual smart_ptr<ISubLexer> lex(const utakata::utf8_string::CUTF8Char& ch,
- const utakata::utf8_string::CUTF8String& str,
- smart_ptr<utakata::utf8::CUTF8InputStream>& stream) = 0;
+ virtual smart_ptr<ISubLexer> lex(smart_ptr<utakata::utf8::UTF8InputStream>& stream) = 0;
// 作成したILexemeを返す。lexの結果を返さない場合に利用される。
// これだけは前方参照のみでなんとか乗り切る必要がある。
#include "sublexer_impl.h"
#include "lexeme_impl.h"
+#include "delimiter_impl.h"
using namespace utakata;
+using namespace utakata::utf8_string;
-smart_ptr<sublexer::ISubLexer> sublexer::CFirstLex::lex(const utf8_string::CUTF8Char& ch,
- const utf8_string::CUTF8String& str,
- smart_ptr<utf8::CUTF8InputStream>& stream)
+sublexer::FirstLexer::FirstLexer() : delimiter_(new sublexer::NormalDelimiter)
+{
+}
+
+smart_ptr<sublexer::ISubLexer> sublexer::FirstLexer::lex(smart_ptr<utf8::UTF8InputStream>& stream)
{
// chにはlexerから渡された、今回読みだした文字が渡されている。
smart_ptr<sublexer::ISubLexer> ret;
- // ()[]`',.は構文解析の重要な要素となるため、このまま返す。
- if (ch.toUTF16Code() == '(' || ch.toUTF16Code() == '[')
- {
- lexeme_ = lexeme::makeOpenParen();
- }
+ UTF8String str;
+ while (!stream->isEOF() && lexeme_.isNull()) {
+ // 加算して様子を見る。
+ // 読出した文字がデリミタであり、lexemeが確定していない場合に
+ // は、そのまま続けて読出すことにする。
+ UTF8Char ch(stream->read());
+ if (delimiter_->isDelimiter(ch)) {
+ continue;
+ }
+
+ str += stream->read();
+ // ()[]`'が最初だった場合、さっさと消えることにする。
+ if (str[0].toUTF16Code() == '(' || str[0].toUTF16Code() == '[')
+ {
+ lexeme_ = lexeme::makeOpenParen();
+ }
- if (ch.toUTF16Code() == ')' || ch.toUTF16Code() == ']')
- {
- lexeme_ = lexeme::makeCloseParen();
- }
+ if (str[0].toUTF16Code() == ')' || str[0].toUTF16Code() == ']')
+ {
+ lexeme_ = lexeme::makeCloseParen();
+ }
- if (ch.toUTF16Code() == '`')
- {
- lexeme_ = lexeme::makeBackQuote();
- }
+ if (str[0].toUTF16Code() == '`')
+ {
+ lexeme_ = lexeme::makeBackQuote();
+ }
- if (ch.toUTF16Code() == '\'')
- {
- lexeme_ = lexeme::makeQuote();
- }
+ if (str[0].toUTF16Code() == '\'')
+ {
+ lexeme_ = lexeme::makeQuote();
+ }
- if (ch.toUTF16Code() == '.')
- {
- lexeme_ = lexeme::makeDot();
- }
+ if (str[0].toUTF16Code() == '.')
+ {
+ // 次の文字がデリミタで終了していなければならない。
+ lexeme_ = lexeme::makeDot();
+ }
- if (ch.toUTF16Code() == ',' || ch.toUTF16Code() == '#')
- {
- // ,や#の場合、次に別の文字が続く可能性があるため、NextLexemeLexerを
- // 呼び出すようにしておく。
- ret.add(new sublexer::CNextLexemeLexer());
- }
+ if (str[0].toUTF16Code() == ',' || str[0].toUTF16Code() == '#')
+ {
+ // 最初の一文字だけでは判別できないため、一文字先読みして
+ // から決定する。
+
+ }
- if (ch.toUTF16Code() == '"')
- {
- // 先頭が"の場合、stringと判断される。
- ret.add(new sublexer::CStringLexer());
+ if (str[0].toUTF16Code() == '"')
+ {
+ // 先頭が"の場合、stringと判断される。
+ ret.add(new sublexer::StringLexer());
+ }
}
-
// 基本的に判定できないことはありえない。
return ret;
}
-smart_ptr<lexeme::ILexeme> sublexer::CFirstLex::getLexeme()
+smart_ptr<lexeme::ILexeme> sublexer::FirstLexer::getLexeme()
{
return smart_ptr<lexeme::ILexeme>();
}
//================================================================================
-smart_ptr<sublexer::ISubLexer> sublexer::CStringLexer::lex(
- const utf8_string::CUTF8Char& ch,
- const utf8_string::CUTF8String& str,
- smart_ptr<utf8::CUTF8InputStream>& stream
+smart_ptr<sublexer::ISubLexer> sublexer::StringLexer::lex(
+ smart_ptr<utf8::UTF8InputStream>& stream
)
{
return smart_ptr<ISubLexer>();
}
-smart_ptr<lexeme::ILexeme> sublexer::CStringLexer::getLexeme()
+smart_ptr<lexeme::ILexeme> sublexer::StringLexer::getLexeme()
{
return lexeme_;
}
//================================================================================
-smart_ptr<sublexer::ISubLexer> sublexer::CNextLexemeLexer::lex(
- const utf8_string::CUTF8Char& ch,
- const utf8_string::CUTF8String& str,
- smart_ptr<utf8::CUTF8InputStream>& stream
- )
-{
-
- smart_ptr<sublexer::ISubLexer> ret;
- // 二文字目が特殊であるようなデータを判別するためのlexer。
- if (str.size() == 1)
- {
- return checkSecondChar(ch, str, stream);
- }
-
-
- return smart_ptr<ISubLexer>();
-}
-
-smart_ptr<lexeme::ILexeme> sublexer::CNextLexemeLexer::getLexeme()
-{
- return lexeme_;
-}
-
-smart_ptr<sublexer::ISubLexer> sublexer::CNextLexemeLexer::checkSecondChar(
- const utf8_string::CUTF8Char& ch,
- const utf8_string::CUTF8String& str,
- smart_ptr<utf8::CUTF8InputStream>& stream
+smart_ptr<sublexer::ISubLexer> sublexer::OneLineCommentLexer::lex(
+ smart_ptr<utf8::UTF8InputStream>& stream
)
{
smart_ptr<sublexer::ISubLexer> ret;
#define _SUBLEXER_IMPL_H_
#include "sublexer.h"
-#include "utf8_string.h"
#include "smart_ptr.h"
#include "utf8.h"
+#include "delimiter.h"
namespace utakata {
namespace sublexer {
-
- class CFirstLex : public ISubLexer
+ class FirstLexer : public ISubLexer
{
// lex関数の内部で最初に実行される。
// ここから返されない場合は、一文字の構文構成文字が返されるということになる。
public:
+ FirstLexer();
+ virtual ~FirstLexer() {}
- smart_ptr<ISubLexer> lex(const utakata::utf8_string::CUTF8Char& ch,
- const utakata::utf8_string::CUTF8String& str,
- smart_ptr<utakata::utf8::CUTF8InputStream>& stream);
+ smart_ptr<ISubLexer> lex(smart_ptr<utakata::utf8::UTF8InputStream>& stream);
smart_ptr<utakata::lexeme::ILexeme> getLexeme();
private:
// 返すべきILexemeが確定した場合に、ここに格納する。
smart_ptr<utakata::lexeme::ILexeme> lexeme_;
+ smart_ptr<utakata::sublexer::IDelimiter> delimiter_;
};
- class CNextLexemeLexer : public ISubLexer
+ class StringLexer : public ISubLexer
{
- // 1文字目だけでは判別できなかった構文に対して実行される。
+ // 文字列だと判断された場合に実行されるsublexer。
+ // 文字列が不正に終わったりしている場合には、その時点で例
+ // 外を発行する。
public:
- CNextLexemeLexer(){}
- virtual ~CNextLexemeLexer(){}
-
- smart_ptr<ISubLexer> lex(const utakata::utf8_string::CUTF8Char& ch,
- const utakata::utf8_string::CUTF8String& str,
- smart_ptr<utakata::utf8::CUTF8InputStream>& stream);
+ StringLexer() {}
+ virtual ~StringLexer() {}
+
+ smart_ptr<ISubLexer> lex(smart_ptr<utakata::utf8::UTF8InputStream>& stream);
smart_ptr<utakata::lexeme::ILexeme> getLexeme();
private:
-
- smart_ptr<ISubLexer> checkSecondChar(
- const utakata::utf8_string::CUTF8Char& ch,
- const utakata::utf8_string::CUTF8String& str,
- smart_ptr<utakata::utf8::CUTF8InputStream>& stream
- );
-
// 返すべきILexemeが確定した場合に、ここに格納する。
smart_ptr<utakata::lexeme::ILexeme> lexeme_;
+
};
-
- class CStringLexer : public ISubLexer
+ class OneLineCommentLexer : public ISubLexer
{
- // 文字列だと判断された場合に実行されるsublexer。
- // 文字列が不正に終わったりしている場合には、その時点で例
- // 外を発行する。
+ // コメントを返す。
+ // と言っても、;から開始されるコメントは完全に無視されるので、lexeme
+ // を保存する必要すらない。
public:
- CStringLexer() {}
- virtual ~CStringLexer() {}
- smart_ptr<ISubLexer> lex(const utakata::utf8_string::CUTF8Char& ch,
- const utakata::utf8_string::CUTF8String& str,
- smart_ptr<utakata::utf8::CUTF8InputStream>& stream);
+ OneLineCommentLexer(){}
+ virtual ~OneLineCommentLexer(){}
- smart_ptr<utakata::lexeme::ILexeme> getLexeme();
+ smart_ptr<ISubLexer> lex(smart_ptr<utakata::utf8::UTF8InputStream>& stream);
- private:
- // 返すべきILexemeが確定した場合に、ここに格納する。
- smart_ptr<utakata::lexeme::ILexeme> lexeme_;
+ smart_ptr<utakata::lexeme::ILexeme> getLexeme();
};
-
};
};
using namespace std;
using namespace utakata;
-bool lexer_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool lexer_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::stringstream ss;
ss << "==========" << endl;
ss << "(hoge)" << endl;
- textarrayformat::CTextArrayReader reader(ss);
+ textarrayformat::TextArrayReader reader(ss);
smart_ptr<istream> formats(new stringstream(reader.get()));
- smart_ptr<utakata::utf8::CUTF8InputStream> st;
- st.add(new utakata::utf8::CUTF8InputStream(formats));
+ smart_ptr<utakata::utf8::UTF8InputStream> st;
+ st.add(new utakata::utf8::UTF8InputStream(formats));
- utakata::lexer::CLexer lexer;
+ utakata::lexer::Lexer lexer;
smart_ptr<lexeme::ILexeme> m(lexer.lex(st));
asserter->check(m->toString()->toStr(), "(");
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("main lexer test");
+ simpletest::SimpleTestSuite suite("main lexer test");
suite.addTester(sfcr::screate(lexer_test, suite.getAsserter()));
// suite.addTester(sfcr::screate(utf8_string_test, suite.getAsserter()));
// suite.addTester(sfcr::screate(utf8_string_util_test, suite.getAsserter()));
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("sublexer's test");
+ simpletest::SimpleTestSuite suite("sublexer's test");
// suite.addTester(sfcr::screate(utf8_multichar_test, suite.getAsserter()));
// suite.addTester(sfcr::screate(utf8_string_test, suite.getAsserter()));
// suite.addTester(sfcr::screate(utf8_string_util_test, suite.getAsserter()));
using namespace std;
-bool taf_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool taf_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::stringstream ss;
ss << "=====" << endl;
ss << "test\ntest" << endl;
- textarrayformat::CTextArrayReader reader(ss);
+ textarrayformat::TextArrayReader reader(ss);
asserter->check(reader.get(), "test\ntest\n");
asserter->check(reader.get(1), "testhoge\n");
asserter->check(reader.get(0), "test\ntest\n");
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("TextArrayFormat");
+ simpletest::SimpleTestSuite suite("TextArrayFormat");
suite.addTester(sfcr::screate(taf_test, suite.getAsserter()));
suite.run();
return 0;
#include "../utf8_string.h"
#include "../TextArrayFormat.h"
-bool utf8_multichar_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_multichar_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::string tmp("あいuえお");
// 含めたテスト
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
// 単独のreadを試す。
- utakata::utf8_string::CUTF8Char ch(stream.read());
+ utakata::utf8_string::UTF8Char ch(stream.read());
asserter->check(ch.toUTF16Code(), utakata::utf8::generateUTF8Code("あ"), "通常read失敗");
// peekが問題なく働いていることのテスト
- utakata::utf8_string::CUTF8Char ch2(stream.peek());
+ utakata::utf8_string::UTF8Char ch2(stream.peek());
asserter->check(ch2.toUTF16Code(), utakata::utf8::generateUTF8Code("い"), "peek失敗");
- utakata::utf8_string::CUTF8Char ch3(stream.read());
+ utakata::utf8_string::UTF8Char ch3(stream.read());
asserter->check(ch3.toUTF16Code(), utakata::utf8::generateUTF8Code("い"), "peek後read失敗");
// asciiだとしても問題無く読みだせるはず。
- utakata::utf8_string::CUTF8Char ch4(stream.peek());
+ utakata::utf8_string::UTF8Char ch4(stream.peek());
asserter->check(ch4.toUTF16Code(), 'u');
// 同一コードなので比較して同じになるはず。
return asserter->isOk();
}
-bool utf8_string_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_string_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
// マルチバイトとascii文字の混在文字も正しく扱うことのできる
// CUTF8Stringのテスト
std::string tmp("ああいうえsssお");
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
- utakata::utf8_string::CUTF8Char ch(stream.read());
+ utakata::utf8_string::UTF8Char ch(stream.read());
- utakata::utf8_string::CUTF8String str(stream.read(5));
+ utakata::utf8_string::UTF8String str(stream.read(5));
asserter->check(str.begin()->toStr(), "あ");
asserter->check(str.size(), 5);
return asserter->isOk();
}
-bool utf8_string_util_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_string_util_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
// CUTF8Stringと共に利用するためのユーティリティ関数の操作を
// 行う。
std::string tmp("あいうえsssお");
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
- utakata::utf8_string::CUTF8String str(stream.read(5));
- utakata::utf8_string::CUTF8String str2(stream.read(3));
- utakata::utf8_string::CUTF8String str3 = str;
+ utakata::utf8_string::UTF8String str(stream.read(5));
+ utakata::utf8_string::UTF8String str2(stream.read(3));
+ utakata::utf8_string::UTF8String str3 = str;
// 挿入してみる。
str.insert(str.begin(), str2.begin(), str2.end());
asserter->check(str3.toStr(), "あsいうえsssお");
// 互いに加算できる。
- utakata::utf8_string::CUTF8String str4 = str + str2;
+ utakata::utf8_string::UTF8String str4 = str + str2;
asserter->check(str4.toStr(), "ssおあいうえsssお");
return asserter->isOk();
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("UTF-8 文字列テスト");
+ simpletest::SimpleTestSuite suite("UTF-8 文字列テスト");
suite.addTester(sfcr::screate(utf8_multichar_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_string_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_string_util_test, suite.getAsserter()));
char operator()(unsigned char t) {return static_cast<char>(t);}
};
-bool utf8_charcheck_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_charcheck_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
// UTF-8の文字を認識するテスト。
// 1byteの文字のみの場合
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
// 単独のreadを試す。
asserter->check(stream.read()[0], 'U');
return asserter->isOk();
}
-bool utf8_multichar_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_multichar_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::string tmp("あいうえお");
// 1byteの文字のみの場合
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
// 複数文字の読み出しのチェック
// 但し、ここでは全体が等しいかどうかを返すに留まる。
return asserter->isOk();
}
-bool utf8_unget_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_unget_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::string tmp("あいうえお");
// 1byteの文字のみの場合
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
// 複数文字の読み出しのチェック
// 但し、ここでは全体が等しいかどうかを返すに留まる。
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("UTF-8 基本テスト");
+ simpletest::SimpleTestSuite suite("UTF-8 基本テスト");
suite.addTester(sfcr::screate(utf8_charcheck_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_multichar_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_unget_test, suite.getAsserter()));
using namespace std;;
using namespace utakata::utf8;
-CUTF8InputStream::CUTF8InputStream() : EOF_(0xff), strm_()
+UTF8InputStream::UTF8InputStream() : EOF_(0xff), strm_()
{
}
-CUTF8InputStream::CUTF8InputStream(const smart_ptr<std::istream>& strm) : EOF_(0xff), strm_(strm)
+UTF8InputStream::UTF8InputStream(const smart_ptr<std::istream>& strm) : EOF_(0xff), strm_(strm)
{
}
-bool CUTF8InputStream::open(const smart_ptr<std::istream>& strm)
+bool UTF8InputStream::open(const smart_ptr<std::istream>& strm)
{
//現在保持しているストリームと切り替える。
// 基本的にただスワップするだけで問題ない。
return true;
}
-std::vector<unsigned char> CUTF8InputStream::read()
+std::vector<unsigned char> UTF8InputStream::read()
{
// UTF-8の一文字を読みだして返す。
// UTF-8に該当しない場合、空のvectorを返す。
if (!strm_->good()) {
- throw CStreamException("not ready input stream");
+ throw StreamException("not ready input stream");
}
// 最初に一文字だけ読みだして、チェックをかける。
return std::vector<unsigned char>(EOF_);
}
-std::vector<unsigned char> CUTF8InputStream::read(int num)
+std::vector<unsigned char> UTF8InputStream::read(int num)
{
// 指定された文字分だけ読みだしてくる。
// 途中で終了した場合、その文字の分だけunsigned charが減少すること
return rtn;
}
-std::vector<unsigned char> CUTF8InputStream::peek()
+std::vector<unsigned char> UTF8InputStream::peek()
{
// 一文字分だけ先読みする。先読みした場合、文字は戻す。
std::vector<unsigned char> tmp = this->read();
return tmp;
}
-void CUTF8InputStream::unget(const std::vector<unsigned char>& ch)
+void UTF8InputStream::unget(const std::vector<unsigned char>& ch)
{
// 渡されたバイト列をストリームに差し戻す。
size_t t = 0;
}
}
-bool utakata::utf8::CUTF8InputStream::isEOF() const
+bool utakata::utf8::UTF8InputStream::isEOF() const
{
if (strm_->good())
{
namespace utf8 {
// inputstreamの準備が出来ていない場合に送出される例外
- class CStreamException : public std::exception
+ class StreamException : public std::exception
{
public:
- CStreamException(const std::string& str) : str_(str) {}
- virtual ~CStreamException() throw() {}
+ StreamException(const std::string& str) : str_(str) {}
+ virtual ~StreamException() throw() {}
const char* what() throw() {
return str_.c_str();
std::string str_;
};
- class CUTF8InputStream : public IInputStream
+ class UTF8InputStream : public IInputStream
{
/**
入力ストリームから、UTF-8のデータを指定した文字だけ読みだして
// 入力に利用するストリームは最初に渡される。
// 最初に渡さない場合には、後から開けるようにしておかなけりゃならない。
- CUTF8InputStream();
- CUTF8InputStream(const smart_ptr<std::istream>& strm);
- virtual ~CUTF8InputStream(){}
+ UTF8InputStream();
+ UTF8InputStream(const smart_ptr<std::istream>& strm);
+ virtual ~UTF8InputStream(){}
bool open(const smart_ptr<std::istream>& strm);
//================================================================================
-utakata::utf8_string::CUTF8Char::CUTF8Char(const std::vector<unsigned char>& utf8) : utf8_bytes_(utf8), utf16_code_(0)
+utakata::utf8_string::UTF8Char::UTF8Char(const std::vector<unsigned char>& utf8) : utf8_bytes_(utf8), utf16_code_(0)
{
this->utf16_code_ = utakata::utf8::generateUTF8Code(utf8_bytes_);
}
-utakata::utf8_string::CUTF8Char::CUTF8Char(const utakata::utf8_string::CUTF8Char& ch)
+utakata::utf8_string::UTF8Char::UTF8Char(const utakata::utf8_string::UTF8Char& ch)
{
// 単純にそれぞれの値をコピーする。
this->utf8_bytes_ = ch.utf8_bytes_;
utf16_code_ = ch.utf16_code_;
}
-utakata::utf8_string::CUTF8Char& utakata::utf8_string::CUTF8Char::operator=(const utakata::utf8_string::CUTF8Char& ch)
+utakata::utf8_string::UTF8Char& utakata::utf8_string::UTF8Char::operator=(const utakata::utf8_string::UTF8Char& ch)
{
// 安全なスワップを利用する。
- CUTF8Char c(ch);
+ UTF8Char c(ch);
swap(c);
return *this;
}
-bool utakata::utf8_string::CUTF8Char::operator==(const utakata::utf8_string::CUTF8Char& ch) const
+bool utakata::utf8_string::UTF8Char::operator==(const utakata::utf8_string::UTF8Char& ch) const
{
- // 全てのCUTF8Charが保持しているUTF16変換が施された
+ // 全てのUTF8Charが保持しているUTF16変換が施された
// コードで比較を行う。実際にはlongでの比較なのでかなり速い。
return ch.utf16_code_ == utf16_code_;
}
-bool utakata::utf8_string::CUTF8Char::operator!=(const utakata::utf8_string::CUTF8Char& ch) const
+bool utakata::utf8_string::UTF8Char::operator!=(const utakata::utf8_string::UTF8Char& ch) const
{
return !(*this == ch);
}
-bool CUTF8Char::operator<(const CUTF8Char& ch) const
+bool UTF8Char::operator<(const UTF8Char& ch) const
{
return utf16_code_ < ch.utf16_code_;
}
-bool CUTF8Char::operator>(const CUTF8Char& ch) const
+bool UTF8Char::operator>(const UTF8Char& ch) const
{
return utf16_code_ > ch.utf16_code_;
}
-void utakata::utf8_string::CUTF8Char::swap(utakata::utf8_string::CUTF8Char& ch)
+void utakata::utf8_string::UTF8Char::swap(utakata::utf8_string::UTF8Char& ch)
{
// 値と標準コンテナなので、特に問題なく動作する。
std::swap(utf16_code_, ch.utf16_code_);
std::swap(utf8_bytes_, ch.utf8_bytes_);
}
-std::string utakata::utf8_string::CUTF8Char::toStr() const
+std::string utakata::utf8_string::UTF8Char::toStr() const
{
// 単純に置換が行える。
std::string tmp;
return tmp;
}
-bool utakata::utf8_string::is_ascii_char(const CUTF8Char& ch)
+bool utakata::utf8_string::is_ascii_char(const UTF8Char& ch)
{
// 0x7f >= ascii >= 0x00 がasciiなので、その範囲で判定を行う。
if (ch.toUTF16Code() >= 0 && ch.toUTF16Code() < 0x80
return false;
}
-bool utakata::utf8_string::is_eof(const CUTF8Char& ch)
+bool utakata::utf8_string::is_eof(const UTF8Char& ch)
{
return ch.getBytes()[0] == 0xff ? true : false;
}
//================================================================================
-utakata::utf8_string::CUTF8String::CUTF8String() : chars_()
+utakata::utf8_string::UTF8String::UTF8String() : chars_()
{
}
-utakata::utf8_string::CUTF8String::CUTF8String(
+utakata::utf8_string::UTF8String::UTF8String(
const std::vector<unsigned char>& bytes) : chars_()
{
assign(bytes);
}
-utakata::utf8_string::CUTF8String::CUTF8String(
- const CUTF8String& str) : chars_(str.chars_)
+utakata::utf8_string::UTF8String::UTF8String(
+ const UTF8String& str) : chars_(str.chars_)
{
}
-void CUTF8String::assign(const std::vector<unsigned char>& bytes)
+void UTF8String::assign(const std::vector<unsigned char>& bytes)
{
// 与えられたbytesを順次utf8charに変換していく。
// 与えられたbytesのうち、有効なデータのみを変換していく。
- std::vector<CUTF8Char> chars;
+ std::vector<UTF8Char> chars;
std::vector<unsigned char>::const_iterator it = bytes.begin(),
end = bytes.end();
std::swap(chars_, chars);
}
-void CUTF8String::assign(const CUTF8String& str)
+void UTF8String::assign(const UTF8String& str)
{
//基本的に=で渡した場合と全く同じなので、そのようにする。
- CUTF8String tmp(str);
+ UTF8String tmp(str);
swap(tmp);
}
-CUTF8String& CUTF8String::operator=(const CUTF8String& str)
+UTF8String& UTF8String::operator=(const UTF8String& str)
{
assign(str);
return *this;
}
-void CUTF8String::swap(CUTF8String& str)
+void UTF8String::swap(UTF8String& str)
{
// シンプルにswapを行う。
std::swap(chars_, str.chars_);
}
-CUTF8String& CUTF8String::operator+=(const CUTF8String& str)
+UTF8String& UTF8String::operator+=(const UTF8String& str)
{
// 一度コピーと加算してから実際にswapさせる。
- CUTF8String tmp(str);
+ UTF8String tmp(str);
chars_.insert(chars_.end(), tmp.chars_.begin(), tmp.chars_.end());
return *this;
}
-CUTF8String& CUTF8String::operator+=(const std::vector<unsigned char>& ch)
+UTF8String& UTF8String::operator+=(const std::vector<unsigned char>& ch)
{
// 実際には文字を設定するのに利用される。
// また、これを定義しておくことで、streamからの結果を直接設定することができる。
- CUTF8String tmp(ch);
+ UTF8String tmp(ch);
chars_.insert(chars_.end(), tmp.chars_.begin(), tmp.chars_.end());
return *this;
}
-CUTF8String& CUTF8String::operator+=(const CUTF8Char& ch)
+UTF8String& UTF8String::operator+=(const UTF8Char& ch)
{
// 実際には文字を設定するのに利用される。
// また、これを定義しておくことで、streamからの結果を直接設定することができる。
- CUTF8String tmp(ch.getBytes());
+ UTF8String tmp(ch.getBytes());
chars_.insert(chars_.end(), tmp.chars_.begin(), tmp.chars_.end());
return *this;
}
-std::string CUTF8String::toStr() const
+std::string UTF8String::toStr() const
{
// 文字列に変換する。
std::string ret;
std::for_each(chars_.begin(), chars_.end(),
- CUTF8StringToString<CUTF8Char>(ret));
+ UTF8StringToString<UTF8Char>(ret));
return ret;
}
-void CUTF8String::insert(CUTF8String::utf8iterator it, CUTF8String::utf8iterator begin,
- CUTF8String::utf8iterator last)
+void UTF8String::insert(UTF8String::utf8iterator it, UTF8String::utf8iterator begin,
+ UTF8String::utf8iterator last)
{
// 渡されたのは実際にはvectorのイテレータなので、
// そのままvectorの実装に任せることができる。
chars_.insert(it, begin, last);
}
-void CUTF8String::insert(CUTF8String::utf8iterator it,
- CUTF8String::const_utf8iterator begin,
- CUTF8String::const_utf8iterator last)
+void UTF8String::insert(UTF8String::utf8iterator it,
+ UTF8String::const_utf8iterator begin,
+ UTF8String::const_utf8iterator last)
{
// 渡されたのがconstであるかどうかというだけの違いであるため、
// そのまま渡すことができる。
//================================================================================
-std::string utakata::utf8_string::substring(const CUTF8String& str, size_t begin, size_t end)
+std::string utakata::utf8_string::substring(const UTF8String& str, size_t begin, size_t end)
{
if (end == 0)
{
// 先頭から末尾までを取得する。
std::string ret;
std::for_each(str.begin() + begin, str.end(),
- CUTF8StringToString<CUTF8Char>(ret));
+ UTF8StringToString<UTF8Char>(ret));
return ret;
}
else if (begin <= end)
{
std::string ret;
std::for_each(str.begin() + begin, str.begin() + (begin + end),
- CUTF8StringToString<CUTF8Char>(ret));
+ UTF8StringToString<UTF8Char>(ret));
return ret;
}
else
}
}
-CUTF8String utakata::utf8_string::operator+(const CUTF8String& lh, const CUTF8String& rh)
+UTF8String utakata::utf8_string::operator+(const UTF8String& lh, const UTF8String& rh)
{
// 双方をコピーして加算して返す。凄い負荷が高い。
- CUTF8String str(lh);
+ UTF8String str(lh);
str += rh;
return str;
}
-CUTF8String utakata::utf8_string::operator+(const CUTF8String& lh, const CUTF8Char& rh)
+UTF8String utakata::utf8_string::operator+(const UTF8String& lh, const UTF8Char& rh)
{
// 文字と加算する。
- CUTF8String tmp(lh);
+ UTF8String tmp(lh);
tmp += rh.getBytes();
return tmp;
}
-CUTF8String utakata::utf8_string::operator+(const CUTF8Char& lh, const CUTF8String& rh)
+UTF8String utakata::utf8_string::operator+(const UTF8Char& lh, const UTF8String& rh)
{
- CUTF8String tmp(lh.getBytes());
+ UTF8String tmp(lh.getBytes());
tmp += rh;
return tmp;
}
std::string str_;
};
- class CUTF8Char
+ class UTF8Char
{
/**
UTF8と判断されたバイト列を受け取り、実際の値を返す。
public:
// バイト列を必ず渡す必要がある。
- CUTF8Char(const std::vector<unsigned char>& utf8);
- virtual ~CUTF8Char(){}
+ UTF8Char(const std::vector<unsigned char>& utf8);
+ virtual ~UTF8Char(){}
// コピーコンストラクタを宣言したため、同時にoperator=を宣言する。
- CUTF8Char(const CUTF8Char& ch);
- CUTF8Char& operator=(const CUTF8Char& ch);
+ UTF8Char(const UTF8Char& ch);
+ UTF8Char& operator=(const UTF8Char& ch);
// 各演算子のオーバーロード。
// <=と>=は、それぞれ>の結果のnot、<の結果のnotを
// 用いることで実装できるため、この二つだけ供えていれば問題ない。
// また、比較には内部で保持しているutf16_code_を用いるため、
// 速度面で気にする必要は無い。
- bool operator==(const CUTF8Char& code) const;
- bool operator<(const CUTF8Char& code) const;
- bool operator>(const CUTF8Char& code) const;
- bool operator!=(const CUTF8Char& code) const;
+ bool operator==(const UTF8Char& code) const;
+ bool operator<(const UTF8Char& code) const;
+ bool operator>(const UTF8Char& code) const;
+ bool operator!=(const UTF8Char& code) const;
// UTF8->UTF16に変換したコードを返す。
long toUTF16Code() const {return this->utf16_code_;}
// 文字列として変換して返す。
std::string toStr() const;
- // 渡されたCUTF8Charの内部と交換する。
- void swap(CUTF8Char& ch);
+ // 渡されたUTF8Charの内部と交換する。
+ void swap(UTF8Char& ch);
private:
long utf16_code_;
};
- // 渡されたCUTF8Charがasciiコードの範囲内に収まっているかどうかを返す。
- bool is_ascii_char(const CUTF8Char& ch);
+ // 渡されたUTF8Charがasciiコードの範囲内に収まっているかどうかを返す。
+ bool is_ascii_char(const UTF8Char& ch);
// UTF8では先頭1バイトが0xffになることはありえないので、
// 先頭1バイトが0xffの場合には、これは終端記号であるとした。
- bool is_eof(const CUTF8Char& ch);
+ bool is_eof(const UTF8Char& ch);
//================================================================================
- class CUTF8String
+ class UTF8String
{
// UTF8の文字列を保持するためのコンテナ。
// 相互での比較などもサポートし、utakataの内部全般で
public:
// イテレータとして簡単に利用するためのtypedefマクロ
- typedef std::vector<CUTF8Char>::iterator utf8iterator;
- typedef std::vector<CUTF8Char>::const_iterator const_utf8iterator;
+ typedef std::vector<UTF8Char>::iterator utf8iterator;
+ typedef std::vector<UTF8Char>::const_iterator const_utf8iterator;
public:
- CUTF8String();
+ UTF8String();
- CUTF8String(const std::vector<unsigned char>& bytes);
- CUTF8String(const CUTF8String& str);
- virtual ~CUTF8String(){}
+ UTF8String(const std::vector<unsigned char>& bytes);
+ UTF8String(const UTF8String& str);
+ virtual ~UTF8String(){}
// 実体に代入する。代入が行われなかった場合、元のデータ
// は保存される。
void assign(const std::vector<unsigned char>& bytes);
- void assign(const CUTF8String& str);
+ void assign(const UTF8String& str);
// iteratorを取得する。
const_utf8iterator begin() const {return chars_.begin();}
utf8iterator end() {return chars_.end();}
// []をオーバーロードする。これは常に境界のチェックを行う。
- const CUTF8Char& operator[](size_t t) const {return chars_.at(t);}
- CUTF8Char& operator[](size_t t) {
- return const_cast<CUTF8Char&>(
- static_cast<const CUTF8String*>(this)->chars_[t]);}
+ const UTF8Char& operator[](size_t t) const {return chars_.at(t);}
+ UTF8Char& operator[](size_t t) {
+ return const_cast<UTF8Char&>(
+ static_cast<const UTF8String*>(this)->chars_[t]);}
// サイズを取得する。
size_t size() const {return chars_.size();}
// 安全なswapと共に提供する。
- CUTF8String& operator=(const CUTF8String& str);
- void swap(CUTF8String& str);
+ UTF8String& operator=(const UTF8String& str);
+ void swap(UTF8String& str);
// 加算のみをサポートする。
- CUTF8String& operator+=(const CUTF8String& str);
- CUTF8String& operator+=(const std::vector<unsigned char>& ch);
- CUTF8String& operator+=(const CUTF8Char& ch);
+ UTF8String& operator+=(const UTF8String& str);
+ UTF8String& operator+=(const std::vector<unsigned char>& ch);
+ UTF8String& operator+=(const UTF8Char& ch);
// std::stringへ変換する。ただし、std::string上でのinsertなどは
// 保証できない。
private:
- std::vector<CUTF8Char> chars_;
+ std::vector<UTF8Char> chars_;
};
- CUTF8String operator+(const CUTF8String& lh, const CUTF8String& rh);
- CUTF8String operator+(const CUTF8String& lh, const CUTF8Char& rh);
- CUTF8String operator+(const CUTF8Char& lh, const CUTF8String& rh);
+ UTF8String operator+(const UTF8String& lh, const UTF8String& rh);
+ UTF8String operator+(const UTF8String& lh, const UTF8Char& rh);
+ UTF8String operator+(const UTF8Char& lh, const UTF8String& rh);
// substringの実装を行う。
// [begin, end)までの文字を文字列として返す。
// endが渡されないか、0が渡された場合、beginから末尾までが返される。
- std::string substring(const CUTF8String& str, size_t begin, size_t end = 0);
+ std::string substring(const UTF8String& str, size_t begin, size_t end = 0);
template<class T>
- class CUTF8StringToString : public std::unary_function<T, void>
+ class UTF8StringToString : public std::unary_function<T, void>
{
// イテレータを受け取り、std::stringを初期化引数で渡されたものに
// コピーしていく。
public:
- CUTF8StringToString(std::string& str) : ret_(str) {}
+ UTF8StringToString(std::string& str) : ret_(str) {}
void operator()(const T& it) {
ret_ += it.toStr();
}
#include "../utf8_string.h"
#include "../TextArrayFormat.h"
-bool utf8_multichar_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_multichar_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
std::string tmp("あいuえお");
// 含めたテスト
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
// 単独のreadを試す。
- utakata::utf8_string::CUTF8Char ch(stream.read());
+ utakata::utf8_string::UTF8Char ch(stream.read());
asserter->check(ch.toUTF16Code(), utakata::utf8::generateUTF8Code("あ"));
// peekが問題なく働いていることのテスト
- utakata::utf8_string::CUTF8Char ch2(stream.peek());
+ utakata::utf8_string::UTF8Char ch2(stream.peek());
asserter->check(ch2.toUTF16Code(), utakata::utf8::generateUTF8Code("い"));
- utakata::utf8_string::CUTF8Char ch3(stream.read());
+ utakata::utf8_string::UTF8Char ch3(stream.read());
asserter->check(ch3.toUTF16Code(), utakata::utf8::generateUTF8Code("い"));
// asciiだとしても問題無く読みだせるはず。
- utakata::utf8_string::CUTF8Char ch4(stream.peek());
+ utakata::utf8_string::UTF8Char ch4(stream.peek());
asserter->check(ch4.toUTF16Code(), 'u');
// ascii文字の範囲であるかどうかを判定する関数のテスト。
return asserter->isOk();
}
-bool utf8_string_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_string_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
// マルチバイトとascii文字の混在文字も正しく扱うことのできる
// CUTF8Stringのテスト
std::string tmp("あいうえsssお");
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
- utakata::utf8_string::CUTF8String str(stream.read(5));
+ utakata::utf8_string::UTF8String str(stream.read(5));
asserter->check(str.begin()->toStr(), "あ");
asserter->check(str.size(), 5);
return asserter->isOk();
}
-bool utf8_string_util_test(smart_ptr<simpletest::CSimpleTestAsserter> asserter)
+bool utf8_string_util_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
{
// CUTF8Stringと共に利用するためのユーティリティ関数の操作を
// 行う。
std::string tmp("あいうえsssお");
smart_ptr<std::istream> ss(new std::stringstream(tmp));
- utakata::utf8::CUTF8InputStream stream(ss);
+ utakata::utf8::UTF8InputStream stream(ss);
- utakata::utf8_string::CUTF8String str(stream.read(5));
- utakata::utf8_string::CUTF8String str2(stream.read(3));
- utakata::utf8_string::CUTF8String str3 = str;
+ utakata::utf8_string::UTF8String str(stream.read(5));
+ utakata::utf8_string::UTF8String str2(stream.read(3));
+ utakata::utf8_string::UTF8String str3 = str;
// 挿入してみる。
str.insert(str.begin(), str2.begin(), str2.end());
int main(int argc, char *argv[])
{
- simpletest::CSimpleTestSuite suite("UTF-8 文字列テスト");
+ simpletest::SimpleTestSuite suite("UTF-8 文字列テスト");
suite.addTester(sfcr::screate(utf8_multichar_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_string_test, suite.getAsserter()));
suite.addTester(sfcr::screate(utf8_string_util_test, suite.getAsserter()));
{
//オペランドの配列をそのまま処理する。
- for_each(ops.begin(), ops.end(), vm::COperandRunner(this->cpu_));
+ //for_each(ops.begin(), ops.end(), vm::OperandRunner(this->cpu_));
return 0;
}