Jak sprawić, aby lex / flex rozpoznawał tokeny nie rozdzielone białymi znakami?
Zajmuję się budową kompilatora, a moim obecnym zadaniem jest napisanie leksera dla języka, który wdrażamy. Nie wiem, jak spełnić wymóg, aby leksyk rozpoznawał połączone żetony. Oznacza to, że tokeny nie są oddzielone białymi znakami. Np .: napis39if
ma być rozpoznawany jako numer39
i słowo kluczoweif
. Jednocześnie lexer musi równieżexit(1)
gdy napotka nieprawidłowe dane wejściowe.
Uproszczona wersja kodu, który mam:
%{
#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); }
%%
Po uruchomieniu tego (lub mojej pełnej wersji) i przekazaniu go do wejścia39if
, reguła błędu jest dopasowana, a wyjście jestERROR: 39if
, kiedy chciałbym, żeby to było:
number: 39
keyword: if
(To znaczy tak samo, jak gdybym wszedł39 if
jako dane wejściowe.)
Przejście przez podręcznik, Mam przeczucie, że przyczyną jest to, że reguła błędu odpowiada dłuższemu możliwemu wejściu niż reguły liczby i słów kluczowych, a flex go preferuje. Powiedziawszy to, nie mam pojęcia, jak rozwiązać tę sytuację. Wydaje się niewykonalne napisanie wyraźnego wyrażenia regularnego, które odrzuci wszystkie dane wejściowe inne niż błędy, i nie wiem, jak inaczej napisać regułę „catch-all” ze względu na obsługę błędów lexera.
AKTUALIZACJA: Przypuszczam, że mogłabym po prostu wprowadzić regułę catch-all. { exit(1); }
ale chciałbym uzyskać trochę ładniejszego wyjścia do debugowania niż „Wprawiłem w błąd w linii 1”.