2017-06-06 10 views
0

私はバイソンとフレックスに経験が豊富で、何か助けが必要です。Bison&flexエラー

私の.yファイルにいくつかのエラーがあります。

賢明な構文の罰金と私は それを「バイソンは、-d」が、私はgccでコンパイルしようとすると、それは私に(ここでは合計noobのを)解決する方法がわからないイムいくつかのエラーを与えるときには、コンパイルされます。

https://i.stack.imgur.com/fUeR7.png

.lexファイル:

%{ 
#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); 
      } 


%% 

.Yファイル:

%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); 
} 

ありがとう!

+0

画像などのテキストを含めないでください。それは読むのが難しく、答えを引用することも不可能です。代わりに、テキスト(またはそれに関連する部分)をコピーしてあなたの質問に貼り付けてください。 – rici

答えて

2

問題は、あなたのバイソンファイルの最初の%codeセクションにおけるCの構文エラーです:セミコロンが欠けている

struct diet 

、そして最終的にはCコンパイラに渡されたときに予測できないの様々なコンパイルエラーを作成します。

ただし、宣言は不要で、単に削除する必要があります。

あなたのフレックスファイルといくつかの問題もあります。正しいトークン定義は、あなたが持っているバイソン、によって作成されたヘッダ・ファイルである

#define VEGETABLE 1 
#define FRUIT 2 
... 

  1. はこれをしないでくださいすでに含まれています。入力した値が正しくないため、解析が失敗します。

  2. はこれをしないでください 次のいずれか

    extern void exit(int); 
    

    exit標準ヘッダstdlib.hで宣言されています。 (そのようバイソンによって生成された1など)、独自のヘッダを含む前に、システムヘッダを含めることが一般的であることを

    #include <stdlib.h> 
    #include <string.h> 
    #include "meals.tab.h" 
    

    注:あなたは、ヘッダーファイルの代わりに、第二推測その内容を含める必要があります。

  3. 最後に、私は強くあなたがlineに行番号を追跡するために、独自の試みを削除することをお勧めします、とだけではなく、フレックスがそれをやらせる:

    %option yylineno 
    

    は、現在の行を維持するために効率的なコードを挿入するには、Flexが発生します変数yylinenoの数値。さらに、すべてのコーナーケースを理解しているので、行番号を正しく維持します。 (あなたが直接yyinからの読み取りにinput()を使用して、フレックス処理を回避場合を除きます。)

+0

ありがとうございます!今コンパイルする – naknik

関連する問題