1 #include "src/exception_macro.h"
2 #include "src/lexer/string_lexer.h"
3 #include "src/lexer/term_lexer.h"
4 #include "src/lexer/term_checker.h"
5 #include "src/lexeme.h"
6 #include "src/encoding_reader.h"
7 #include "src/unicode.h"
9 namespace lexer = utakata::lexer;
10 namespace term = utakata::lexer::term;
11 namespace reader = utakata::reader;
12 namespace unicode = utakata::unicode;
15 bool lexer::EscapeLexer::Lex(reader::EncodingReader* reader,
17 unicode::UniString escape(reader->Read(kEscapeValidLength));
18 if (escape.IsEmpty() || escape.At(0).rawcode != '\\') {
22 if (escape.GetSize() < kEscapeValidLength) {
23 THROW_EXCEPTION_(lexer::LexException,
24 unicode::Convert("invalid escape seacense"));
27 term::IntralineWhiteSpaceChecker intraline;
28 term::LineEndingChecker lineend;
29 if (!CheckEscapeSeacense(escape.At(1)) && !intraline(escape.At(1)) &&
30 !lineend(escape.At(1))) {
31 unicode::UniString encoded_string("invalid escape seacense : ");
32 encoded_string.Append(escape);
33 THROW_EXCEPTION_(lexer::LexException, encoded_string);
36 if (!intraline(escape.At(1)) && !lineend(escape.At(1))) {
37 *code = ConvertEscapeToCode(escape);
39 reader->Read(kEscapeValidLength);
40 unicode::UniChar checker(escape.At(1));
41 while (intraline(checker) && !reader->IsEof()) {
42 checker = unicode::UniChar(reader->Read());
45 if (!lineend(checker)) {
46 unicode::UniString encoded_string;
47 THROW_EXCEPTION_(lexer::LexException,
48 unicode::Convert("must line ending after whitespaces"));
51 while (intraline(checker) && !reader->IsEof()) {
53 checker = unicode::UniChar(reader->Peek());
61 // 文字列の終了地点は、同一行の`"`か、\\を含む複数行後の対応する`"`となります。
62 // 対応する`"`が存在しないままreaderの末尾に到達すると、LexExceptionが
64 // また、\から行末まで空白文字のみが続き、次の行の最初の文字までが、改行か
65 // 空白のみである場合、その間の空白及び改行は無視され、文字列は継続している
67 lexer::Lexeme* lexer::StringLexer::Lex(reader::EncodingReader* reader) {
68 term::StringDelimiterChecker string_delimiter;
70 unicode::UniChar head(reader->Read());
71 if (!string_delimiter(head)) {
76 term::StarndardDelimiterChecker std_delimiter;
77 term::WhitespaceChecker white_delimiter;
78 term::LineEndingChecker lineending_checker;
80 unicode::UniString str;
81 bool syntax_ok = false;
83 while (!reader->IsEof() && !syntax_ok) {
84 unicode::UniChar tmp(reader->Peek());
86 if (string_delimiter(tmp)) {
92 if (lineending_checker(tmp)) {
93 while (!reader->IsEof() && (white_delimiter(tmp) || std_delimiter(tmp))) {
97 str.Append(unicode::UniChar(reader->Read()));
102 THROW_EXCEPTION_(lexer::LexException,
103 unicode::Convert("not found end of string."));
106 return new lexer::Lexeme(str, lexer::Lexeme::kString);