简体   繁体   English

Antlr4 有没有办法在带有监听器的节点上行走

[英]Antlr4 Is there a way to walk on a node with a listener

I am working with antlr4 to parse some inner language.我正在使用 antlr4 来解析一些内部语言。 The way I do it is the standard way of creating a stream of tokens, then creating a parse tree with set tokens.我这样做的方式是创建令牌的 stream 的标准方式,然后使用设置的令牌创建解析树。 And the last step is creating a tree.最后一步是创建一棵树。 Now that I have a tree I can use the walk command to walk over it.现在我有一棵树,我可以使用walk命令走过它。 The walk command and the parse tree being created are an extension of the BaseListener class. walk 命令和正在创建的解析树是BaseListener class 的扩展。 For my project I use many lookaheads, I mostly use the visitors as a sort of look ahead.对于我的项目,我使用了许多前瞻,我主要使用访问者作为一种前瞻。 A visitor function can be applied on a node from the parser tree.访问者 function 可以应用于解析器树中的节点。 (Assuming you implement a visitor class) I have tried creating a smaller listener class to act as my look ahead on a specific node. (假设您实现了一个访问者类)我尝试创建一个较小的侦听器 class 来充当我在特定节点上的前瞻。 However, I'm not managing to figure out if this is even possible.但是,我无法弄清楚这是否可能。 Or is there another / better / smarter way to create a look ahead?还是有另一种/更好/更智能的方式来创造未来?

To make the question seem shorter: Can a listener class be used on a node in the antlr4 parser tree-like visitor can?为了使问题看起来更短:可以在 antlr4 解析器树状访问者的节点上使用侦听器 class 吗?

There's no real reason to do anything fancy with a listener here.没有真正的理由在这里与听众做任何花哨的事情。 To handle your example of resolving the type of an expression, this can be done in a couple of steps.要处理解析表达式类型的示例,可以通过几个步骤来完成。 You'll need a listener that builds a symbol table (presumably a scoped symbol table so that each scope in your parse tree has a symbol table and references to “parent” scopes it might search to resolve the data types of any variables.).您将需要一个构建符号表的侦听器(可能是一个范围符号表,以便解析树中的每个 scope 都有一个符号表和对“父”范围的引用,它可能会搜索以解析任何变量的数据类型。)。 Depending upon your needs, you can build these scoped symbol tables in your listener, pushing and popping them on a stack as you enter/exit scopes, or you may do this is a separate listener attaching a reference to scope nodes to your parse tree.根据您的需要,您可以在侦听器中构建这些范围符号表,在您进入/退出范围时将它们推送和弹出堆栈,或者您可以这样做是一个单独的侦听器,将对 scope 节点的引用附加到您的分析树。 This symbol table will be required for type resolution, so if you can reference variables in your source prior to encountering the declaration, you'd need too pass your tree with a listener building and retaining the symbol table structure.类型解析将需要此符号表,因此如果您可以在遇到声明之前引用源中的变量,您还需要通过侦听器构建树并保留符号表结构。

With the symbol table structure available to your listener for resolving expression types.使用您的侦听器可用于解析表达式类型的符号表结构。 If you always use the exit* method overrides then all of the data types for any sub-expressions will have already been resolved.如果您总是使用exit*方法覆盖,那么任何子表达式的所有数据类型都将被解析。 With all of the sub-expression types, you can infer the type of the expression you're about to “exit”.使用所有子表达式类型,您可以推断出您将要“退出”的表达式的类型。 Evaluating the type of child expressions should cover all of the “lookahead” you need to resolve an expression's type.评估子表达式的类型应该涵盖解析表达式类型所需的所有“前瞻”。

There's really nothing about this approach that rules out a visitor either, it would just be up to you to visit each child, determining it's type, and then, at the end of the listener, resolve the expression type from the types of it's children.这种方法实际上也没有排除访问者,它只取决于您访问每个孩子,确定它的类型,然后在侦听器结束时,从它的孩子的类型中解析表达式类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM