0
votes

Im trying to convert from infix to postfix and capturing the char in the correct order using a list. Here is my bison file:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
%}
%union{
    char list[100];
    int integer;
};

%token <integer> NUM
%token ENDOFLINE
%left '+' '-'
%left '*' '/'
%right NEGATIVE
%type <list> Exp
%%

Statement: 
    | Statement Line
;
Line: Exp ENDOFLINE{ printf("Result -> %s\n", $1);  }
    | ENDOFLINE
;
Exp:  Exp '+' Exp {add($$,(char)$2);}
    |   Exp '*' Exp {add($$,(char)$2);}
    |   Exp '-' Exp {add($$,(char)$2);}
    |   Exp '/' Exp {add($$,(char)$2);}
    |   '-' Exp %prec NEGATIVE {add($$,(char) $1);}
    |   NUM     {$$ = create_list(); add($$,(char) $1);}
;
%%
char * create_list(){
    char expList [100];
    return expList;
}
void add(char* array, char input){
    int length = stlen(array);
    array[length] = input;
}
int main(){
    yyparse();

}

int yyerror (char *msg) {
    return printf ("error YACC: %s\n", msg);
}

I have multiple problems, one being that it says i cant add an int to char[], and another saying request for member add in something not a struct or union. I'm very new to Bison/Flex, is this the proper implementation if i want to store these values so i might use them in main(at some point)?

EDIT: Here is my most up to date code. I updated my lex file to recognize the individual operators and return that token as well as added the proper functions and their prototypes to my bison file(a4grammer2.y).

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>

    char * create_list();
    void add(char* array, char input);
    int yyerror(char* s);
    int main(void);
%}
%union{
    char list[100];
    char character;
    int integer;
};

%token <integer> NUM
%token <character> PLUS
%token <character> MINUS
%token <character> MULTIPLY
%token <character> DIVIDE
%token ENDOFLINE
%right NEGATIVE
%type <list> Exp
%%

Statement: 
    | Statement Line
;
Line: Exp ENDOFLINE{ printf("Result -> %s\n", $1);  }
    | ENDOFLINE
;
Exp:  Exp PLUS Exp {add($$,$2);}
    |   Exp MULTIPLY Exp {add($$,$2);}
    |   Exp MINUS Exp {add($$,$2);}
    |   Exp DIVIDE Exp {add($$,$2);}
    |   MINUS Exp %prec NEGATIVE {add($$,$1);}
    |   NUM     {strcpy($$,create_list()); add($$, $1);}
;
%%
char * create_list(){
    char expList [100];
    return expList;
}
void add(char* array, char input){
    int length = stlen(array);
    array[length] = input +'0';
}
int main(){
    yyparse();

}

int yyerror (char *msg) {
    return printf ("error YACC: %s\n", msg);
}

now when i compile this using:

yacc -d a4grammer2.y

I get this error

warning: 20 shift/reduce conflicts [-Wconflicts-sr]

and when i try to compile using gcc i get this:

a4grammer2.y: In function ‘create_list’:
a4grammer2.y:44:5: warning: function returns address of local variable [-Wreturn-local-addr]
     return expList;
1
The value for Exp is an array of characters, meaning that in the Exp rules $$ is also an array of characters. And you would not expect e.g. list->add('+') to work, would you? You need to actually create functions to append the characters to the array.Some programmer dude
@JoachimPileborg i believe i added the proper function that i need. However when i try to pass the second parameter it tells me it has no type even when i try and cast it as a charjustin
You need to add a prototype declaration of the function before you can call it, otherwise the compiler will not know it exits. Also, if you want to treat the array as a string, you need to remember to zero-terminate it properly. Lastly, please edit your question to show the actual and complete and unedited errors, because otherwise all we can do, really, is just guess.Some programmer dude
@JoachimPileborg i edited in my most up to date code along with the full errors/warnings it is producing when i go to compile it.justin
You are returning a pointer to a local variable in the create_list function, and as you (should) know local variables go out of scope when a function returns, leaving you with a stray pointer. You don't even need that function, just do e.g. strcpy($$, strtol($1, NULL, 10));Some programmer dude

1 Answers

0
votes

Apart from what has been noted in comments:

Exp:  Exp '+' Exp {add($$,(char)$2);}

This, and every production like it, should be of the general form

Exp:  Exp '+' Exp {$$ = add($1,$3);}

and I have no idea what makes you think that every Exp can be cast to a char. Life would be very uninteresting, and your program entirely unnecessary, if that were the case.