【问题标题】:yacc loses values among reductionyacc 在减少中失去价值
【发布时间】:2014-10-26 10:23:13
【问题描述】:

我正在研究此语法以构建用于类型检查或类似的 SDD。我昨天花了很多时间研究数据结构和解析操作,但我总是遇到分段错误。在我看来,YACC(bison) 在减少中失去了价值。

因此,我决定用更简单的动作构建更简单的语法。似乎值在一次又一次减少中丢失了,或者我做错了什么?词法分析器部分在此示例中不相关,因此我省略了它。

遵循语法及其操作以及结果与预期结果..

D:   T VAR SEMICOLON D              {
                                    printf("processing D -> T var ; D\n");
                                    printf("\tvalue of T is %f\n", $1);
                                }
|/*empty*/                      {
                                    printf("processing D -> empty\n");
                                }
;

T:  B                               {
                                    printf("processing B inside T\n");
                                    printf("\tvalue of B is %f\n", $1);
                                } 

C                               {   printf("processing C inside T\n");
                                    printf("processing T-> B C\n");
                                    printf("\tvalue of B is %f\n", $1);
                                    printf("\tvalue of C is %f\n", $<dbl>2);
                                    $$ = $1 + $<dbl>2;

                                }
| RECORD '{' D '}'              {   printf("processing record { D }\n");}
;

B:   INT                            {   printf("processing B -> int\n");
                                    $$ = 1;
                                }
| FLOAT                         {   printf("processing B -> float\n");
                                    $$ = 1;
                                }
;

C:  /*empty*/                       {   printf("processing C -> empty\n");
                                    printf("\tsetting C to be equal to 1\n");
                                    $$=1;
                                }
| LBRACK NUM RBRACK C           {   int n = $2;
                                    printf("processing C -> [%d] C\n", n);
                                    double d = $4;
                                    printf("\tprevious C value is %f\n", d);
                                    double f = d+ 1;
                                    printf("\tnew value of $$ is %f\n", f);
                                    $$ = f;
                                }
;

这是像int [12][3] ciao;这样的输入的输出

processing B -> int
processing B inside T
    value of B is 1.000000
processing C -> empty
    setting C to be equal to 1
processing C -> [3] C
    previous C value is 1.000000
    new value of $$ is 2.000000           
processing C -> [12] C                    
    previous C value is 2.000000          
    new value of $$ is 3.000000           
processing C inside T
processing T-> B C
    value of B is 1.000000
    value of C is 0.000000                (*)
processing D -> empty
processing D -> T var ; D
    value of T is 1.000000                (*)

正如您所见,在标有 * 的 C 缩减中丢失了价值,我希望它会长大,如下所示

processing B -> int
processing B inside T
    value of B is 1.000000
processing C -> empty
    setting C to be equal to 1
processing C -> [3] C
    previous C value is 1.000000
    new value of $$ is 2.000000           
processing C -> [12] C                    
    previous C value is 2.000000          
    new value of $$ is 3.000000           
processing C inside T
processing T-> B C
    value of B is 1.000000
    value of C is 3.000000                
processing D -> empty
processing D -> T var ; D
    value of T is 4.000000                

感谢任何提示以及达到范围的解释和建议,有什么我遗漏的吗?

【问题讨论】:

  • T->C 产生式只有一项,而您在语义动作中引用了两项。
  • 不!请注意,它们之间没有管道..产生式是T-> B C..

标签: c parsing bison yacc parser-generator


【解决方案1】:

T 的产生式如下,大大简化了:

T: B { /* Mid Rule Action (MRA) */ } C { $$ = $1 + $2; }

T 的最终操作中,$2 指的是 MRA,因为 MRA 计入生产条款。 (实际上,MRA 被替换为 RHS 为空的非终结符。)所以 C$3

由于 MRA 实际上并没有设置值,$2 有点不确定,但0 不太可能。

野牛手册参考:

Using Mid-Rule Actions:

中间规则操作本身算作规则的组成部分之一。当同一规则后面有另一个动作时(通常最后还有另一个动作),这会有所不同:在计算出在$n 中使用哪个数字n 时,您必须计算这些动作以及符号。

Mid-Rule Action Translation:指出“中间规则动作实际上转化为常规规则和动作”,然后提供了一些产生的空规则示例(及其内部名称,有助于理解bison调试输出。)

【讨论】:

  • 嗯,我会尝试.. 我不知道有这样的考虑.. 所以,yacc 自动将 mra 转换为文献中称为标记的东西之一?我的意思是与 T-> B M C 相同,其中 M->empty 并具有关联的操作(我认为您称其为空 rhs)?
  • @LMG,是的,准确地说。
  • 我真的很高兴你帮我发现了这一点。+1 和正确的答案老兄!
  • 谢谢你。真的为我节省了一些时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多