作为传递给_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
变量的目的吗?
答案 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
表示“不在哪里”。