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