1 #include "src/lexeme.h"
2 #include "src/exception_macro.h"
3 #include "src/encoding_reader.h"
4 #include "src/lexer/term_checker.h"
5 #include "src/lexer/term_lexer.h"
6 #include "src/lexer/number_lexer.h"
7 #include "src/lexer/number_lexer_detail_templates.h"
8 #include "src/unicode.h"
10 namespace lexer = utakata::lexer;
11 namespace reader = utakata::reader;
12 namespace term = utakata::lexer::term;
13 namespace unicode = utakata::unicode;
16 bool lexer::detail::MantissaWidthLexer::Lex(reader::EncodingReader* reader,
17 unicode::UniString* string) {
18 lexer::TermLexer<term::NumberDigit<10> > digit_10;
20 unicode::UniChar ch(reader->Peek());
21 if (ch.rawcode() != '|') {
25 unicode::UniString code(ch, 1);
26 while (!reader->IsEof()) {
27 if (!digit_10.CheckToken(reader)) {
30 unicode::Append(code, reader->Read(digit_10.ReadToken(reader)));
33 const int kMantissaSize = 2;
34 if (code.GetSize() < static_cast<unsigned int>(kMantissaSize)) {
35 THROW_EXCEPTION_(lexer::LexException,
36 unicode::Convert("must one or more digits that after `|' "));
44 bool lexer::detail::SuffixLexer::Lex(reader::EncodingReader* reader,
45 unicode::UniString* string) {
46 lexer::TermLexer<term::ExponentMarker> marker;
47 if (!marker.CheckToken(reader)) {
51 unicode::UniString code(unicode::Convert(
52 reader->Read(marker.ReadToken(reader))));
54 lexer::TermLexer<term::Sign> sign;
55 lexer::TermLexer<term::NumberDigit<10> > digit_10;
57 if (!sign.CheckToken(reader)) {
58 THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
59 "must have sign after `exponent marker'"));
61 code.Append(unicode::Convert(
62 reader->Read(marker.ReadToken(reader))));
64 if (!digit_10.CheckToken(reader)) {
65 THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
66 "must have digit[0-9] after `sign'"));
69 while (!reader->IsEof()) {
70 if (!digit_10.CheckToken(reader)) {
73 code.Append(unicode::Convert(
74 reader->Read(marker.ReadToken(reader))));
83 bool lexer::detail::DecimalLexer::Lex(reader::EncodingReader* reader,
84 unicode::UniString* string) {
85 UIntegerLexer<10> uint_lexer;
86 unicode::UniString code;
88 if (uint_lexer.Lex(reader, &code)) {
90 unicode::UniString suffix_string;
91 suffix.Lex(reader, &suffix_string);
93 if (!suffix_string.IsEmpty()) {
95 string->Append(suffix_string);
97 InnerLexFloating(reader, &code);
102 lexer::TermLexer<term::NumberDigit<10> > digit;
105 unicode::UniChar ch(reader->Peek());
106 if (ch.rawcode() != '.') {
112 unicode::UniString digit_string;
113 while (!reader->IsEof() && digit.CheckToken(reader)) {
114 unicode::Append(digit_string, reader->Read(digit.ReadToken(reader)));
117 if (digit_string.IsEmpty()) {
118 THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
119 "complex format error that nessesary one of more digits after ."));
121 code.Append(digit_string);
123 if (!suffix.Lex(reader, &code)) {
124 THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
125 ". <digit> nessesary after suffix"));
127 string->Append(code);
135 bool lexer::detail::DecimalLexer::InnerLexFloating(
136 reader::EncodingReader* reader, unicode::UniString* string) {
137 lexer::TermLexer<term::NumberDigit<10> > digit;
139 unicode::UniString code;
141 unicode::UniChar ch(reader->Peek());
143 if (ch.rawcode() != '.') {
150 while (!reader->IsEof() && digit.CheckToken(reader)) {
151 unicode::Append(code, reader->Read(digit.ReadToken(reader)));
154 if (!suffix.Lex(reader, &code)) {
155 THROW_EXCEPTION_(lexer::LexException, unicode::Convert(
156 ". <digit> nessesary after suffix"));
158 string->Append(code);
163 // <number>の字句要素を解釈します。解釈されない場合、NULLが返されます。
164 // 字句構文違反があった場合、LexException例外が発生します。
165 lexer::Lexeme* lexer::NumberLexer::Lex(reader::EncodingReader* reader) {
166 lexer::detail::NumLexer<2> binary;
167 lexer::detail::NumLexer<8> oct;
168 lexer::detail::NumLexer<10> decimal;
169 lexer::detail::NumLexer<16> hex;
171 unicode::UniString number_string;
172 if (binary.Lex(reader, &number_string)) {
173 return new lexer::Lexeme(number_string, lexer::Lexeme::kNumber);
174 } else if (oct.Lex(reader, &number_string)) {
175 return new lexer::Lexeme(number_string, lexer::Lexeme::kNumber);
176 } else if (decimal.Lex(reader, &number_string)) {
177 return new lexer::Lexeme(number_string, lexer::Lexeme::kNumber);
178 } else if (hex.Lex(reader, &number_string)) {
179 return new lexer::Lexeme(number_string, lexer::Lexeme::kNumber);