2010-11-25 1 views
8

Dans mon projet de programmation, je veux analyser les attributs de la ligne de commande en utilisant flex/bison. Mon programme est appelé comme ceci:Comment puis-je analyser une chaîne C (char *) avec flex/bison?

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

Est-il possible d'analyser cette chaîne en utilisant Flex/Bison sans l'écrire dans un fichier et l'analyse de ce fichier?

+2

Je pense que l'écriture d'une machine à états simple serait plus facile et plus propre que d'utiliser Flex ou Bison pour cela. –

+0

Si vous pensez avoir besoin de flex et de bison, quelle est la complexité de cette grammaire? Et je suis d'accord avec James: pour juste analyser des listes d'entiers séparés par des virgules avec un espace et des parenthèses optionnels, C serait le meilleur. –

+0

Je n'ai utilisé que flex et bison ensemble jusqu'à maintenant. En y regardant de plus près, il est plus logique de n'utiliser que flex. –

Répondre

4

Voir cette question String input to flex lexer

+5

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses à lien uniquement peuvent devenir invalides si la page liée change. – ProgramFOX

+0

Ou peut-être simplement fermer la question en tant que doublon? – firegurafiku

2

Je pense que vous pouvez obtenir quelque chose comme ça (je l'ai fait une chose similaire) en utilisant fmemopen pour créer un flux à partir d'un char* puis le remplacer STDIN

Quelque chose comme ça (pas sûr si elle est pleinement fonctionnelle depuis J'essaie vraiment de se rappeler syscalls disponibles, mais ce serait quelque chose de semblable à ce)

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; 
-1

La réponse est « oui ». Voir la publication d'O'Reilly intitulée "lex & yacc", 2e édition par Doug Brown, John Levine, Tony Mason. Reportez-vous au chapitre 6, section "Entrée à partir de chaînes".

Je viens aussi de remarquer qu'il y a quelques bonnes instructions dans la section "Entrée de cordes", chapitre 5 de "flex and bison", par John Levine. Recherchez les routines yy_scan_bytes (char * octets, int len), yy_scan_string ("chaîne") et yy_scan_buffer (char * base, taille yy_size_t). Je n'ai pas scanné les chaînes moi-même, mais j'essaierai bientôt.

+0

"aller acheter un livre" n'est pas une réponse. – aaa90210

1

Voici un exemple de flex complet.

%% 

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

un autre exemple. celui-ci redéfinit la macro 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; 
} 
Questions connexes