Как заставить lex / flex распознавать токены, не разделенные пробелами?

Я беру курс по построению компилятора, и мое текущее задание - написать лексер для языка, который мы реализуем. Я не могу понять, как выполнить требование, чтобы лексер распознавал сцепленные токены. То есть токены не разделены пробелами. Например: строка39if должен быть признан как число39 и ключевое словоif, Одновременно лексер должен такжеexit(1) когда он сталкивается с неверным вводом.

Упрощенная версия кода у меня есть:

%{
#include <stdio.h>
%}

%option main warn debug

%%

if      |
then    |
else    printf("keyword: %s\n", yytext);

[[:digit:]]+    printf("number: %s\n", yytext);

[[:alpha:]][[:alnum:]]*     printf("identifier: %s\n", yytext);

[[:space:]]+    // skip whitespace
[[:^space:]]+   { printf("ERROR: %s\n", yytext); exit(1); }

%%

Когда я запускаю это (или мою полную версию) и передаю ему ввод39if, правило ошибки совпадает и выводERROR: 39if, когда я хотел бы, чтобы это было:

number: 39
keyword: if

(Т.е. так же, как если бы я вошел39 if как вход.)

По инструкцииЯ догадываюсь, что причина в том, что правило ошибки соответствует более длинному вводу, чем правила числа и ключевого слова, и flex это предпочтет. Тем не менее, я понятия не имею, как решить эту ситуацию. Кажется невозможным написать явное регулярное выражение, которое будет отклонять все входные данные, не связанные с ошибками, и я не знаю, как еще написать правило "catch-all" для обработки ошибок лексера.

ОБНОВИТЬ: Я полагаю, я мог бы просто сделать правило всеобъемлющим. { exit(1); } но я хотел бы получить более приятный вывод отладочной информации, чем «я запутался в строке 1».

Ответы на вопрос(1)

Ваш ответ на вопрос