【问题标题】:Shift Reduce Error In YACC减少 YACC 中的误差
【发布时间】:2014-10-03 21:59:31
【问题描述】:

我正在使用 lex 和 yacc。以下是 lex 和 yacc 计算器的程序。在执行 yacc 文件时。请帮我解决这个问题。我收到以下错误:

这是错误:

conflicts: 20 shift/reduce

//YACC程序

 %{
#include<stdio.h>
#include<math.h>

extern void printsymbol();

struct symboltable
{
char name[20];
double value;
}ST[20];

%}

%union
{
double p;
}

%token <p> NUM
%token <p> IDENTIFIER
%token SIN COS TAN ROOT
%left '+' '-'
%left '*' '/'
%type <p> E

%%

Edash:E';'{printf("\n=%f",$1);printsymbol();}
      |Edash E';'{printf("\n=%f",$2);printsymbol();}

E:    E'+'E      {$$=$1+$3;}
      |E'-'E     {$$=$1-$3;}
      |E'*'E     {$$=$1*$3;}
      |E'/'E     {$$=$1/$3;}
      |NUM    {$$=$1;}
      |IDENTIFIER {$$=ST[(int)]$1.value;}
      |'('E')'     {$$=$2;}
      |IDENTIFIER'='E {$$=ST[(int)]$1.value=$3;}
      |SIN E          {$$=sin($2*3.141/180);}
      |COS E          {$$=sin($2*3.141/180);}
      |TAN E          {$$=sin($2*3.141/180);}
      |ROOT E          {$$=sqrt($2);}

%%

int main()
{
yyparse();
}

yyerror()
{
printf("Error Found..!");
}

【问题讨论】:

  • 一些历史版本的“One True Awk”源代码在语法上有多达 96 个 shift/reduce 冲突。查看这个历史悠久的存储库:github.com/danfuzz/one-true-awk 所以,如果您不知道如何操作 Yacc,那么您和贝尔实验室的一些名人一起工作!

标签: yacc


【解决方案1】:

你的冲突来自规则:

  |IDENTIFIER '=' E
  |SIN E
  |COS E
  |TAN E
  |ROOT E

因为这些规则都没有为它们设置优先级(没有在这些规则中的任何标记上设置),所以当您收到 SIN X + Y 这样的输入时,解析器不知道是否 将其解析为
(SIN X) + YSIN (X + Y)

您可以通过为所有这些规则设置优先级来解决它,这很容易通过添加一行来完成

%nonassoc '=' SIN COS TAN ROOT

为所有这些标记设置优先级值,这些标记将被规则继承。由您决定它们是否应该比二元运算符更高或更低的优先级。对于正常的约定,您可能希望 = 的优先级较低,函数的优先级较高(这意味着您实际上需要两个新行而不是将它们全部放在一行中)

【讨论】:

    【解决方案2】:

    您必须使用-v 选项运行yacc 才能生成名为y.output 的文件。在那里你可以找到有关冲突的线索。该文件显示了生成的解析器的详细状态,以及哪些状态在移动特定令牌或通过某些规则减少之间存在冲突。

    您的语法可能存在以下问题:

    E : IDENTIFIER '=' E
    

    假设你有你有

    X = 3 + 5
    

    =+ 的优先级是什么?如果解析器刚刚看到X = 3,并且下一个前瞻标记是+,它应该怎么做?它应该通过规则E : IDENTIFIER '=' E 减少 X = 3E 还是应该转移 + 并继续扫描更长的右侧@987654334 @?

    看看y.output,看看它是否证实了这个假设。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多