mercredi 5 août 2015

C String while using Bison/Flex


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]));



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire