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

时间:2017-08-03 04:31:45

标签: 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 expression # CategoryBlock
    ;

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

label
    : ALPHANUM
    ;

atom 
    : ALPHANUM
    ;

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

  

(cat1 :(((1 OR 2)AND(3))))和cat2:(4)

使用以下解析树:

enter image description here

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

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"

我一直在为听众寻找一些教程,并对发生的事情有一个非常明确的想法。但是,我似乎无法找到有关像我正在使用的递归问题的大量信息。你对我如何开始有任何提示吗?

编辑:澄清我希望实现的目标,

输入字符串示例:

  

cat1:(4 AND 5)和cat2:(4)

我想以递归方式生成以下类(使用括号列表表示法表示相应的链接列表):

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

1 个答案:

答案 0 :(得分:2)

既然你提到你已经审阅了听众模式,那么我建议:

  1. 创建一个侦听器并将其连接到TreeWalker
  2. 监听器支持覆盖&#34;输入&#34; (从树上下来)和#34;退出&#34; (回到树上)事件。为每个&#34; Exit事件创建一个简单的硬编码覆盖。
  3. 运行该应用程序。您将看到工作中的深度优先遍历和递归。
  4. 从那里,更新您的&#34;退出&#34;事件覆盖以添加到链表结构,或者基于堆栈的结构也适用于展开递归。
  5. 在任何一种情况下,当您完成后,您将拥有与您提议的结构非常相似的内容。
  6. 使用Listener和Exit事件,将为您处理递归和遍历。你会发现它非常有用。