我有一个生成的语法,它做两件事:
这两个函数是分开的,让我们将它们称为These ()和These()。
validate()函数从字符串输入构建树,同时确保它满足BNF对语言的要求。values ()函数将值插入到该树中,以获得结果(通常为true或false)。
代码当前所做的是每次在输入上运行input (),只为了生成用于计算()的树。有些输入需要60秒来检查。我想要做的是序列化validate()的结果(假设它符合语法要求),将序列化后的表单存储在后端数据库中,然后将其从数据库中加载,作为validate()的一部分。
我注意到可以在解析树上执行方法toStringTree(),并检索LISP样式树。但是,我能否将LISP样式树还原为ANTLR解析树?如果没有,是否有人推荐另一种方法来序列化和存储生成的解析树?
谢谢你的帮助。
杰森
发布于 2014-03-21 14:58:43
ANTLR 4的ParseRuleContext数据结构(生成的解析器用于表示解析树中语法规则的ParseTree的具体实现)在默认情况下是不可序列化的。打开第233期上的项目问题跟踪器涵盖功能请求。但是,根据我使用ANTLR进行解析的许多应用程序的经验,从长远来看,我不相信序列化解析树是有用的。对于序列化解析树的每个问题,一个更好的解决方案已经存在。
另一个选项是将最后一个已知的有效文件的散列存储在数据库中。在使用解析器创建解析树之后,如果输入文件具有与上次验证相同的散列,则可以跳过验证步骤。这利用了反two 4的两个方面:
如果您需要的性能超出了所获得的性能,那么解析树并不是您应该使用的数据结构。StringTemplate 4比StringTemplate 3具有巨大的性能优势,主要是因为解释器从使用AST(相当于此推理的解析树)转换为线性字节码表示/解释器。由于性能原因,ST4的AST永远不需要序列化,因为字节码将被序列化。实际上,C#端口StringTemplate 4正是提供了这个特性。
发布于 2014-04-10 16:43:20
如果语法的输入数据是由几个独立的块组成的,您可以尝试分别存储每个块的字符串,并使用ThreadPool为每个块独立运行解析过程。
例如,假设输入数据是一组方法声明:
int add(int a, int b) {
return a+b;
}
int mul(int a, int b) {
return a*b;
}
...语法是这样的:
methodList : methodDeclaration methodList
|
;
methodDeclaration : // your method declaration rules...解析器的第一次运行只是收集每个方法文本并存储它。解析器以methodList规则启动进程。
void visitMethodList(MethodListContext ctx) {
if(ctx.methodDeclaration() != null) {
String methodStr = formatParseTree(ctx.methodDeclaration(), " ");
// store methodStr for later parsing
}
// visit next method list item, if any
if(ctx.methodList() != null) {
visit(ctx.methodList());
}
}第二次运行启动每个方法声明的解析(例如,在一个单独的线程中)。为此,解析器从methodDeclaration规则开始。
void visitMethodDeclaration(MethodDeclarationContext ctx) {
// parse the method block
}如果直接调用methodDeclaration规则的ctx.methodDeclaration().getText()将合并所有子节点AntLR文档的文本,则会对其进行格式化,这可能使其无法再次进行解析。如果空白是语法中的标记分隔符,那么在标记之间添加一个空格不应该更改解析树。
String formatParseTree(ParseTree tree, String separator) {
StringBuilder builder = new StringBuilder();
for(int i = 0; i < tree.getChildCount(); i ++) {
ParseTree child = tree.getChild(i);
if(child instanceof TerminalNode) {
builder.append(child.getText());
builder.append(separator);
} else if(child instanceof RuleContext) {
builder.append(formatParseTree(child, separator));
}
}
return builder.toString();
}https://stackoverflow.com/questions/22562061
复制相似问题