Bison 野牛,@1和$1之间的差额

Bison 野牛,@1和$1之间的差额,bison,flex-lexer,Bison,Flex Lexer,我正在编写一个Pascal编译器,并且已经有了可用的语法。现在我想从语义分析开始,但实际上不理解它在bison中是如何工作的。不知何故,我通过尝试每一个选项编写了一段工作代码,我想知道@1和$1之间的区别是什么 uint_values_split_by_comma: UINT { pas::ic_label label = ctx->tab->new_label(); ctx->tab->add_label_

我正在编写一个Pascal编译器,并且已经有了可用的语法。现在我想从语义分析开始,但实际上不理解它在bison中是如何工作的。不知何故,我通过尝试每一个选项编写了一段工作代码,我想知道@1和$1之间的区别是什么

uint_values_split_by_comma:
        UINT {
            pas::ic_label label = ctx->tab->new_label();
            ctx->tab->add_label_entry(@1, $1, label);
        }
        | uint_values_split_by_comma COMMA UINT {}
;
也看到了野牛的文档,仍然没有得到它。

当写一个时,
$n
引用一个,而
@n
引用一个

以下是来自以下方面的示例:

$1
指左侧表达式的值,
$3
指右侧表达式的值

关于位置,在中,我们可以阅读:

与语义值一样,可以使用一组专用的构造在操作中到达位置。在上面的示例中,整个分组的位置是@$,而子表达式的位置是@1和@3

以下是语义位置用法的示例:

exp:
  …
| exp '/' exp
    {
      @$.first_column = @1.first_column;
      @$.first_line = @1.first_line;
      @$.last_column = @3.last_column;
      @$.last_line = @3.last_line;
      if ($3)
        $$ = $1 / $3;
      else
        {
          $$ = 1;
          fprintf (stderr, "%d.%d-%d.%d: division by zero",
                   @3.first_line, @3.first_column,
                   @3.last_line, @3.last_column);
        }
    }

在此示例中,使用位置可以打印带有错误精确位置的详细错误消息。

$1
是第一个符号的值
@1
是第一个符号(符号开始和结束的行和列)的位置。请参阅。谷歌十秒钟。
exp:
  …
| exp '/' exp
    {
      @$.first_column = @1.first_column;
      @$.first_line = @1.first_line;
      @$.last_column = @3.last_column;
      @$.last_line = @3.last_line;
      if ($3)
        $$ = $1 / $3;
      else
        {
          $$ = 1;
          fprintf (stderr, "%d.%d-%d.%d: division by zero",
                   @3.first_line, @3.first_column,
                   @3.last_line, @3.last_column);
        }
    }