5

I'm writing a simple calculator based on .gertrude esolang. What I'm trying to do is parse a text file that contains ratios (in the form of n/m) with flex, than check if the ratio is an index for an operation (+ - / *) or a number and than send the right token to Bison. I get no error when the code are compiled, but when the program is running returns a -segmentation fault core dump - for every kind of input (like 1/2 14/10 1/8 that should be 2 + 8).

Here gertrude.l

%{ 
#include <stdlib.h> 
#include <string.h>
#include <stdio.h>
#include "gertrude.tab.h" 
void yyerror(char *);    

int FrazioneToDecimale(char *str1){
    int num, den;
        unsigned tot;
        char *token;
    char *deli;
            const char del = '/';
            *deli = del;
        token = strtok (str1, deli);
        num = atoi(token);
        token = strtok (NULL, deli);
        den = atoi(token);   
        tot = 1 / (num/den);
    return tot;
}
%}

%% 

/* ratio */ 

"14/10" {
            yylval.sval = '+';
            return SOMMA;
            }

"11/7"  { 
            yylval.sval = '-';
            return SOTTRAZIONE;
            }


"6/16"  {
            yylval.sval = '*';
            return MOLTIPLICAZIONE;
            }

"5/8"   {
            yylval.sval = '/';
            return DIVISIONE;
            }

[0-9]+"/"[0-9]+    {
                            //yylval = *yytext ;
            yylval.ival = FrazioneToDecimale(yytext);
                return NUMERO;
                } 


[ \t] ;


[ \n] { return EOL; };

%% 



int yywrap(void) { 
return 0; 

} 

Here gertrude.y

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

%union {
int ival;
char sval;
}

%type <ival>  exp fattore termine
%token <ival> NUMERO
%token <sval> SOMMA SOTTRAZIONE MOLTIPLICAZIONE DIVISIONE 
%token EOL 

%% 

istruzione: 
    | istruzione exp EOL { printf("= %d\n", $2); }
    ;

exp: fattore
    | exp SOMMA fattore { $$ = $1 + $3; } 
    | exp SOTTRAZIONE fattore { $$ = $1 - $3; } 
    ;

fattore: termine
       | fattore MOLTIPLICAZIONE termine { $$ = $1 * $3; }
   | fattore DIVISIONE termine { $$ = $1 / $3; }
            ;

termine: NUMERO { $$ = $1; }
       ;

%%
int main(void) {
    yyparse();
}

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

Thanks in advance for any kind of advice!

thebeefeater
  • 53
  • 1
  • 4
  • Please be careful of tagging. Flex is for the Apache/Adobe UI Framework. Flex-lexer is for the lexical analyzer. – JeffryHouser Oct 16 '13 at 10:37
  • Sorry and thanks for the tip; i've just picked the one suggested below the box! – thebeefeater Oct 16 '13 at 10:41
  • Duplicate of http://stackoverflow.com/questions/8957829 – stackoverflow Oct 16 '13 at 11:14
  • No, not a duplicate of stackoverflow.com/questions/8957829, even if both are about strtok problems. That one is about trying to change a constant string. – Thomas Padron-McCarthy Oct 16 '13 at 13:45
  • thanks for the link. I've understood what the problem is, but I'm still trying to let it work. If I copy the yytext content into a char[8] buff with strcpy, than call the function passing buff as argument, I still get the same seg fault error. – thebeefeater Oct 16 '13 at 15:05

1 Answers1

6

Your code has a problem with pointers and strings. This is a C problem, not a Bison or Flex problem.

Look at these lines from gertrude.l:

char *deli;
const char del = '/';
*deli = del;

Your pointer variable deli is uninitialized and contains garbage, so it might point anywhere. Then you follow that pointer to where it points (anywhere!) and you put a character there. This causes the program to crash. Plus the string (wherever it is) isn't NUL-terminated.

Simply replace those three lines with this line:

 char *deli = "/";
Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
  • Thank you mate! That was the the error! Now it works fine! Lesson learned today: always inizialize what you declare! Again, thanks! – thebeefeater Oct 16 '13 at 16:40