Objective
Given an ASCII string, decide whether it is a valid C integer literal.
C integer literal
A C integer literal consists of:
One of:
0followed by zero or more octal digits (0–7)A nonzero decimal digit followed by zero or more decimal digits (
0–9)0Xor0x, followed by one or more hexadecimal digits (0–9,A–F, anda–f)
optionally followed by one of:
One of
Uoru, which are the "unsigned" suffixesOne of
L,l,LL, orll, which are the "long" and "long long" suffixesAny combination of the above, in any order.
Note that there can be arbitrarily many digits, even though C doesn't support arbitrary-length integers. Likewise, even if the literal with l and co would overflow the long type or co, it is still considered a valid literal.
Also note that there must not be a leading plus or minus sign, for it is not considered to be a part of the literal.
Rules
It is implementation-defined to accept leading or trailing whitespaces.
Non-ASCII string falls in don't care situation.
Examples
Truthy
000742u42lu42UL19827489765981697847893769837689346573uLL(Digits can be arbitrarily many even if it wouldn't fit theunsigned long longtype)0x8f6aa032838467beee3939428l(So can to thelongtype)0XCa0(You can mix cases)
Falsy
08(Non-octal digit)0x(A digit must followXorx)-42(Leading signature isn't a part of the literal)42Ll(OnlyLLorllis valid for thelong longtype)42LLLL(Redundant type specifier)42Uu(Redundant type specifier)42Ulu(Redundant type specifier)42lul(Redundant type specifier)42H(Invalid type specifier)0b1110010000100100001(Valid C++, but not valid C)HelloEmpty string
Ungolfed solution
Haskell
Doesn't recognize leading or trailing whitespaces.
Returns () on success. Monadic failure otherwise.
import Text.ParserCombinators.ReadP decideCIntegerLit :: ReadP () decideCIntegerLit = do choice [ do '0' <- get munch (flip elem "01234567"), do satisfy (flip elem "123456789") munch (flip elem "0123456789"), do '0' <- get satisfy (flip elem "Xx") munch1 (flip elem "0123456789ABCDEFabcdef") ] let unsigned = satisfy (flip elem "Uu") let long = string "l" +++ string "L" +++ string "ll" +++ string "LL" (unsigned >> long >> return ()) +++ (optional long >> optional unsigned) eof
1L1L,0xabucdlu(or any other test case with anl/L/usomewhere in the middle, making it invalid). \$\endgroup\$2-1(starts with a digit and is a valid C constant-expression, but not a bare integer literal). So for example feedinga=2-1;ora[2-1];to a C compiler wouldn't reject it. (Working on abashanswer that usescc -cafter testing the first digit, trying to let a compiler do the heavy lifting.) \$\endgroup\$0o765. This is a valid octal literal in many languages that might try to get away with a built-in "eval" / "read-int" sort of approach, but it's not valid C. \$\endgroup\$0band0oliteral prefixes now. \$\endgroup\$