I'm not very experienced in bison and flex and i need some help.
i have some errors in my .y file.
syntax wise its fine and it compiles when i "bison -d" it but when i try to compile with gcc it gives me some errors that im not sure how to solve(total noob here):
https://i.stack.imgur.com/fUeR7.png
the .lex file:
%{
#include "meals.tab.h"
#include <string.h>
extern void exit(int);
int line = 1;
#define VEGETABLE 1
#define FRUIT 2
#define BREAD 3
#define MEAT 4
#define CAKE 5
#define CHOCOLATE_ICE_CREAM 6
#define VANILLA_ICE_CREAM 7
#define BEGIN_MEAL 100
#define END_MEAL 101
%}
%option noyywrap
%%
"<meal>" {return BEGIN_MEAL;}
"</meal>" {return END_MEAL;}
"broccoli" {return VEGETABLE;}
"lettuce" {return VEGETABLE;}
"tomato" {return VEGETABLE;}
"cucumber" {return VEGETABLE;}
"orange" {return FRUIT;}
"apple" {return FRUIT;}
"strawberry" {return FRUIT;}
"watermelon" {return FRUIT;}
"chicken" {return MEAT;}
"beef" {return MEAT;}
"bread" {return BREAD;}
"cake" {return CAKE}
"chocolate ice cream" {return CHOCOLATE_ICE_CREAM ;}
"vanilla ice cream" {return VANILLA_ICE_CREAM ;}
"," /* skip comma */
[\t ]+ /* skip white space */
\n { line++; }
. { fprintf (stderr, "line %d: unrecognized token %c\n",
line, yytext[0]);
exit(1);
}
%%
the .y file:
%code {
#include <stdio.h>
extern int yylex (void);
void yyerror (const char *s);
struct diet
}
%code requires {
struct diet {
int veg_fruit, dessert, calories, isDesertFine, isVeggieFine;
};
}
%union {
struct diet _diet;
}
%token BEGIN_MEAL END_MEAL VEGETABLE FRUIT MEAT BREAD CAKE CHOCOLATE_ICE_CREAM VANILLA_ICE_CREAM
%type <_diet> list_of_meals meal list_of_servings serving
%error-verbose
%%
day: list_of_meals{
if(($1.calories <= 18) && ($1.isDesertFine == 0) && ($1.isVeggieFine == 0))
printf ("everything is OK\n");
else if($1.calories <= 18 && $1.isDesertFine == 0)
printf ("Not enough veggies/fruits\n");
else if($1.calories <= 18 && $1.isVeggieFine == 0)
printf ("Too many desserts\n");
else if($1.isDesertFine == 0 && $1.isVeggieFine == 0)
printf ("Too many calories: total is $1.calories\n");
else if($1.calories <= 18){
printf ("Too many desserts\n");
printf ("Not enough veggies/fruits\n");
}
else if($1.isDesertFine == 0){
printf ("Too many calories: total is $1.calories\n");
printf ("Not enough veggies/fruits\n");
}
else if($1.isVeggieFine == 0){
printf ("Too many desserts\n");
printf ("Too many calories: total is $1.calories\n");
}
else{
printf ("Too many calories: total is $1.calories\n");
printf ("Too many desserts\n");
printf ("Not enough veggies/fruits\n");
}
};
list_of_meals: list_of_meals meal {$$.calories = $1.calories + $2.calories;
$$.isDesertFine = $1.isDesertFine + $2.isDesertFine;
$$.isVeggieFine = $1.isVeggieFine + $2.isVeggieFine;};
list_of_meals: /*empty*/ {$$.calories = -1;
$$.veg_fruit = -1;
$$.dessert = -1;
$$.isVeggieFine = 1;
};
meal: BEGIN_MEAL list_of_servings END_MEAL {if($2.calories > 18)
printf ("Meal : too many calories\n");
if($2.veg_fruit < 2){
printf ("Meal : not enough veggies/fruit\n");
$$.isVeggieFine = 1;
}else{ $$.isVeggieFine = 0;}
if($2.dessert > 1){
printf ("Meal : too many desserts\n");
$$.isDesertFine = 1;
}else{ $$.isDesertFine = 0;}
$$.calories = $2.calories;
};
list_of_servings: list_of_servings ',' serving {$$.calories = $1.calories + $3.calories;
$$.veg_fruit = $1.veg_fruit + $3.veg_fruit;
$$.dessert = $1.dessert + $3.dessert;};
list_of_servings: serving {$$.calories = $1.calories;
$$.veg_fruit = $1.veg_fruit;
$$.dessert = $1.dessert;};
serving: VEGETABLE {$$.calories = 1; $$.veg_fruit = 1;}
| FRUIT {$$.calories = 2; $$.veg_fruit = 1;}
| MEAT {$$.calories = 3;}
| BREAD {$$.calories = 4;}
| CAKE{$$.calories = 5; $$.dessert = 1;}
| CHOCOLATE_ICE_CREAM{$$.calories = 6; $$.dessert = 1;}
| VANILLA_ICE_CREAM {$$.calories = 7; $$.dessert = 1;}
;
%%
#include <stdio.h>
#include <stdlib.h>
main (int argc, char **argv)
{
extern FILE *yyin;
if (argc != 2) {
fprintf (stderr, "Usage: %s <input-file-name>\n", argv[0]);
return 1;
}
yyin = fopen (argv [1], "r");
if (yyin == NULL) {
fprintf (stderr, "failed to open %s\n", argv[1]);
return 2;
}
yyparse ();
fclose (yyin);
return 0;
}
void yyerror (const char *s)
{
extern int line;
fprintf (stderr, "line %d: %s\n", line, s);
}
Thanks!