https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70529
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- pp-number: digit . digit pp-number digit pp-number identifier-nondigit pp-number e sign pp-number E sign pp-number . identifier-nondigit: nondigit universal-character-name other implementation-defined characters nondigit: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ digit: one of 0 1 2 3 4 5 6 7 8 9 sign: one of + - Thus 0x123P2 is valid pp-number, because it starts with a digit, is followed by nondigit, then 3 times digit, then nondigit and then another digit, all matching the above grammar. But 0x123P-2 is not a pp-number, because in the grammar sign is only allowed after e or E letters. 0.123P2E-3E+3e-2E+2 is also a pp-number. After lexing this one is of course rejected, because it is not a valid floating point constant.