mirror of
https://github.com/boostorg/wave.git
synced 2026-01-19 04:42:16 +00:00
Implement support for digit separators in preprocessor expressions
Integers with digit separators are already recognized as literal tokens. This commit adds proper interpretation of them as integers for use in expressions e.g. with #if
This commit is contained in:
@@ -468,7 +468,7 @@ pp_number:
|
||||
|
||||
if (s->detect_pp_numbers) {
|
||||
/*!re2c
|
||||
"."? Digit (Digit | NonDigit | ExponentStart | ".")*
|
||||
"."? Digit (("'"? (Digit | NonDigit | ExponentStart)) | ".")*
|
||||
{ BOOST_WAVE_RET(T_PP_NUMBER); }
|
||||
|
||||
// because we reached this point, then reset the cursor,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* Generated by re2c 1.0.2 on Sun Oct 26 21:28:07 2025 */
|
||||
/* Generated by re2c 1.0.2 on Thu Nov 13 14:28:22 2025 */
|
||||
#line 1 "strict_cpp.re"
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_closure.hpp>
|
||||
#include <boost/spirit/include/classic_assign_actor.hpp>
|
||||
@@ -171,13 +173,20 @@ intlit_grammar_gen<TokenT>::evaluate(TokenT const &token,
|
||||
intlit_grammar g(is_unsigned);
|
||||
uint_literal_type result = 0;
|
||||
typename TokenT::string_type const &token_val = token.get_value();
|
||||
|
||||
// filter out digit separators
|
||||
auto not_digit_separator = [](char c){ return c != '\''; };
|
||||
auto digits_begin = boost::make_filter_iterator(not_digit_separator, token_val.begin(), token_val.end());
|
||||
auto digits_end = boost::make_filter_iterator(not_digit_separator, token_val.end(), token_val.end());
|
||||
typename TokenT::string_type token_digits(digits_begin, digits_end);
|
||||
|
||||
using boost::spirit::classic::parse_info;
|
||||
parse_info<typename TokenT::string_type::const_iterator> hit =
|
||||
parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
|
||||
parse(token_digits.begin(), token_digits.end(), g[spirit_assign_actor(result)]);
|
||||
|
||||
if (!hit.hit) {
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_integer_literal,
|
||||
token_val.c_str(), token.get_position());
|
||||
token_digits.c_str(), token.get_position());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
// Tests integer preprocessing number token and type of #if expression.
|
||||
|
||||
//O --long_long
|
||||
//O --c++17
|
||||
|
||||
// 12.1:
|
||||
//R #line 26 "t_5_014.cpp"
|
||||
//R #line 27 "t_5_014.cpp"
|
||||
//R true
|
||||
#if __TESTWAVE_LONG_MAX__ <= __TESTWAVE_LONG_MIN__
|
||||
"Bad evaluation of long."
|
||||
@@ -26,7 +27,7 @@
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 34 "t_5_014.cpp"
|
||||
//R #line 35 "t_5_014.cpp"
|
||||
//R true
|
||||
#if __TESTWAVE_LONG_MAX__ <= (__TESTWAVE_LONG_MAX__ / 2) /* 0x3FFFFFFF */
|
||||
"Bad evaluation of long."
|
||||
@@ -35,7 +36,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.2:
|
||||
//R #line 43 "t_5_014.cpp"
|
||||
//R #line 44 "t_5_014.cpp"
|
||||
//R true
|
||||
#if __TESTWAVE_ULONG_MAX__ / 2 < __TESTWAVE_LONG_MAX__
|
||||
"Bad evaluation of unsigned long."
|
||||
@@ -44,7 +45,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.3: Octal number.
|
||||
//R #line 52 "t_5_014.cpp"
|
||||
//R #line 53 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0177777 != 65535
|
||||
"Bad evaluation of octal number."
|
||||
@@ -53,7 +54,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.4: Hexadecimal number.
|
||||
//R #line 61 "t_5_014.cpp"
|
||||
//R #line 62 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0Xffff != 65535 || 0xFfFf != 65535
|
||||
"Bad evaluation of hexadecimal number."
|
||||
@@ -62,7 +63,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.5: Suffix 'L' or 'l'.
|
||||
//R #line 70 "t_5_014.cpp"
|
||||
//R #line 71 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0L != 0 || 0l != 0
|
||||
"Bad evaluation of 'L' suffix."
|
||||
@@ -71,7 +72,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.6: Suffix 'U' or 'u'.
|
||||
//R #line 79 "t_5_014.cpp"
|
||||
//R #line 80 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 1U != 1 || 1u != 1
|
||||
"Bad evaluation of 'U' suffix."
|
||||
@@ -80,7 +81,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.7: Negative integer.
|
||||
//R #line 88 "t_5_014.cpp"
|
||||
//R #line 89 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0 <= -1
|
||||
"Bad evaluation of negative number."
|
||||
@@ -89,7 +90,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.8: Long Long integers
|
||||
//R #line 97 "t_5_014.cpp"
|
||||
//R #line 98 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0LL != 0 || 0ll != 0
|
||||
"Bad evaluation of 'LL' suffix."
|
||||
@@ -98,7 +99,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.8: Unsigned Long Long integers
|
||||
//R #line 106 "t_5_014.cpp"
|
||||
//R #line 107 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 1ull != 1 || 1uLL != 1 || 1Ull != 1 || 1ULL != 1 || 1llu != 1 || 1llU != 1 || 1LLu != 1 || 1LLU != 1
|
||||
"Bad evaluation of 'ULL' or 'LLU' suffix."
|
||||
@@ -107,7 +108,7 @@ true
|
||||
#endif
|
||||
|
||||
// 12.9: invalid (mixed case) long long integers
|
||||
//R #line 115 "t_5_014.cpp"
|
||||
//R #line 116 "t_5_014.cpp"
|
||||
//R long long foo = 1234l L;
|
||||
//R long long bar = 5678L l;
|
||||
//R unsigned long long baz = 1234uL l;
|
||||
@@ -117,6 +118,81 @@ long long bar = 5678Ll;
|
||||
unsigned long long baz = 1234uLl;
|
||||
unsigned long long quux = 5678uLl;
|
||||
|
||||
// Evaluating numbers containing digit separators
|
||||
|
||||
//R #line 128 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 120'3 < 120'2
|
||||
"Bad comparison of signed integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 136 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 1'202 != 120'2l
|
||||
"Bad equality comparison of signed integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 144 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 120'3ul < 120'2u
|
||||
"Bad comparison of unsigned integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 152 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 1'202U != 120'2UL
|
||||
"Bad equality comparison of unsigned integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 160 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0x13'37c0de != 0x13'37c0'de
|
||||
"Bad equality comparison of hex integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 168 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0x13'37c0de < 0x13'27c0'de
|
||||
"Bad comparison of hex integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 176 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0b10'0101 != 0b1'00101
|
||||
"Bad equality comparison of binary integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
//R #line 184 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0b10'0101 > 0b11'0101
|
||||
"Bad comparison of binary integers with digit separators"
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
|
||||
// Now one comparison the other way, just in case
|
||||
//R #line 191 "t_5_014.cpp"
|
||||
//R true
|
||||
#if 0x13'37c0d'e == 0x1'3'3'7'c0de
|
||||
true
|
||||
#else
|
||||
"Bad equality comparison for many hex digits with separator"
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2002-2005 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
// Verify that long integer literals from a macro expansion parse correctly
|
||||
// This test covers #162
|
||||
|
||||
//O --c++11
|
||||
//O --c++17
|
||||
//O -DFOO=0x1234567ULL
|
||||
#define BAZ (FOO*2UL+1UL)
|
||||
#define BAR (BAZ + 1ULL)
|
||||
|
||||
#if defined(BAR) && (BAR == 0x2468AD0)
|
||||
#if defined(BAR) && (BAR == 0x246'8AD0)
|
||||
struct Bar {};
|
||||
#else
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user