You can just add an additional pattern to detect an error.
The following does not use macros, because I personally find them distracting. But the idea is the same.
[[:alpha:]][[:alnum:]]* { return IDENTIFIER; }
[[:digit:]]+"."([[:digit:]]+)? { return NUMBER; }
[[:digit:]]+"."([[:digit:]]+)?[[:alpha:]] { return BAD_NUMBER; }
The last pattern will only match if there is a letter immediately following a NUMBER, and will override the second pattern because of the longest-match rule.
By the way, a better pattern for a number is:
[[:digit:]]+("."[[:digit:]]*)?|"."[[:digit:]]+
That will match 23.
and .56
, which many people expect to be valid numbers.
You might also find this answer interesting, particularly the examples from other programming languages. Most languages (other than C & family) do allow 123abc
to be scanned as two tokens, which usually leads to a syntax error anyway, and that is both the easiest and the most maintainable solution.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…