0
votes

I am a beginner in Flex and Bison (I have some basic knowledge of C) and I am creating a simple parser.

The goal here is to fill the following structure :

struct numvariable {
    int nodetype;    /* type V */
    char* value;
};

In order to do that, first, I am trying to print the char* entered by the user in the lexer (working : prints the value entered by the user) and then in the parser (not working, null).

Here is the corresponding line in the lexer.l file (the string entered by the user is correctly printed here) :

[a-zA-Z][a-zA-Z0-9]* {
    char *yycopy = strdup(yytext);
    printf("lexer %s\n", yycopy);
    yylval.var == yycopy;
    free(yycopy);
    return NAME; 
}

Following is the parser.y file :

%{
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include "header.h"
extern int yylex(void);
struct ast *result;
%}
%union {
  struct ast *a;
  char *var;
}
%token <var> NAME
%type <a> exp
%%
calclist: /* nothing */
| calclist exp          { result = $2; }
 ;
exp: NAME               { $$ = newvar($1); }
 ;
%%
struct ast *newvar(char *val)
{
    printf("parser %s\n", val);
    struct numvariable *a =
     (struct numvariable *)malloc(sizeof(struct numvariable));
    a->nodetype = 'V';
    //  a->value = val;
    return (struct ast *)a;
}

I tried to make it as simple as possible, please tell me if there is any missing information needed to understand the problem.

I think $1 is not of type char* but then, what is its type ? And how to convert it to char* ? I think I am missing something between the lexer and the parser as I don't know why the char* is printed in the lexer and not in the parser... (The same code applied to numbers (change char* to double) works perfectly...)

Thank you in advance for your help :)

1

1 Answers

1
votes

I think $1 is not of type char* but then, what is its type ?

If something didn't have the correct type, the compiler would produce an error or at least a warning (unless you have warnings disabled, are explicitly casting the value or using void pointers, which you aren't in this case). So when there's a type error, you'd usually know about it. That's not the problem here.

char *yycopy = strdup(yytext);
// ...
yylval.var == yycopy;
free(yycopy);

Here you're making var point to the memory returned by strdup and then immediately freeing that memory. So var now points to freed memory and any attempt to dereference it will lead to undefined behaviour.

You should not free the memory for your strings until you're done working with them (which might very well be the end of the program since those string will likely end up in your AST, and possibly the IR as well).