在here中,_loc变量作为传递给mk_sequence函数的参数出现在match ... with表达式的语法规则中。
| "match"; e = sequence; "with"; a = match_case ->
<:expr< match $mksequence' _loc e$ with [ $a$ ] >>但mksequence的function body中并没有使用它。
value mksequence _loc =
fun
[ <:expr< $_$; $_$ >> | <:expr< $anti:_$ >> as e -> <:expr< do { $e$ } >>
| e -> e ]
;_loc变量也会出现在语法规则中的other places中。
在camlp4代码生成tutorial中,_loc代表位置。但我不太明白那里的解释。有人能给我解释一下传递一个未使用的_loc变量的目的吗?
发布于 2013-03-19 12:08:12
粗略地说,_loc就是“当前的位置”。通常,在解析规则中,匹配的AST的位置是必选的。
_loc是一个普通的OCaml变量,实际上在CamlP4代码中无处不在,但P4的语法糖很好地隐藏了它们的大部分存在。你可以通过P4对你的P4模块进行预处理来了解'_loc‘是如何在P4中被引入和使用的。例如,
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的函数。它绑定到与以[ Gram.Skeyword "match"...开头的规范匹配的AST的位置。然后在扩展为Ast.ExMat (_loc, ...)的<:expr< match ... >>中使用_loc,在mksequence' _loc e中第二次使用它,后者是手工编写的。
<:expr<...>>和p4中的其他<:XXX<...>>构造使用这个_loc变量,这样您就可以创建自己的_loc,而无需过多考虑它的位置。它自动使用_loc,“当前解析的位置”。如果你不想为<:expr<...>>使用_loc,你可以使用<:expr@myloc<...>>来显式地指定你的<:expr<...>>的位置。
有时您希望在解析规则之外使用<:expr<...>>,在这种情况下,_loc是未绑定的。您必须使用<:expr@myloc<...>>,或者在通过其他方式绑定_loc之后使用<:expr<...>。通常是let _loc = Loc.ghost,意思是“没有地方”。
P4非常复杂,而且网络上没有太多可用的文档。有时,通过P4扩展P4代码有助于理解它是如何工作的。
https://stackoverflow.com/questions/15489863
复制相似问题