Как я могу разобрать строку C (char *) с помощью flex/bison?


В моем программном проекте я хочу проанализировать атрибуты командной строки с помощью flex/bison. Моя программа называется так:

./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename

Можно ли разобрать эту строку с помощью flex/bison, не записывая ее в файл и не разбирая этот файл?

5 8

5 ответов:

Смотрите этот вопрос строковый ввод для flex lexer

Я думаю, что вы можете достичь чего-то подобного (я сделал аналогичную вещь), используя fmemopen, чтобы создать поток из char*, а затем заменить его на stdin

Что-то вроде этого (не уверен, что это полностью функционально, так как я на самом деле пытаюсь вспомнить доступные syscalls, но это было бы что-то подобное этому)

char* args = "(1,2,3)(4,5)(6,7,8)"
FILE *newstdin = fmemopen (args, strlen (args), "r");
FILE *oldstdin = fdup(stdin);

stdin = newstdin;

// do parsing

stdin = oldstdin;

Вот полный пример flex.

%%

<<EOF>> return 0;

.   return 1;

%%

int yywrap()
{
    return (1);
}

int main(int argc, const char* const argv[])
{
    YY_BUFFER_STATE bufferState = yy_scan_string("abcdef");

    // This is a flex source. For yacc/bison use yyparse() here ...    
    int token;
    do {
        token = yylex();
    } while (token != 0);

    // Do not forget to tell flex to clean up after itself. Lest
    // ye leak memory.
    yy_delete_buffer(bufferState);

    return (EXIT_SUCCESS);
}

Еще один пример. это переопределяет макрос YY_INPUT:

%{
int myinput (char *buf, int buflen);
char *string;
int offset;
#define YY_INPUT(buf, result, buflen) (result = myinput(buf, buflen));
%}
%%

[0-9]+             {printf("a number! %s\n", yytext);}

.                  ;
%%

int main () {
    string = "(1, 2, 3)(4, 5)(6, 7, 8)";
    yylex();
}

int myinput (char *buf, int buflen) {
    int i;
    for (i = 0; i < buflen; i++) {
        buf[i] = string[offset + i];
        if (!buf[i]) {
            break;
        }
    }
    offset += i;
    return i;
}

Ответ - "да". Смотрите публикацию О'Рейли под названием "lex & yacc", 2-е издание Дуга Брауна, Джона Левина, Тони Мейсона. См. Главу 6, раздел "ввод из строк".

Я также только что заметил, что есть некоторые хорошие инструкции в разделе "ввод из строк", Глава 5 "flex and bison", Джон Левин. Высматривать процедуры yy_scan_bytes(типа char *байт, инт лен), yy_scan_string("строка"), и yy_scan_buffer(типа char *основания, размер yy_size_t). Я не сканировал из завязывает сам, но скоро попробует.