2017-06-06 107 views
0

我對野牛和彎曲不是很有經驗,我需要一些幫助。野牛&彎曲錯誤

我在我的.y文件中有一些錯誤。

語法明智的罰款和編譯的時候是我「野牛-d」它 但是當我嘗試用gcc來編譯它給了我一些錯誤,即時通訊不知道如何解決(這裏總小白):

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


%% 

中不間斷文件:

%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編譯器。

但是,該聲明是不必要的,應該簡單地刪除。

也有一些問題,你的Flex文件:

  1. 不要這樣做:

    #define VEGETABLE 1 
    #define FRUIT 2 
    ... 
    

    正確的標記定義在野牛創建的頭文件,它必須已包括在內。您提供的值不正確,將導致解析失敗。

  2. 不要這樣做之一:

    extern void exit(int); 
    

    exit在標準頭stdlib.h聲明;你應該包含頭文件,而不是第二個猜測的內容:

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

    請注意,這是傳統的,包括你自己的頭文件(如野牛產生的一個)之前,包括系統頭。

  3. 最後,我強烈建議你刪除了自己的企圖line跟蹤行號,相反只是讓柔性做到這一點:

    %option yylineno 
    

    會導致柔性插入有效的代碼,以保持當前行編號在變量yylineno。此外,它會正確保持行號,因爲它理解所有的角落案例。 (除非你使用input()迴避柔性處理,直接從yyin閱讀)

+0

謝謝!它現在編譯 – naknik