1

I'm working on a bison/flex project where I am using string but I'm not able to use well methods like strlen() (same for strcmp etc.)

To better explain I wrote a new short .l and .y files:

%{
#include <string>
#include "test.tab.h"
void yyerror(char*);
extern void printVars();
int yyparse(void);
char linebuf[500];


%}

%option yylineno

blanks          [ \t\n]+
text            [^<>]+


%%

\n.*  { strncpy(linebuf, yytext+1, sizeof(linebuf)); /* save the next line */
        yyless(1);      /* give back all but the \n to rescan */
       }

{blanks}        { /* ignore */ };

"<test>"        return(START);
"</test>"       return(STOP);
"<string>"      return(BEGIN_STRING);
"</string>"     return(END_STRING);
"<num>"         return(BEGIN_NUM);
"</num>"        return(END_NUM);

{text}          { yylval.str_val=strdup(yytext);
                  return(IDENTIFIER);
                }

.               return yytext[0];

%%


void yyerror(char *s){ 
    printf("--------- ERROR ---------\n");
    printf("%d: %s at %s in this line:\n%s\n", yylineno, s, yytext, linebuf);
    }

int yywrap (void){
    printf("--------- EOF ---------\n");
    }

int main(int num_args, char** args){
    if(num_args != 2) {printf("usage: ./parser filename\n"); exit(0);}
    FILE* file = fopen(args[1],"r");
    if(file == NULL) {printf("couldn't open %s\n",args[1]); exit(0);}
    yyin = file;
    yyparse();
    fclose(file);

    printVars();
}

And

%{
#include <stdio.h>
#include <string>
#define MAX_VAR     10

using namespace std;
extern int yylex();
extern void yyerror(char*);
void printVars();

string data_str[MAX_VAR];
string data_int[MAX_VAR];
int num_data_str = 0;
int num_data_int = 0;

%}



//Symbols
%union
{
    char *str_val;
};

%token START
%token STOP
%token BEGIN_NUM
%token END_NUM
%token BEGIN_STRING
%token END_STRING

%token <str_val>    IDENTIFIER

%start MyTest

%%

MyTest:
    START Block STOP
    ;

Block:
    /* empty */
    | Block 
      BEGIN_STRING IDENTIFIER END_STRING
      { if(num_data_str<MAX_VAR){
            data_str[num_data_str]=$3;
            num_data_str++;
        }
        else printf("string: %s not saved!\n", $3); }
    | Block
      BEGIN_NUM IDENTIFIER END_NUM
      { if(num_data_int<MAX_VAR){
            data_int[num_data_int]=$3;
            num_data_int++; //saved
        }
        else printf("integer: %s not saved!\n", $3); }
    ;

%%

void printVars(){
    printf("Printing Strings:\n");
    for(int i=0;i<num_data_str;i++) printf("-- %s of length %d\n",data_str[i].c_str(),strlen(data_str[i]));
    printf("Printing Integers:\n");
    for(int i=0;i<num_data_int;i++) printf("-- %s \n",data_int[i].c_str());

}

As you can see I have

#include <string>
using namespace std;

In this way I have the following error while compiling:

test.tab.c: In function ‘int yyparse()’:
test.tab.c:1289:35: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
       yyerror (YY_("syntax error"));
                                   ^
test.tab.c:1433:35: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
   yyerror (YY_("memory exhausted"));
                                   ^
test.y: In function ‘void printVars()’:
test.y:66:100: error: ‘strlen’ was not declared in this scope
  for(int i=0;i<num_data_str;i++) printf("-- %s of length %d\n",data_str[i].c_str(),strlen(data_str[i]));
pittuzzo
  • 493
  • 8
  • 29
  • If you want to use c++, you could consider using bisonc++ and flexc++ instead. These are geared towards generating clean and clear c++ code. See http://bisoncpp.sourceforge.net/bisonc++man.html and http://flexcpp.sourceforge.net/. – dgel Aug 05 '15 at 12:12

1 Answers1

3

As you can see I have #include <string>

C string functions in C++ require <cstring> header, not <string>.

Since flex/bison produce C code, consider turning off the deprecated conversion warning. This Q&A explains how.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Actually I tried also cstring but it is worse: `test.y:10:1: error: ‘string’ does not name a type string data_str[MAX_VAR]; ^ test.y:11:1: error: ‘string’ does not name a type string data_int[MAX_VAR]; ^` Thank you for the howto turning off deprecated conversion warning, now I'm using: `bison -d test.y; flex test.l; g++ -Wno-write-strings -o test1 lex.yy.c test.tab.c;` – pittuzzo Aug 05 '15 at 12:16
  • @pittuzzo Since you are using both `strlen` from `` and `std::string` from ``, you need both headers. – Sergey Kalinichenko Aug 05 '15 at 12:20
  • Yes, finally working: using `#include ` - `#include ` - `using namespace std;` together – pittuzzo Aug 05 '15 at 12:37