gpt4 book ai didi

python - 如何获取带注释的语法树?

转载 作者:行者123 更新时间:2023-11-30 22:30:12 24 4
gpt4 key购买 nike

我正在尝试为多种语言创建一个文档生成器。为此,我需要一个 AST,以便知道,例如,这个注释是针对一个类的,而这个注释是针对此类的方法的。

我开始编写这个简单的 Python 代码,它通过递归查看来显示树:

import sys
import antlr4
from ECMAScriptLexer import ECMAScriptLexer
from ECMAScriptParser import ECMAScriptParser

def handleTree(tree, lvl=0):
for child in tree.getChildren():
if isinstance(child, antlr4.tree.Tree.TerminalNode):
print(lvl*'│ ' + '└─', child)
else:
handleTree(child, lvl+1)

input = antlr4.FileStream(sys.argv[1])
lexer = ECMAScriptLexer(input)
stream = antlr4.CommonTokenStream(lexer)
parser = ECMAScriptParser(stream)
tree = parser.program()
handleTree(tree)

并尝试使用 antlr EcmaScript grammar 解析这段 Javascript 代码。 :

var i = 52; // inline comment

function foo() {
/** The foo documentation */
console.log('hey');
}

输出:

│ │ │ │ └─ var
│ │ │ │ │ │ └─ i
│ │ │ │ │ │ │ └─ =
│ │ │ │ │ │ │ │ │ │ └─ 52
│ │ │ │ │ └─ ;
│ │ │ └─ function
│ │ │ └─ foo
│ │ │ └─ (
│ │ │ └─ )
│ │ │ └─ {
│ │ │ │ │ │ │ │ │ │ │ │ └─ console
│ │ │ │ │ │ │ │ │ │ │ └─ .
│ │ │ │ │ │ │ │ │ │ │ │ └─ log
│ │ │ │ │ │ │ │ │ │ │ └─ (
│ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 'hey'
│ │ │ │ │ │ │ │ │ │ │ └─ )
│ │ │ │ │ │ │ │ │ └─ ;
│ │ │ └─ }
└─ <EOF>

所有注释都被忽略,可能是因为 channel(HIDDEN) 的存在 in the grammar .

经过一番谷歌搜索后,我发现 this有了这个答案:

Unless you have a very compelling reason to put the comment inside the parser (which I'd like to hear), you should put it in the lexer.

那么,为什么注释不应包含在解析器中以及如何获取包含注释的树?

最佳答案

So, why comments should not be included in the parser and how to get a tree including comments?

如果您从规则MultiLineComment中删除->channel(HIDDEN)

MultiLineComment
: '/*' .*? '*/' -> channel(HIDDEN)
;

那么MultiLineComment将最终出现在解析器中。但是,每个解析器规则都需要在允许的地方包含这些标记。

例如,采用arrayLiteral解析器规则:

/// ArrayLiteral :
/// [ Elision? ]
/// [ ElementList ]
/// [ ElementList , Elision? ]
arrayLiteral
: '[' elementList? ','? elision? ']'
;

因为这是 JavaScript 中有效的数组文字:

[/* ... */ 1, 2 /* ... */ , 3 /* ... */ /* ... */]

这意味着您需要使用 MultiLineComment 标记来丢弃所有解析器规则,如下所示:

/// ArrayLiteral :
/// [ Elision? ]
/// [ ElementList ]
/// [ ElementList , Elision? ]
arrayLiteral
: '[' MultiLineComment* elementList? MultiLineComment* ','? MultiLineComment* elision? MultiLineComment* ']'
;

这会变得一团糟。

编辑

来自评论:

So it's not possible to generate a tree including comments with antlr? Is there some hacks or other libraries to do this?

格罗森伯格的回答:

Antlr provides a convenience method for this task: BufferedTokenStream#getHiddenTokensToLeft. In walking the parse tree, access the stream to obtain the node associated comment, if any. Use BufferedTokenStream#getHiddenTokensToRight to get any trailing comment.

关于python - 如何获取带注释的语法树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46139628/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com