【问题标题】:yacc parser reduces before left recursion suffixyacc 解析器在左递归后缀之前减少
【发布时间】:2021-11-22 16:45:58
【问题描述】:

我在 yacc 中编写了一个非常简单的左递归语法,它基于一种简单的类 C 语言的数据类型。生成的 yacc 解析器在左递归后缀之前减少,我也不知道为什么。

这里是源代码:

%%
start: type {
        printf("Reduced to start.\n");
    };

type: pointer {
        printf("Reduced pointer to type.\n");
    } 
    | char {
        printf("Reduced char to type.\n");
    };

char: KW_CHAR {
        printf("Reduced to char.\n");
    };

pointer: type ASTERISK {
        printf("Reduced to pointer.\n");
    };
%%

给定输入char * (KW_CHAR ASTERISK):

Reduced to char.
Reduced char to type.
syntax error

【问题讨论】:

  • 我认为您的源代码在语法之外有问题,或者您没有正确构建它。很难说,因为显示的不够多。填写详细信息,对我来说效果很好。
  • 很可能是词法分析器问题——也许是空间引起了问题。尝试在启用 YYDEBUG 的情况下运行(在调用 yyparse(); 之前设置 yydebug = 1;

标签: c parsing yacc lalr


【解决方案1】:

您似乎不是在询问您收到的解析错误(如 cmets 中所述,这可能是yylex() 返回的令牌类型的问题),而是为什么解析器减少按照跟踪显示的顺序执行。这就是我将在这里尝试解决的问题,即使它很可能是 XY problem,因为理解归约顺序很重要。

在这种情况下,归约顺序非常简单。如果您有作品:

pointer: type ASTERISK 

那么type 必须在ASTERISK 移位之前减少。在 LR 解析器中,当要归约的右侧恰好在最后一个消耗的输入令牌处结束时,必须进行归约。 (前瞻标记已被词法扫描器识别,但尚未被解析器使用。因此它不是归约的一部分,也可用于识别在同一点结束的其他归约。)

我希望制作过程中的原因更加明显

type: char

char 需要在type 之前减少。在减少char 之前,它不能用于减少type

确实,这两个示例显示了相同的行为。减少是从左到右执行的,从下到上(即,儿童优先)。因此这种解析的名称。

因此,您的解析器显示的归约顺序(首先是 char,然后是 type,只有在 * 移动后,pointer)正是预期的。

【讨论】:

  • 谢谢。这是一个词法分析器的问题,但是我对解析的理解不够,所以我认为这是一个解析器的问题。
猜你喜欢
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
  • 2015-08-03
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多