在camlp4中定义语法规则时_loc变量的目的是什么?

时间:2013-03-19 01:15:11

标签: ocaml camlp4

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

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

但它未在mksequence的{​​{3}}中使用。

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

_loc变量也出现在语法规则的function body other中。

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

1 个答案:

答案 0 :(得分: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使用了<:expr< match ... >>,除了在Ast.ExMat (_loc, ...)的第二次使用之外,它被扩展为mksequence' _loc e,这是手工编写的。

<:expr<...>>和p4中的其他<:XXX<...>>构造使用此_loc变量,这样您就可以创建AST而不必考虑它的位置。它会自动使用_loc,“当前解析的位置”。如果您不想对_loc使用<:expr<...>>,可以使用<:expr@myloc<...>>明确指定AST的位置。

有时您希望在解析规则之外使用<:expr<...>>,在这种情况下_loc是未绑定的。您必须使用<:expr@myloc<...>>,或在使用其他内容绑定<:expr<...>后使用_loc。通常,let _loc = Loc.ghost表示“不在哪里”。

P4非常复杂,网络上没有太多的文件。有时通过P4扩展P4代码有助于理解它的工作原理。

相关问题