Parsing 递归地使用Antlr4解析器和侦听器

Parsing 递归地使用Antlr4解析器和侦听器,parsing,recursion,antlr,antlr4,context-free-grammar,Parsing,Recursion,Antlr,Antlr4,Context Free Grammar,我正在做一个项目,解析类似布尔的DSL,并将其转换为特定的JSON格式。我已经构建了一个通用的类层次结构来完成这个任务,但是我不确定从哪里开始将解析树转换成我想要的数据结构 这是我的语法: grammar filter; filter: category EOF; category : LPAREN category RPAREN # ParenCat | category AND category # CatAndBlock | label COLON expres

我正在做一个项目,解析类似布尔的DSL,并将其转换为特定的JSON格式。我已经构建了一个通用的类层次结构来完成这个任务,但是我不确定从哪里开始将解析树转换成我想要的数据结构

这是我的语法:

grammar filter;

filter: category EOF;

category
    : LPAREN category RPAREN # ParenCat
    | category AND category # CatAndBlock
    | label COLON expression # CategoryBlock
    ;

expression
    : LPAREN expression RPAREN  # ParenExp
    | NOT expression            # NotBlock
    | expression AND expression  # AndBlock
    | expression OR expression   # OrBlock
    | atom # AtomExp
    ;

label
    : ALPHANUM
    ;

atom 
    : ALPHANUM
    ;
以下是输入字符串的示例:

(第1类:((1或2)和(3)))和第2类:(4)

使用以下解析树:

下面是我希望实现的类层次结构的草图(每个类都有自己的“write”方法):


既然您提到您已经回顾了Listener模式,那么我建议您:

  • 创建一个侦听器并将其连接到TreeWalker
  • 侦听器支持对“回车”(沿树向下)和“退出”(沿树向上)事件的重写。为每个可用的“退出”事件创建一个简单的硬编码覆盖
  • 运行应用程序。您将看到深度优先遍历和递归正在工作
  • 然后,更新“退出”事件覆盖以添加到链表结构中,或者基于堆栈的结构也适用于展开递归
  • 在这两种情况下,当您完成时,您将拥有与您提议的结构非常相似的内容

  • 使用Listener和Exit事件,递归和遍历将为您解决。您会发现它非常有用。

    您能详细说明一下您到底想做什么吗?您已经给出了一个解析树示例,因此可以尝试用文字或伪代码描述您希望Listener做什么……基本上,我想转换I使用解析后的输出将数据输入到类层次结构中。可能只是指定侦听器有点模糊。我在文章末尾做了一些详细说明。如果仍然太模糊,请告诉我。
    CategoryContainer: LinkedList<Category>
        Category: LinkedList<ItemBlock> list, String categoryName #CategoryBlock
            ItemBlock: LinkedList<ItemBlock> list, String type
                AndBlock extends ItemBlock
                OrBlock extends ItemBlock
                NotBlock extends ItemBlock
                AtomBlock extends ItemBlock: list = null, String value = "atomValue"
    
    CategoryContainer: 
    [
        Category: categoryName="cat1", # CategoryBlock Listener
        [ 
            AndBlock: [ AtomBlock: value="4", AtomBlock: value="5" ] # AndBlock Listener
        ],
        Category: categoryName="cat2", # CategoryBlock Listener
        [
            AtomBlock: value="4" # AtomBlock Listener
        ]
    ]