Обычно это обрабатывается синтаксическим анализатором в верхней части сканера, который дает вам намного более чистый код. Вы можете эмулировать это до некоторой степени состояниями:
%option noyywrap
%top {
#define TOKEN_LEFT_PAREN 4711
#define TOKEN_RIGHT_PAREN 4712
#define TOKEN_NUMBER 4713
}
%x PAREN_STATE
%%
"(" BEGIN(PAREN_STATE); return TOKEN_LEFT_PAREN;
<PAREN_STATE>{
[0-9]+ return TOKEN_NUMBER;
")" BEGIN(INITIAL); return TOKEN_RIGHT_PAREN;
.|\n /* maybe signal syntax error here */
}
%%
int main (int argc, char *argv [])
{
int i;
while ((i = yylex ()))
printf ("%d\n", i);
return 0;
}
но это станет очень грязным, как только ваша грамматика станет более сложной.