如何获得带注释的语法树?

2024-06-25 23:18:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为几种语言创建一个文档生成器。为此,我需要一个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代码:

^{pr2}$

该输出:

│ │ │ │ └─ 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.

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


Tags: the代码infromimportchildtreeparser
1条回答
网友
1楼 · 发布于 2024-06-25 23:18:58

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

如果从规则^{cd2>}中删除^{cd1>}

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

然后^{cd2>}最终会在解析器中结束。但是,然后,您的每个解析器规则都需要包含允许它们的标记。

例如,使用^{cd4>}解析器规则:

^{pr2}$

由于这是JavaScript中的有效数组文字:

^{pr3}$

这意味着您需要使用^{{cd2>}标记丢弃所有解析器规则,如:

^{pr4}$

会变成一个大烂摊子。

编辑

从评论中:

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.

相关问题 更多 >