• [^] # Re: YY_INPUT

    Posté par (site web personnel) . En réponse au message Parser une chaine de caractère en C avec Flex/Bison. Évalué à 1.

    Désolé mais ça ne marche pas... il ne se passe rien quand j'exécute !!!

    main.l

    %{
    #include <string.h>
    #include "main.tab.h"

    #undef YY_INPUT
    #define YY_INPUT(b,r,ms) (r = my_yyinput(b, ms))

    extern char* g_str;
    extern size_t g_str_size; /* taille de g_str */
    extern int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */

    int my_yyinput(char* buf, int max_size)
    {
    /* on calcule le nombre de caractères à copier dans buf,
    * soit on a assez de caractères pour remplir, buf, soit on prend le reste de la chaine
    */
    int num = fmin(max_size, g_str_size-g_str_read);


    /* on copie notre chaine dans buf */
    if (num > 0)
    {
    memcpy(buf, g_str+g_str_read, num);
    g_str_read += num;
    }
    return num;
    }


    %}

    %option case-insensitive

    INTEGER [0-9]+
    FLOATING [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?

    %%

    {INTEGER} {yylval=atoi(yytext); return TOK_NUMBER;}
    heat return TOK_HEAT;
    on|off {yylval=!strcmp(yytext,"on"); return TOK_STATE;}
    set return TOK_SET;
    temperature return TOK_TEMPERATURE;
    get return TOK_GET;
    \n return TOK_EOL; /* end of line */;
    [ \t]+ /* ignore whitespace */;

    %%


    main.y

    %{
    #include <stdio.h>
    #include <string.h>

    #define STR_SIZE 50
    char g_str[STR_SIZE];
    /*char* g_str;*/
    size_t g_str_size; /* taille de g_str */
    int g_str_read; /* nombre de caractère déjà envoyés à lex, initializé au départ à 0 */

    /*
    #define STR_SIZE 50
    char str[STR_SIZE];

    int myinput(char *buf, int max){
    memcpy(buf, str, STR_SIZE);
    }
    */
    /*
    int n = min(max, gStringLimit-gStringPtr);
    if(n>0){
    memcpy(buf, gStringPtr, n);
    gStringPtr +=n;
    }
    return n;
    }
    */


    int value; /* temperature value */

    enum _state {
    off,
    on
    };
    enum _state state;

    void show_heat_state() {
    if (state==off) {
    printf("\tHeat is off\n");
    } else {
    printf("\tHeat is on\n");
    }
    }

    %}


    %token TOK_NUMBER TOK_HEAT TOK_STATE TOK_SET TOK_TEMPERATURE TOK_GET TOK_EOL

    %%

    commands: /* empty */
    | commands command TOK_EOL
    ;

    command:
    heat_switch
    |
    heat_get
    |
    target_set
    |
    target_get
    ;

    heat_switch:
    TOK_HEAT TOK_STATE
    {
    if (2ドル==0) {
    state=off;
    } else if (2ドル==1) {
    state=on;
    }
    show_heat_state();
    }
    ;

    heat_get:
    TOK_GET TOK_HEAT
    {
    show_heat_state();
    }
    ;


    target_set:
    TOK_SET TOK_TEMPERATURE TOK_NUMBER
    {
    value=3ドル;
    printf("\tTemperature set to %d\n",value);
    }
    ;

    target_get:
    TOK_GET TOK_TEMPERATURE
    {
    printf("\tTemperature is %d\n",value);
    }
    ;
    %%


    void yyerror(const char *str) {
    fprintf(stderr,"yyerror: %s\n",str);
    }

    int yywrap() {
    return 1;
    }



    int main(void) {

    strcpy(g_str,"get temperature");
    /* printf(g_str); */

    value=0;
    state=off;

    yyparse();

    return 0;
    }


    Makefile

    all:
    flex main.l
    bison -d main.y
    gcc lex.yy.c main.tab.c -lfl -o main
    ./main