|  | 
|  | 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