Como fazer lex / flex reconhecer tokens não separados por espaço em branco?
Estou fazendo um curso de construção de compiladores e minha tarefa atual é escrever o léxico para a linguagem que estamos implementando. Não consigo descobrir como satisfazer a exigência de que o lexer reconheça tokens concatenados. Ou seja, tokens não separados por espaços em branco. Por exemplo: a string39if
é suposto ser reconhecido como o número39
e a palavra-chaveif
. Simultaneamente, o lexer também deveexit(1)
quando encontra entrada inválida.
Uma versão simplificada do código que tenho:
%{
#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); }
%%
Quando eu executo esta (ou minha versão completa), e passo a entrada39if
, a regra de erro é correspondida e a saída éERROR: 39if
, quando eu gostaria que fosse:
number: 39
keyword: if
(Ou seja, o mesmo como se eu tivesse entrado39 if
como a entrada.)
Indo pelo manual, Tenho um palpite de que a causa é que a regra de erro corresponde a uma entrada mais longa possível do que as regras de número e palavra-chave, e o flex irá preferir isso. Dito isto, não tenho ideia de como resolver esta situação. Parece impraticável escrever um regexp explícito que rejeitará todas as entradas sem erros, e não sei como escrever uma regra "pega-tudo" para lidar com erros de lexer.
ATUALIZAR: Eu suponho que eu poderia apenas fazer com que a regra geral fosse. { exit(1); }
mas eu gostaria de obter uma saída de depuração mais agradável do que "fiquei confuso na linha 1".