• C

error: invalid operands to binary

Hello,

I try to compile my yacc grammar but i get the following errors :

error: invalid operands to binary *
error: invalid operands to binary /


Thanks in advance for any help !
unknown_Asked:
Who is Participating?
 
mrjoltcolaConnect With a Mentor Commented:
You have the %type factor declared as sval:

%type <sval> factor


But you are using it as numeric in the "term" rule:

term                  :      factor '*' factor  {printf("rule 4\n");} {$$ = $1 * $3;}
|      factor '/' factor  {printf("rule 5\n");} {$$ = $1 / $3;}
|      factor {printf("rule 6\n");}  {$$ = $1;}  ;


$1  *  $3 is the same as if you wrote:   yylval1.sval  *  yylval2.sval

You can't multiple 2 strings, and your intention here is to treat them has numbers, so define them as such in your %type declarations

0
 
unknown_Author Commented:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

      
#define YYDEBUG 1

extern int  yyparse();
extern FILE *yyin;      

int yywrap()
 {
    return 1;
 }

void yyerror(const char *s)
 {
    fflush(stdout);
    printf("\n%*s\n%*s\n", s);
 }



enum treetype {operator_node, number_node, variable_node};
 typedef struct tree {
   enum treetype nodetype;
   union {
     struct {struct tree *left, *right; char operator;} an_operator;
     int ival;
     char sval;
   } body;
 } tree;
 static tree *make_operator (tree *l, char o, tree *r) {
   tree *result= (tree*) malloc (sizeof(tree));
   result->nodetype= operator_node;
   result->body.an_operator.left= l;
   result->body.an_operator.operator= o;
   result->body.an_operator.right= r;
   return result;
 }
 static tree *make_number (int n) {
   tree *result= (tree*) malloc (sizeof(tree));
   result->nodetype= number_node;
   result->body.ival= n;
   return result;
 }
 static tree *make_variable (char v) {
   tree *result= (tree*) malloc (sizeof(tree));
   result->nodetype= variable_node;
   result->body.sval= v;
   return result;
 }
 static void printtree (tree *t, int level) {
 #define step 4
   if (t)
     switch (t->nodetype)
     {
       case operator_node:
        printtree (t->body.an_operator.right, level+step);
        printf ("%*c%c\n", level, ' ', t->body.an_operator.operator);
        printtree (t->body.an_operator.left, level+step);
        break;
       case number_node:
        printf ("%*c%d\n", level, ' ', t->body.ival);
        break;
       case variable_node:
        printf ("%*c%c\n", level, ' ', t->body.sval);
     }
 }



%}
 
%start goal

%union {
      int ival;
      char * sval;
        tree* btree;
}
 
%token <sval> IDENTIFIER
%token <sval> VARIABLE
%token <ival> INTEGER
 /*%token <ival> FLOAT*/
%token <sval> STRING
%token <sval> LITERAL
%token <sval> UNKNOWN
%token <sval> PLUS
%token <sval> MINUS
%token <sval> TIMES
%token <sval> SLASH
%token <sval> LPAREN
%token <sval> RPAREN
%token <sval> SEMICOLON
%token <sval> COMMA
%token <sval> EQL
%token <sval> OR
%token <sval> OR2
%token <sval> AND
%token <sval> AND2
/* keywords */
%token <sval> IF
%token <sval> ELSE
%token <sval> statement
%token <sval> DO
%token <sval> INT
%token <sval> RETURN
%token <sval> VOID
%token <sval> FLOAT
%token <sval> WHILE
%type <btree> goal
%type <ival> expression
%type <ival> term
%type <sval> factor
%type <sval> ifstatement
%type <sval> whilestatement
%type <sval> dostatement
%type <sval> variable_list
%type <sval> variable



%%

goal                  :
variable '=' expression SEMICOLON {printf("rule : VAR = Expression\n");}
|      ifstatement SEMICOLON
|      whilestatement SEMICOLON
|       dostatement SEMICOLON
|      INT variable_list SEMICOLON {printf("rule: INT_VARIABLE\n");}      
|      FLOAT variable_list SEMICOLON   {printf("rule: FLOAT_VARIABLE\n");} {printtree ($1, 1);} ;

expression            :      term '+' term {printf("rule 1\n");} {$$ = make_operator ($1, '+', $3);}
|      term '-' term {printf("rule 2\n");} {$$ = make_operator ($1, '-', $3);}
|      term {printf("rule 3\n");}  {$$ = $1;}   ;

term                  :      factor '*' factor  {printf("rule 4\n");} {$$ = $1 * $3;}
|      factor '/' factor  {printf("rule 5\n");} {$$ = $1 / $3;}
|      factor {printf("rule 6\n");}  {$$ = $1;}  ;

factor                  :      variable {printf("rule 7\n");} {$$ = make_variable ($1);}
|      INTEGER {printf("rule 8\n");} {$$ = make_number ($1);}
|      FLOAT {printf("rule 9\n");} {$$ = make_number ($1);}
|      STRING {printf("rule 10\n");}
|      '(' expression ')' {printf("rule 11\n");} {$$= make_block ($2);};

ifstatement            :      IF '(' expression ')' goal ELSE goal SEMICOLON {printf("rule: IF_ELSE_STATEMENT\n");}
|      IF '(' expression ')' goal {printf("rule: IF_STATEMENT\n");};

whilestatement      :      WHILE '(' expression ')' goal {printf("rule: WHILE_STATEMENT\n");} {$$= make_while ($3, $5);} ;      
            
dostatement : DO expression WHILE '(' expression ')'   {printf("rule DO_STATEMENT\n");} {$$= make_do ($2, $5);} ;


variable : VARIABLE {printf("rule var2\n");}  {$$= list ($1); /* [$1] */} ;

      
variable_list : VARIABLE {printf("rule 15\n");} {$$= list ($1); /* [$1] */}
|        variable ',' variable_list {printf("rule 16\n");}  ;

                     
%%

#include "lex.yy.c"

main(int argc,char *argv[])
{
 if(argc<1)
  {
   printf("Please specify the input file\n");
   exit(0);
  }
 FILE *fp=fopen(argv[1],"r");
 if(!fp)
 {
  printf("couldn't open file for reading\n");
  exit(0);
 }
  yyin=fp;
  yyparse();
  fclose(fp);
}
 
 
0
 
HalfAsleepCommented:
Is it just me, or does the printf statement in yyerror look a bit suspect?

printf("\n%*s\n%*s\n", s);

I don't think I have ever seen a "%*s %*s", s statement before.

I can understand something like the code I have supplied, but what on earth does that printf statement do?
 const char* msg = "Hello printf";
 int string_size = strlen (msg);
 printf("msg: %.*s", string_size, msg);

Open in new window

0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
Infinity08Commented:
HalfAsleep, %*s also works - it provides a minimum width to print the string. However, that printf is missing three parameters :) The output will likely show garbage.
0
 
HalfAsleepCommented:
That is what I meant, I could not understand the single string parameter.  For that printf, I would expect 4.
0
 
unknown_Author Commented:
Thank you very much !
 Can you please have a look to the print parse tree question:
http://www.experts-exchange.com/Programming/Languages/C/Q_24279119.html

Im not sure how to work with the printout of the parse tree.


Thanks!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.