粗略地说,_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"...
。然后在<:expr< match ... >>
处使用_loc
,除了其在mksequence' _loc e
处手动写入的第二用途之外,其被扩展为Ast.ExMat (_loc, ...)
。
<:expr<...>>
和其他<:XXX<...>>
p4中的结构使用这个_loc
变量,以便您可以创建您的AST,而不必考虑它的位置。它会自动使用_loc
“当前解析的位置”。如果您不想为<:expr<...>>
使用_loc
,则可以使用<:[email protected]<...>>
明确指定AST的位置。
有时您想在解析规则之外使用<:expr<...>>
,在这种情况下_loc
是未绑定的。您必须使用<:[email protected]<...>>
或使用<:expr<...>
以其他方式绑定_loc
之后。通常,let _loc = Loc.ghost
这意味着“不在哪里”。
P4是非常复杂的,网络上没有太多可用的文档。有时用P4扩展你的P4代码有助于理解它的工作原理。
谢谢! “有时候用P4扩展P4代码有助于理解它的工作原理。” 如何用P4扩展我的camlp4代码? – 2013-03-19 06:57:37
就像我在答案中写的一样。camlp4rf,如果您使用修订的语法(并且您在问题中使用了修订的语法)。 camlp4of 为原始语法。 –
camlspotter
2013-03-20 17:40:28