Почему flex-lexer ничего не выводит? - PullRequest
0 голосов
/ 25 апреля 2020

Я пишу небольшую программу для пользовательского набора токенов. Но я не наблюдаю результат работы. Есть идеи?

Вот несколько структур для удобного хранения токенов. Фрагмент структуры необходим для отображения координат токена в тексте (начальные координаты - конечные координаты).

%option noyywrap bison-bridge bison-locations
%option noyywrap yylineno 


%{
    #include <stdio.h>
    #include <stdlib.h>

    #define TAG_IDENT 1
    #define TAG_NUMBER 2
    #define TAG_OPERATION 3

    char * tag_names [] =
    {
        "END_OF_PROGRAM", "IDENT", 
        "NUMBER", "OPERATION"
    };

    struct Position
    {
        int line, pos, index;
    };

    void print_pos(struct Position *p)
    {
        printf("(%d, %d)", p->line, p->pos);
    }

    struct Fragment
    {
        struct Position starting , following ;
    };

    typedef struct Fragment YYLTYPE;

    void print_frag (struct Fragment *f)
    {
        print_pos(&(f->starting));
        printf("-");
        print_pos(&(f->following));
    }

Структурный токен содержит значение токена. 'init_scanner' читает текст, 'err' показывает нераспознанные токены. Если в начале каждого действия вам необходимо выполнить одни и те же операции (например, вычислить координаты токена), то эти операции можно записать в макрос YY_USER_ACTION.

    struct Token
    {
        char *token;
    };

    typedef struct Token YYSTYPE;

    struct Position cur;

    #define YY_USER_ACTION              \
    {                                   \
        int i;                          \
        yylloc->starting = cur;         \
                                        \
        for (i = 0; i < yyleng; i++)    \
        {                               \
            if (yytext[i] == '\n')      \
            {                           \
                cur.line++;             \
                cur.pos = 1;            \
            }                           \
            else                        \
                cur.pos++;              \
            cur.index++;                \
        }                               \
                                        \
        yylloc->following = cur;        \
    }                                   \

    void init_scanner(char *program)
    {
        cur.line = 1;
        cur.pos = 1;
        cur.index = 0;
        yy_scan_string(program);
    }

    void err (char *msg)
    {
        printf("UNKNOWN ");
        print_pos(&cur);
        printf (": %s\n", msg);
    }
%}

Регулярные выражения:

digit       [0-9]
letter      [a-zA-Z]
operation   <=|==|=

%%

({letter}|{digit})*({digit})    {
                                    yylval->token = yytext;
                                    return TAG_IDENT;
                                }

\<{digit}+\>                    {
                                    yylval->token = yytext;
                                    return TAG_NUMBER;
                                }

{operation}                     {
                                    yylval->token = yytext;
                                    return TAG_OPERATION;
                                }

[ \t]+                          {

                                }

\n                              {

                                }

.                               {
                                    err("unexpected character");
                                }

<<EOF>>                         {
                                    return 0;
                                }

%%

#define PROGRAM "dfjdkfsd3 34j3234 23 ="           \
                "    == <= 34234r3"                \
                "ffefef <324234234> <wer444> == "

Главное веселье c:

int main ()
{
    int tag;
    YYSTYPE value;
    YYLTYPE coords;

    init_scanner(PROGRAM);

    do
    {
        tag = yylex(&value, &coords);
        if (tag != 0)
        {
            print_pos(&cur);
            printf (": %s\n", tag);
        }
    }
    while (tag != 0);

    return 0;
}

Я ввожу следующие команды:

flex *filename*.l
gcc lex.yy.c -lfl
a.exe

Однако ничего не происходит

...