1

_loc变量出现在表达式的语法规则中,match ... with作为传递给mk_sequence函数的参数。

    | "match"; e = sequence; "with"; a = match_case ->
        <:expr< match $mksequence' _loc e$ with [ $a$ ] >>

但它没有用在mksequence's函数体中。

  value mksequence _loc =
    fun
    [ <:expr< $_$; $_$ >> | <:expr< $anti:_$ >> as e -> <:expr< do { $e$ } >>
    | e -> e ]
  ;

_loc变量也出现在语法规则的其他 地方。

在camlp4代码生成教程中,它说_loc代表位置。但我不太明白那里的解释。有人可以向我解释传递未使用_loc变量的目的吗?

4

1 回答 1

3

粗略地说,_loc就是“当前位置”。通常它是在解析规则中匹配的 AST 的位置。

_loc是一个普通的 OCaml 变量,实际上在 CamlP4 代码中无处不在,但是 P4 的语法糖很好地隐藏了它们的大部分存在。您可以通过 P4 预处理您的 P4 模块来了解如何在 P4 中引入和使用“_loc”。例如,

EXTEND Gram
  my_syntax:
    [ [ "match"; e = sequence; "with"; a = match_case ->
          <:expr< match $mksequence' _loc e$ with [ $a$ ] >>
    ] ];
END;

如果你对上面的内容进行预处理camlp4rf,你就会明白它的真正含义:

Gram.extend (my_syntax : 'my_syntax Gram.Entry.t)
  ((fun () ->
      (None,
       [ (None, None,
          [ ([ Gram.Skeyword "match";
               Gram.Snterm
                 (Gram.Entry.obj (sequence : 'sequence Gram.Entry.t));
               Gram.Skeyword "with";
               Gram.Snterm
                 (Gram.Entry.obj (match_case : 'match_case Gram.Entry.t)) ],
             (Gram.Action.mk
                (fun (a : 'match_case) _ (e : 'sequence) _
                   (_loc : Gram.Loc.t) ->
                   (Ast.ExMat (_loc, (mksequence' _loc e), a) : 'my_syntax)))) ]) ]))
     ())

这有点难,但你可以找到Gram.Action.mk一个引入参数的函数_loc。它绑定到与以 . 开头的规范匹配的 AST 的位置[ Gram.Skeyword "match"...。然后_loc使用 at<:expr< match ... >>扩展为Ast.ExMat (_loc, ...),除了第二次使用 at mksequence' _loc e,它是手写的。

<:expr<...>>p4中的其他<:XXX<...>>构造使用此_loc变量,因此您可以创建 AST 而无需过多考虑它的位置。它自动使用_loc“当前解析的位置”。如果你不想使用_locfor<:expr<...>>你可以使用<:expr@myloc<...>>明确指定你的 AST 的位置。

有时您想<:expr<...>>在解析规则之外使用,在这种情况下_loc是未绑定的。您必须使用<:expr@myloc<...>>,或在被其他东西<:expr<...>绑定后使用。_loc通常,let _loc = Loc.ghost这意味着“没有地方”。

P4 非常复杂,网上没有太多可用的文档。有时,通过 P4 扩展您的 P4 代码有助于理解它是如何工作的。

于 2013-03-19T04:08:12.093 回答