#include "src/exception_macro.h"
#include "src/lexer/string_lexer.h"
-#include "src/lexer/delimiters.h"
+#include "src/lexer/term_lexer.h"
+#include "src/lexer/term_checker.h"
#include "src/lexeme.h"
#include "src/encoding_reader.h"
#include "src/unicode.h"
namespace lexer = utakata::lexer;
-namespace delimiter = utakata::lexer_delimiter;
+namespace term = utakata::lexer::term;
namespace reader = utakata::reader;
namespace unicode = utakata::unicode;
-// 宣言のコメントを参照してください。
-bool lexer::StringDispatchTerm::IsDispatch(
- const unicode::UniString& string) const {
- if (!string.IsEmpty() && string.At(0).rawcode() == '"') {
- return true;
+// 宣言のコメントを参照して下さい。
+bool lexer::EscapeLexer::Lex(reader::EncodingReader* reader,
+ unsigned int* code) {
+ unicode::UniString escape(reader->Read(kEscapeValidLength));
+ if (escape.IsEmpty() || escape.At(0).rawcode != '\\') {
+ return false;
}
- return false;
+ if (escape.GetSize() < kEscapeValidLength) {
+ THROW_EXCEPTION_(lexer::LexException,
+ unicode::Convert("invalid escape seacense"));
+ }
+
+ term::IntralineWhiteSpaceChecker intraline;
+ term::LineEndingChecker lineend;
+ if (!CheckEscapeSeacense(escape.At(1)) && !intraline(escape.At(1)) &&
+ !lineend(escape.At(1))) {
+ unicode::UniString encoded_string("invalid escape seacense : ");
+ encoded_string.Append(escape);
+ THROW_EXCEPTION_(lexer::LexException, encoded_string);
+ }
+
+ if (!intraline(escape.At(1)) && !lineend(escape.At(1))) {
+ *code = ConvertEscapeToCode(escape);
+ } else {
+ reader->Read(kEscapeValidLength);
+ unicode::UniChar checker(escape.At(1));
+ while (intraline(checker) && !reader->IsEof()) {
+ checker = unicode::UniChar(reader->Read());
+ }
+
+ if (!lineend(checker)) {
+ unicode::UniString encoded_string;
+ THROW_EXCEPTION_(lexer::LexException,
+ unicode::Convert("must line ending after whitespaces"));
+ }
+
+ while (intraline(checker) && !reader->IsEof()) {
+ reader->Read();
+ checker = unicode::UniChar(reader->Peek());
+ }
+ *code = 0;
+ }
+
+ return true;
}
// 文字列の終了地点は、同一行の`"`か、\\を含む複数行後の対応する`"`となります。
// 対応する`"`が存在しないままreaderの末尾に到達すると、LexExceptionが
// 送出されます。
-// また、行末から次の行の最初の文字までが、改行か空白のみである場合、
-// 行末から次の空白以外の文字までの文字列は無視され、文字列は継続している
+// また、\から行末まで空白文字のみが続き、次の行の最初の文字までが、改行か
+// 空白のみである場合、その間の空白及び改行は無視され、文字列は継続している
// とみなされます。
-lexer::Lexeme* lexer::StringLexer::Lex(const unicode::UniString& string,
- reader::EncodingReader* reader) {
- if (reader == NULL) {
- THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
- "reader must valid instance"));
+lexer::Lexeme* lexer::StringLexer::Lex(reader::EncodingReader* reader) {
+ term::StringDelimiterChecker string_delimiter;
+ {
+ unicode::UniChar head(reader->Read());
+ if (!string_delimiter(head)) {
+ return NULL;
+ }
}
- delimiter::StarndardDelimiterChecker std_delimiter;
- delimiter::StringDelimiterChecker string_delimiter;
- delimiter::WhitespaceChecker white_delimiter;
- delimiter::LineEndingChecker lineending_checker;
+ term::StarndardDelimiterChecker std_delimiter;
+ term::WhitespaceChecker white_delimiter;
+ term::LineEndingChecker lineending_checker;
unicode::UniString str;
bool syntax_ok = false;
break;
}
- if (lineending_checker(tmp, reader)) {
+ if (lineending_checker(tmp)) {
while (!reader->IsEof() && (white_delimiter(tmp) || std_delimiter(tmp))) {
reader->Read();
}