このページを編集する際は,編集に関する方針に従ってください.[]
概要[]
- gcc-4.1.0/libcpp/expr.cにて定義
- 数値型を解析して正しいフラグをたてる
- 整数型か、浮動小数点型か
- 大きさ(バイト数)はどのくらいか
- 虚数なのか
- 複数の規格に対応するためのコードが結構ある
引数[]
- cpp_reader *pfile
- const cpp_token *token
実装[]
140 /* Categorize numeric constants according to their field (integer,
141 floating point, or invalid), radix (decimal, octal, hexadecimal),
142 and type suffixes. */
143 unsigned int
144 cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
145 {
146 const uchar *str = token->val.str.text;
147 const uchar *limit;
148 unsigned int max_digit, result, radix;
149 enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
150
- 一桁だけならば簡単に分かる
151 /* If the lexer has done its job, length one can only be a single
152 digit. Fast-path this very common case. */
153 if (token->val.str.len == 1)
154 return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;
155
- 初期値
156 limit = str + token->val.str.len;
157 float_flag = NOT_FLOAT;
158 max_digit = 0;
159 radix = 10;
160
- 基数を求める
161 /* First, interpret the radix. */
162 if (*str == '0')
163 {
164 radix = 8;
165 str++;
166
167 /* Require at least one hex digit to classify it as hex. */
168 if ((*str == 'x' || *str == 'X')
169 && (str[1] == '.' || ISXDIGIT (str[1])))
170 {
171 radix = 16;
172 str++;
173 }
174 }
175
- 数字列の最後までスキャンして正しい様式になっているか調べる
176 /* Now scan for a well-formed integer or float. */
177 for (;;)
178 {
179 unsigned int c = *str++;
180
181 if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
182 {
183 c = hex_value (c);
184 if (c > max_digit)
185 max_digit = c;
186 }
187 else if (c == '.')
188 {
189 if (float_flag == NOT_FLOAT)
190 float_flag = AFTER_POINT;
191 else
192 SYNTAX_ERROR ("too many decimal points in number");
193 }
194 else if ((radix <= 10 && (c == 'e' || c == 'E'))
195 || (radix == 16 && (c == 'p' || c == 'P')))
196 {
197 float_flag = AFTER_EXPON;
198 break;
199 }
200 else
201 {
202 /* Start of suffix. */
203 str--;
204 break;
205 }
206 }
207
- 浮動小数点で基数8のときは基数10に置き換える
- 些細なエラー処理か何かか?
208 if (float_flag != NOT_FLOAT && radix == 8)
209 radix = 10;
210
- 基数以上の値を使うのはエラー
211 if (max_digit >= radix)
212 SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
213
- 浮動小数点の処理
214 if (float_flag != NOT_FLOAT)
215 {
216 if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
217 cpp_error (pfile, CPP_DL_PEDWARN,
218 "use of C99 hexadecimal floating constant");
219
220 if (float_flag == AFTER_EXPON)
221 {
222 if (*str == '+' || *str == '-')
223 str++;
224
225 /* Exponent is decimal, even if string is a hex float. */
226 if (!ISDIGIT (*str))
227 SYNTAX_ERROR ("exponent has no digits");
228
229 do
230 str++;
231 while (ISDIGIT (*str));
232 }
233 else if (radix == 16)
234 SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
235
- 後置詞の処理
236 result = interpret_float_suffix (str, limit - str);
237 if (result == 0)
238 {
239 cpp_error (pfile, CPP_DL_ERROR,
240 "invalid suffix \"%.*s\" on floating constant",
241 (int) (limit - str), str);
242 return CPP_N_INVALID;
243 }
244
- 伝統的なCだと浮動小数点型の後置詞を許さない
245 /* Traditional C didn't accept any floating suffixes. */
246 if (limit != str
247 && CPP_WTRADITIONAL (pfile)
248 && ! cpp_sys_macro_p (pfile))
249 cpp_error (pfile, CPP_DL_WARNING,
250 "traditional C rejects the \"%.*s\" suffix",
251 (int) (limit - str), str);
252
253 result |= CPP_N_FLOATING;
254 }
- 整数型の処理
255 else
256 {
- 後置詞の処理
257 result = interpret_int_suffix (str, limit - str);
258 if (result == 0)
259 {
260 cpp_error (pfile, CPP_DL_ERROR,
261 "invalid suffix \"%.*s\" on integer constant",
262 (int) (limit - str), str);
263 return CPP_N_INVALID;
264 }
265
266 /* Traditional C only accepted the 'L' suffix.
267 Suppress warning about 'LL' with -Wno-long-long. */
268 if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
269 {
270 int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
271 int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
272
273 if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
274 cpp_error (pfile, CPP_DL_WARNING,
275 "traditional C rejects the \"%.*s\" suffix",
276 (int) (limit - str), str);
277 }
278
279 if ((result & CPP_N_WIDTH) == CPP_N_LARGE
280 && ! CPP_OPTION (pfile, c99)
281 && CPP_OPTION (pfile, warn_long_long))
282 cpp_error (pfile, CPP_DL_PEDWARN,
283 "use of C99 long long integer constant");
284
285 result |= CPP_N_INTEGER;
286 }
287
288 if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
289 cpp_error (pfile, CPP_DL_PEDWARN,
290 "imaginary constants are a GCC extension");
291
- 基数の処理
292 if (radix == 10)
293 result |= CPP_N_DECIMAL;
294 else if (radix == 16)
295 result |= CPP_N_HEX;
296 else
297 result |= CPP_N_OCTAL;
298
299 return result;
300
- SYNTAX_ERROR, SYNTAX_ERROR2はマクロで、最後の所がここへのgoto文になっている
301 syntax_error:
302 return CPP_N_INVALID;
303 }