1
votes

I am trying to develop a language parser on CentOS 6.0 by means of Bison 3.0 (C parser generator), Flex 2.5.35 and gcc 4.4.7. I have the following Bison grammar file:

%{
#include <stdio.h>
%}

%union {
  int int_t;
  char* str_t;
}
%token SEP
%token <str_t> ID
%start start
%type <int_t> plst

%%

start: plst start
     | EOS              { YYACCEPT; }
;
// <id> , <id> , ... , <id>
plst: ID SEP_PARAMS plst    { printf("Rule 1 %s %s \n",$1,$2); } 
    | ID            { printf("Rule 2 %s \n", $1); }
    | /* empty */       {  }
;

%%

int yyerror(GNode* root, const char* s) {printf("Error: %s", s);}

The problem

As it is now, it is not really a meaningful one, but it is enough to understand my problem I think. Consider that I have a scanner written in Flex which recognizes my tokens. This grammar file is used to recognize simple identifier lists like: id1,id2,...,idn. My problem is that in each grammar rule, when I try to get the value of the identifier (the string representing the same of the identifier), I get a NULL pointer as also proved by my printfs.

What am I doing wrong? Thankyou

Edit

Thanks to recent answers, I could understand that the problems strongly relates to Flex and its configuration file. In particular I have edited my lex file in order to meet the specifications described by the Flex Manual for Bison Bridging:

{ID}     { printf("[id-token]");
           yylval->str_t = strdup(yytext);
           return ID; }

However after running Bison, then Flex (providing the --bison-bridge option) and then the compiler, I execute the generated parser and I instantly get Segmentation Fault.

What's the problem?

2
You do set the correct union fields in the lexer?Some programmer dude
ehm... I do not know what you are talking about... I import in the lex file the .tab.h file generated by bison if this is what you mean...Andry
Should I show the lex file as well? Is it related?Andry
Found an answer for my edit thanks to this question: stackoverflow.com/questions/6432549/why-is-yylval-nullAndry

2 Answers

2
votes

The flex option --bison-bridge (or %option bison-bridge) matches up to the bison option %define api.pure. You need to use either BOTH bison-bridge and api.pure or NEITHER -- either way can work, but they need to be consistent. Since it appears you are NOT using api.pure, you want to delete the --bison-bridge option.

0
votes

The values for $1, $2 etc. have to be set by the lexer.

If you have a rule in the lexer for identifiers, like

ID       [a-z][a-z0-9]*

%%

{ID}    { return ID; }

the semantic values are not set.

You have to do e.g.

{ID}    {   /* Set the unions value, used by e.g. `$1` in the parser */
            yylval.str_t = strdup(yytext); 
            return ID;
        }

Remember to free the value in the parser, as strdup allocates memory.