Skip to content

Commit f97c16f

Browse files
committed
add python ASTPrint example
1 parent c262c41 commit f97c16f

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

example/python/ASTPrint.gdl

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// script
2+
use coref::python::*
3+
4+
fn default_db() -> PythonDB {
5+
return PythonDB::load("coref_python_src.db")
6+
}
7+
8+
// 递归查找以a为起点的语法树边,b 和 c 组成一条有向边,b 为父节点,c 为子节点,index 为这条边在树中距离 root 的层级
9+
fn searchEdge(a: CombineElement, b: CombineElement, c: CombineElement, index: int) -> bool {
10+
if (a = b.getAnAncestorForIndex(index) || (b = a && index = 0)) {
11+
if (b = c.getParent()) {
12+
return true
13+
}
14+
}
15+
}
16+
17+
// 获取位置信息,如果该节点在 ast parser 中不存在位置信息,则会递归展示该节点的父节点的位置信息,
18+
// 例如 Comprehension,Arguments,Withitem, DocstringComment 等类型
19+
fn getLoc(p: CombineElement, line: int, col: int) -> bool {
20+
return line = p.getLocation().getStartLineNumber() &&
21+
col = p.getLocation().getStartColumnNumber()
22+
}
23+
24+
// 输出AST语法树的有向边,以及点的代码片段
25+
// 第一列是层数,从0开始
26+
// 第二列是当前边的父节点
27+
// 第三列是父节点的节点类型
28+
// 第四列是父节点的代码片段
29+
// 第五列是父节点起始行号
30+
// 第六列是父节点起始列号
31+
// 第七列是当前边的子节点
32+
// 第八列是子节点的节点类型
33+
// 第九列是子节点的代码片段
34+
// 第十列是子节点起始行号
35+
// 第十一列是子节点起始列号
36+
@output
37+
fn out(filePath: string,
38+
depth: int,
39+
parent: CombineElement,
40+
parentKind: string,
41+
parentContent: string,
42+
parentLine: int,
43+
parentColumn: int,
44+
child: CombineElement,
45+
childKind: string,
46+
childContent: string,
47+
childLine: int,
48+
childColumn: int) -> bool {
49+
for (a in File(default_db())) {
50+
if (filePath = a.getRelativePath() &&
51+
searchEdge(CombineElement(default_db()).find(a), parent, child, depth) &&
52+
childContent = child.print() && // 输出子节点的内容
53+
shortPrint(parent, parentContent) && // 优化输出父节点内容
54+
parentKind = parent.getType() &&
55+
childKind = child.getType() &&
56+
getLoc(parent, parentLine, parentColumn) &&
57+
getLoc(child, childLine, childColumn)) {
58+
return true
59+
}
60+
}
61+
}
62+
63+
// 找到长度在 5 行以上的Expression, 可以调整
64+
fn isLongExpression(s: CombineElement) -> bool {
65+
return Expression(default_db()).find(s).getSize().getNumberOfTotalLines() > 4
66+
}
67+
68+
// 优化输出父节点
69+
fn shortPrint(p: CombineElement, n: string) -> bool {
70+
if (isStatement(p)) {
71+
return n = p.getType()
72+
}
73+
if (!isStatement(p)) {
74+
if (isLongExpression(p)) {
75+
return n = p.getType()
76+
}
77+
if (!isLongExpression(p)) {
78+
return n = p.print()
79+
}
80+
}
81+
}
82+
83+
// 找到属于Statement的节点
84+
fn isStatement(s: CombineElement) -> bool {
85+
for (b in Statement(default_db())) {
86+
if (b.key_eq(s)) {
87+
return true
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)