Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么yacc或bison将$1转换为yyvsp[(1)-(1)].s?_C_Bison_Yacc - Fatal编程技术网

为什么yacc或bison将$1转换为yyvsp[(1)-(1)].s?

为什么yacc或bison将$1转换为yyvsp[(1)-(1)].s?,c,bison,yacc,C,Bison,Yacc,Yacc来源如下: element: IDENTIFIER { $$ = gst_element_factory_make ($1, NULL); if ($$ == NULL) { ADD_MISSING_ELEMENT (graph, $1); SET_ERROR (graph->error, GST

Yacc来源如下:

element:    IDENTIFIER                { $$ = gst_element_factory_make ($1, NULL);
                        if ($$ == NULL) {
                          ADD_MISSING_ELEMENT (graph, $1);
                          SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT, _("no element \"%s\""), $1);
                          /* if FATAL_ERRORS flag is set, we don't have to worry about backwards
                           * compatibility and can continue parsing and check for other missing
                           * elements */
                          if ((graph->flags & GST_PARSE_FLAG_FATAL_ERRORS) == 0) {
                            gst_parse_strfree ($1);
                            YYERROR;
                          }
                        }
                        gst_parse_strfree ($1);
                                              }
    |   element ASSIGNMENT        { gst_parse_element_set ($2, $1, graph);
                        $$ = $1;
它被翻译成如下代码:

 { (yyval.e) = gst_element_factory_make ((yyvsp[(1) - (1)].s), NULL);
                    if ((yyval.e) == NULL) {
                      ADD_MISSING_ELEMENT (graph, (yyvsp[(1) - (1)].s));
                      SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT, _("no element \"%s\""), (yyvsp[(1) - (1)].s));
                      /* if FATAL_ERRORS flag is set, we don't have to worry about backwards
                       * compatibility and can continue parsing and check for other missing
                       * elements */
                      if ((graph->flags & GST_PARSE_FLAG_FATAL_ERRORS) == 0) {
                        gst_parse_strfree ((yyvsp[(1) - (1)].s));
                        YYERROR;
                      }
                    }
                    gst_parse_strfree ((yyvsp[(1) - (1)].s));
                                          }
break;
其中一种翻译转换为:

gst_element_factory_make ($1, NULL)
致:

[(1)-(1)]
把我弄糊涂了。
为什么
[(1)-(1)]
句子代表了
$1
的价值?

正如乔纳森·莱夫勒(Jonathan Leffler)在一篇评论中所说,bison和yacc以一种便于代码生成的风格生成正确的代码,而不是针对人类读者

然而,各种堆栈的处理相当简单。Bison维护两个或三个堆栈:状态堆栈;值堆栈;以及可选的位置堆栈。这三个堆栈是独立的,因为否则就需要创建一个包含状态、值和(如有必要)位置的堆栈插槽结构

堆栈的大小始终相同,这意味着在值堆栈(以及位置堆栈)的开头有一个未使用的插槽。如果你参考LR解析算法的经典描述,比如在《龙之书》的“LR解析算法”一节——《我的版本》第4.7节——你会清楚地看到这一点;堆栈的状态比语法符号多一个,因此没有
X0

在这种情况下,值堆栈的顶部将精确地

V1 V2 … Vm
V1 V2…Vm
(其中
Vi
是符号
Xi
的语义值)。或者,用野牛的话来说:

$1$2…$m


这意味着,
$1
yyvsp[1-m]
$2
yyvsp[2-m]
,依此类推,在
yyvsp[m-m]
处的
$m
。这正是bison生成的代码所做的;它将
$i
表示为
yyvsp[(i)-(m)]
,其中
m
是右手边被缩短的长度(以语法符号表示)。

yyvsp
是指向数组的一部分的指针,该数组包含(指向)与
$1
$2
相对应的值,等。
$1
的值存储在
yyvsp[0]
中,可以将其写入
yyvsp[(1)-(1)]
,其中第一个
1
$1
的后缀,第二个是文本1。这是机器生成的代码,您不需要阅读它。如果你这样做,你必须接受它是(1)正确的,(2)方便程序生成而不是程序员阅读。而
.s
部分是因为你有一个联合类型,
$1
标识符
)的类型使得值存储在联合的
s
元素中。
s0 X1 s1 X2 s2 … Xm sm
A → X1 X2 … Xm
V1 V2 … Vm