8 Stimmen

Wie kann ich einen C-String (char *) mit flex/bison parsen?

In meinem Programmierprojekt möchte ich Befehlszeilenattribute mit flex/bison analysieren. Mein Programm wird wie folgt aufgerufen:

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

Ist es möglich, diese Zeichenfolge mit flex/bison zu analysieren, ohne sie in eine Datei zu schreiben und diese Datei zu analysieren?

6voto

epatel Punkte 45365

Siehe diese Frage String-Eingabe für Flex-Lexer

3voto

Jack Punkte 128223

Ich glaube, Sie können so etwas erreichen (ich habe etwas Ähnliches gemacht), indem Sie fmemopen um einen Stream aus einer char* und dann in stdin ersetzen

Etwas in der Art (ich bin nicht sicher, ob es voll funktionsfähig ist, da ich gerade versuche, mich an verfügbare Syscalls zu erinnern, aber es wäre etwas Ähnliches wie das hier)

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;

2voto

Tad Carlucci Punkte 61

Hier ist ein vollständiges Flex-Beispiel.

%%

<<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);
}

0voto

Jake Punkte 1926

Ein weiteres Beispiel. Dieses definiert das Makro YY_INPUT neu:

%{
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;
}

-1voto

Kevin Jensen Punkte 9

Die Antwort lautet "Ja". Siehe die O'Reilly-Publikation "lex & yacc", 2. Auflage von Doug Brown, John Levine, Tony Mason. Siehe Kapitel 6, den Abschnitt "Input from Strings".

Außerdem habe ich gerade festgestellt, dass es im Abschnitt "Input from Strings", Kapitel 5 von "flex and bison", von John Levine, einige gute Anleitungen gibt. Achten Sie auf die Routinen yy_scan_bytes(char *bytes, int len), yy_scan_string("string"), und yy_scan_buffer(char *base, yy_size_t size). Ich habe selbst noch nicht von Strings gescannt, werde es aber bald ausprobieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X