我正在为PL/SQL编写一个简单的解析器和重写工具,我已经完成了解析器并获得了AST,但现在我遇到了两个问题:
示例SQL:select a,b from t where a=2
在解析了sql并获得ast之后,我想将sql更改为
select fun(a),b from t where a = fun1(2);
顺便说一句,我用ANTLR为C生成AST,
谢谢你的建议!
发布于 2012-07-31 20:01:46
请看我在how to regenerate source code from an AST上的回答。
工作比你想象的要多。
ANTLR以字符串模板的形式提供了一些帮助,但您可能会发现这些都是喜忧参半的:虽然它们可以生成代码文本,但它们将精确地生成模板中的内容,并且您可能希望根据其原始布局重新生成代码,而字符串模板的布局希望重写该布局。
发布于 2013-03-22 12:17:06
下面的代码将遍历AST并将所有AST节点打印到stderr。相同的树遍历器是可以替换树节点的树转换器的基础。
使用:(pANTLR3_BASE_TREE)(psr->adaptor->nilNode(psr->adaptor));分配新的树节点
删除带有:parentASTnode>删除子节点(parentASTnode,nodeIndex)的AST节点;deleteChild不释放删除的节点
将节点替换为:parentASTnode>replaceChildren(parentASTnode、nStartChildIndex、nStopChildIndex、newASTnode);不能在AST树级别的中间插入节点,只能替换节点或添加到父节点子列表的末尾
void printTree(pANTLR3_BASE_TREE t, int indent)
{
pANTLR3_BASE_TREE child = NULL;
int children = 0;
char * tokenText = NULL;
string ind = "";
int i = 0;
if ( t != NULL )
{
children = t->getChildCount(t);
for ( i = 0; i < indent; i++ )
ind += " ";
for ( i = 0; i < children; i++ )
{
child = (pANTLR3_BASE_TREE)(t->getChild(t, i));
tokenText = (char *)child->toString(child)->chars;
fprintf(stderr, "%s%s\n", ind.c_str(), tokenText);
if (tokenText == "<EOF>")
break;
printTree(child, indent+1);
}
}
}
// Run the parser
pANTLR3_BASE_TREE langAST = (psr->start_rule(psr)).tree;
// Print the AST
printTree(langAST, 0);
// Get the Parser Errors
int nErrors = psr->pParser->rec->state->errorCount;
https://stackoverflow.com/questions/11752166
复制相似问题