2017-06-06 87 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