1414
1515#include " processor/wetext_token_parser.h"
1616
17+ #include < stdexcept>
18+
1719#include " utils/wetext_log.h"
1820#include " utils/wetext_string.h"
1921
@@ -33,24 +35,26 @@ const std::unordered_map<std::string, std::vector<std::string>> ZH_TN_ORDERS = {
3335 {" money" , {" value" , " currency" }},
3436 {" time" , {" noon" , " hour" , " minute" , " second" }}};
3537const std::unordered_map<std::string, std::vector<std::string>> JA_TN_ORDERS = {
36- {" date" , {" year" , " month" , " day" }},
37- {" money" , {" value" , " currency" }}};
38+ {" date" , {" year" , " month" , " day" }}, {" money" , {" value" , " currency" }}};
3839
3940const std::unordered_map<std::string, std::vector<std::string>> EN_TN_ORDERS = {
4041 {" date" , {" preserve_order" , " text" , " day" , " month" , " year" }},
4142 {" money" , {" integer_part" , " fractional_part" , " quantity" , " currency_maj" }}};
42- const std::unordered_map<std::string, std::vector<std::string>> ZH_ITN_ORDERS =
43- {{" date" , {" year" , " month" , " day" }},
44- {" fraction" , {" sign" , " numerator" , " denominator" }},
45- {" measure" , {" numerator" , " denominator" , " value" }},
46- {" money" , {" currency" , " value" , " decimal" }},
47- {" time" , {" hour" , " minute" , " second" , " noon" }}};
43+ const std::unordered_map<std::string, std::vector<std::string>> ITN_ORDERS = {
44+ {" date" , {" year" , " month" , " day" , " preserve_order" }},
45+ {" fraction" , {" sign" , " numerator" , " denominator" }},
46+ {" measure" , {" numerator" , " denominator" , " value" , " units" }},
47+ {" money" , {" currency" , " value" , " decimal" , " quantity" }},
48+ {" time" , {" hour" , " minute" , " second" , " noon" , " zone" }},
49+ {" telephone" , {" country_code" , " number_part" }},
50+ {" electronic" , {" username" , " domain" , " protocol" }}};
4851
4952TokenParser::TokenParser (ParseType type) {
5053 if (type == ParseType::kZH_TN ) {
5154 orders_ = ZH_TN_ORDERS ;
52- } else if (type == ParseType::kZH_ITN ) {
53- orders_ = ZH_ITN_ORDERS ;
55+ } else if (type == ParseType::kZH_ITN || type == ParseType::kEN_ITN ||
56+ type == ParseType::kJA_ITN ) {
57+ orders_ = ITN_ORDERS ;
5458 } else if (type == ParseType::kEN_TN ) {
5559 orders_ = EN_TN_ORDERS ;
5660 } else if (type == ParseType::kJA_TN ) {
@@ -62,9 +66,12 @@ TokenParser::TokenParser(ParseType type) {
6266
6367void TokenParser::Load (const std::string& input) {
6468 wetext::SplitUTF8StringToChars (input, &text_);
65- CHECK_GT (text_.size (), 0 );
69+ if (text_.empty ()) {
70+ throw std::invalid_argument (" token stream must not be empty" );
71+ }
6672 index_ = 0 ;
6773 ch_ = text_[0 ];
74+ tokens_.clear ();
6875}
6976
7077bool TokenParser::Read () {
@@ -94,38 +101,54 @@ bool TokenParser::ParseChar(const std::string& exp) {
94101}
95102
96103bool TokenParser::ParseChars (const std::string& exp) {
97- bool ok = false ;
104+ size_t start = index_ ;
98105 std::vector<std::string> chars;
99106 wetext::SplitUTF8StringToChars (exp, &chars);
100107 for (const auto & x : chars) {
101- ok |= ParseChar (x);
108+ if (!ParseChar (x)) {
109+ index_ = start;
110+ ch_ = text_[start];
111+ return false ;
112+ }
102113 }
103- return ok ;
114+ return true ;
104115}
105116
106117std::string TokenParser::ParseKey () {
107- CHECK_NE (ch_, EOS );
108- CHECK_EQ (UTF8_WHITESPACE .count (ch_), 0 );
118+ if (ch_ == EOS || UTF8_WHITESPACE .count (ch_) > 0 ) {
119+ throw std::invalid_argument (" expected token key at position " +
120+ std::to_string (index_));
121+ }
109122
110123 std::string key = " " ;
111124 while (ASCII_LETTERS .count (ch_) > 0 ) {
112125 key += ch_;
113126 Read ();
114127 }
128+ if (key.empty ()) {
129+ throw std::invalid_argument (" invalid token key at position " +
130+ std::to_string (index_));
131+ }
115132 return key;
116133}
117134
118135std::string TokenParser::ParseValue () {
119- CHECK_NE (ch_, EOS );
120- bool escape = false ;
136+ if (ch_ == EOS ) {
137+ throw std::invalid_argument (" expected token value at end of stream" );
138+ }
121139
122140 std::string value = " " ;
123141 while (ch_ != " \" " ) {
142+ if (ch_ == EOS ) {
143+ throw std::invalid_argument (" unterminated token value" );
144+ }
124145 value += ch_;
125- escape = ch_ == " \\ " ;
146+ bool escape = ch_ == " \\ " ;
126147 Read ();
127148 if (escape) {
128- escape = false ;
149+ if (ch_ == EOS ) {
150+ throw std::invalid_argument (" unterminated escape in token value" );
151+ }
129152 value += ch_;
130153 Read ();
131154 }
@@ -137,20 +160,31 @@ void TokenParser::Parse(const std::string& input) {
137160 Load (input);
138161 while (ParseWs ()) {
139162 std::string name = ParseKey ();
140- ParseChars (" { " );
163+ if (!ParseChars (" { " )) {
164+ throw std::invalid_argument (" expected token opening delimiter" );
165+ }
141166
142167 Token token (name);
168+ bool closed = false ;
143169 while (ParseWs ()) {
144170 if (ch_ == " }" ) {
145171 ParseChar (" }" );
172+ closed = true ;
146173 break ;
147174 }
148175 std::string key = ParseKey ();
149- ParseChars (" : \" " );
176+ if (!ParseChars (" : \" " )) {
177+ throw std::invalid_argument (" expected token field delimiter" );
178+ }
150179 std::string value = ParseValue ();
151- ParseChar (" \" " );
180+ if (!ParseChar (" \" " )) {
181+ throw std::invalid_argument (" expected closing quote" );
182+ }
152183 token.Append (key, value);
153184 }
185+ if (!closed) {
186+ throw std::invalid_argument (" unterminated token " + name);
187+ }
154188 tokens_.emplace_back (token);
155189 }
156190}
0 commit comments