Как я могу разобрать строку C (char *) с помощью flex/bison?
В моем программном проекте я хочу проанализировать атрибуты командной строки с помощью flex/bison. Моя программа называется так:
./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename
Можно ли разобрать эту строку с помощью flex/bison, не записывая ее в файл и не разбирая этот файл?
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). Я не сканировал из завязывает сам, но скоро попробует.