YACC规则没有减少 [英] YACC Rules not reduced

查看:49
本文介绍了YACC规则没有减少的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码calc.y.我不断收到错误:yacc:1 条规则从未减少yacc: 3 减少/减少冲突

This is my code calc.y. I keep getting the error: yacc: 1 rule never reduced yacc: 3 reduce/reduce conflicts

不太清楚这是什么意思

我在其他地方做过一些研究,但我现在迷路了.我猜所指的规则是程序和语句,但即便如此……reduce 规则是什么意思?

Ive done some research in other places but I am now lost. Im guessing the rules being referred to is program and statement but even so... what does the reduce rule mean?

%{
  #include <stdio.h>
  FILE *outfile;
  int yyline = 1;
  int yycolumn = 1;
%}

%union{
  int nw;
  struct{
    int v;
    char s[1000];
  }attr;
}

%token   SEMInumber
%token   LPARENnumber
%token   <nw> ICONSTnumber
%token   BEGINnumber
%token   PROGRAMnumber
%token   MINUSnumber
%token   TIMESnumber
%token   <nw> VARnumber
%token   INTnumber
%token   EOFnumber
%token   COMMAnumber
%token   RPARENnumber
%token   <nw>IDnumber
%token   ENDnumber
%token   ISnumber
%token   PLUSnumber
%token   DIVnumber
%token   PRINTnumber
%token   EQnumber

%type <attr> exp
%type <attr> term
%type <attr> factor
%%


program: PROGRAMnumber IDnumber ISnumber compstate
         ;

compstate: BEGINnumber {print_header();} statement ENDnumber{print_end();}
           | BEGINnumber {print_header();} statement SEMInumber statement ENDnumber{print_end();}
           ;

statement: IDnumber EQnumber exp
           | PRINTnumber exp
 | declaration
           ;

declaration: VARnumber IDnumber
             | VARnumber IDnumber COMMAnumber IDnumber
             ;

exp: term {$$.v = $1.v; strcpy($$.s, $1.s);}
     | exp PLUSnumber term {$$.v = $1.v + $3.v; sprintf($$.s, "(%s) + (%s)", $1. s, $3.s);}
     | exp MINUSnumber term {$$.v = $1.v - $3.v; sprintf($$.s, "(%s) - (%s)", $1. s, $3.s);}
     ;

term: factor {$$.v = $1.v; strcpy($$.s, $1.s);}
      | term TIMESnumber factor {$$.v = $1.v * $3.v; sprintf($$.s, "(%s) * (%s)", $1.s, $3.s);}
      | term DIVnumber factor {$$.v = $1.v / $3.v; sprintf($$.s, "(%s) / (%s)", $1.s, $3.s);}
      ;

 factor: ICONSTnumber {$$.v = $1; sprintf($$.s, "%d", $1);}
          | IDnumber {$$.v = $1.v; strcpy($$.s,  $1.s);}
          | LPARENnumber exp RPARENnumber {$$.v = $2.v; strcpy($$.s,  $2.s);}
;


%%


int main()
{
  if(!yyparse())
    {
      printf("accept\n");
    }
  else
    printf("reject\n");
}

void print_header() {}
void print_end(){}

void yyerror(const char *str)
{
  printf("yyerror: %s at line %d\n", str, yyline);
}

推荐答案

当 compstate 移动 BEGINnumber 标记时,中间规则操作的两个内部规则 {print_header();} 都可以减少导致在 R/R 冲突中.你可以替换

When compstate shifts the BEGINnumber token, two inner rules for the mid rule action {print_header();} can be both reduced resulting in a R/R conflict. Youe can replace

compstate: BEGINnumber {print_header();} statement ENDnumber{print_end();}
           | BEGINnumber {print_header();} statement SEMInumber statement 
ENDnumber{print_end();}
           ;

例如

begin_number:
    BEGINnumber { print_header(); }

compstate: begin_number statement ENDnumber{print_end();}
           | begin_number statement SEMInumber statement 
ENDnumber{print_end();}
           ;

解决冲突.

这篇关于YACC规则没有减少的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆