OSDN Git Service

lexerに関係するソースをsrc/lexer配下に移動。
[simplecms/utakata.git] / src / lexer / string_lexer.cpp
1 #include "src/exception_macro.h"
2 #include "src/lexer/string_lexer.h"
3 #include "src/lexer/delimiters.h"
4 #include "src/lexeme.h"
5
6 namespace lexer = utakata::lexer;
7 namespace delimiter = utakata::lexer_delimiter;
8
9 // 宣言のコメントを参照してください。
10 bool lexer::StringDispatchTerm::IsDispatch(
11     const unicode::UniString& string) const {
12   if (!ch.IsEmpty() && ch.At(0).rawcode() == '"') {
13     return true;
14   }
15
16   return false;
17 }
18
19 // 文字列の終了地点は、同一行の`"`か、\\を含む複数行後の対応する`"`となります。
20 // 対応する`"`が存在しないままreaderの末尾に到達すると、LexExceptionが
21 // 送出されます。
22 // また、行末から次の行の最初の文字までが、改行か空白のみである場合、
23 // 行末から次の空白以外の文字までの文字列は無視され、文字列は継続している
24 // とみなされます。
25 lexeme::ILexeme* lexer::StringLexer::Lex(const unicode::UniString& string.
26                                          reader::EncodingReader* reader) {
27   if (reader == NULL) {
28     THROW_EXCEPTION_(lexer::LexException, "reader must valid instance");
29   }
30
31   delimiter::StarndardDelimiterChecker std_delimiter();
32   delimiter::StringDelimiterChecker string_delimiter();
33   delimiter::WhitespaceChecker white_delimiter();
34   delimiter::LineEndingChecker lineending_checker();
35
36   unicode::UniString str();
37   bool syntax_ok = false;
38
39   while (!reader->IsEof() && !syntax_ok) {
40     UniChar tmp(stream->Peek());
41
42     if (string_delimiter(tmp)) {
43       stream->Read();
44       syntax_ok = true;
45       break;
46     }
47
48     if (lineending_checker(tmp, reader)) {
49       while (!stream->IsEof() && (white_delimiter(tmp) || std_delimiter(tmp))) {
50         stream->Read();
51       }
52     } else {
53       str.Append(unicode::UniChar(stream->read()));
54     }
55   }
56
57   if (!syntax_ok) {
58     THROW_EXCEPTION_(lexer::LexException, "not found end of string.");
59   }
60
61   return new lexeme::StringLexeme(str);
62 }