所以我在玩lpeg来代替boost Spirit语法,我必须说boost::spirit比lpeg优雅自然得多。然而,由于当前 C++ 编译器技术的限制和 C++ 中的 TMP 问题,它是一个婊子。在这种情况下,类型机制是你的敌人而不是你的朋友。另一方面,Lpeg 虽然丑陋和基本导致更高的生产力。
无论如何,我离题了,我的 lpeg 语法的一部分如下所示:
function get_namespace_parser()
local P, R, S, C, V =
lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.V
namespace_parser =
lpeg.P{
"NAMESPACE";
NAMESPACE = V("WS") * P("namespace") * V("SPACE_WS") * V("NAMESPACE_IDENTIFIER")
* V("WS") * V("NAMESPACE_BODY") * V("WS"),
NAMESPACE_IDENTIFIER = V("IDENTIFIER") / print_string ,
NAMESPACE_BODY = "{" * V("WS") *
V("ENTRIES")^0 * V("WS") * "}",
WS = S(" \t\n")^0,
SPACE_WS = P(" ") * V("WS")
}
return namespace_parser
end
此语法(虽然不完整)与以下内容匹配namespace foo {}
。我想实现以下语义(这是使用 boost spirit 时的常见用例)。
- 为命名空间规则创建一个局部变量。
namespace IDENTIFIER {
当已匹配时,将命名空间数据结构添加到此局部变量。- 将新创建的命名空间数据结构传递给
NAMESPACE_BODY
AST,以进一步构建 AST... 以此类推。
我确信这个用例是可以实现的。没有例子表明它。我对语言或库的了解不足以弄清楚如何去做。有人可以显示它的语法。
编辑:在尝试了几天与 lpeg 共舞并开始踩脚之后,我决定回归精神 :D 很明显 lpeg 是用 lua 函数编织的,而且这种编织是非常自由的-form(而精神有明确的非常有据可查的语义)。我只是还没有正确的 lua 心智模型。