将 ANTLR 解析树转换为 JSON [英] Convert ANTLR parse tree to JSON

查看:157
本文介绍了将 ANTLR 解析树转换为 JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有效的语法并且已经实现了一个监听器(在 Java 中).我可以在控制台中用缩进显示解析树,但是我想将它导出为 JSON 结构,以便它可以在任何通用查看器中使用.

I have a working grammar and have implemented a listener (in Java). I can display the parse tree in the console with indentation however what I would like is to export it to a JSON structure so that it can be used in any generic viewer.

是否有已经制作的方法可以做到这一点,还是我必须以某种方式完全从头开始创建 json 文件?

Is there an already made method that can do this or will I have to create the json file absolutely from scratch somehow?

谢谢!

PS:我还设法通过 TreeView 类在 Swing 中显示...

PS: I also managed to display in Swing via the TreeView class...

推荐答案

是否有已经制作的方法可以做到这一点,还是我必须以某种方式完全从头开始创建 json 文件?

Is there an already made method that can do this or will I have to create the json file absolutely from scratch somehow?

正如评论中已经提到的:不,在ANTLR的核心API中没有这样的方法.你将不得不推出自己的.

As already mentioned in the comments: no, there is no such method in the core API of ANTLR. You will have to roll your own.

我有一个用于调试的实用方法,可以将 ANTLR ParseTree 传输到 java.util.Map 中,该方法可以轻松转换为 JSON 对象.我很高兴在这里分享.

I have a utility method for debugging purposes that transfers an ANTLR ParseTree into a java.util.Map which can easily be transformed into a JSON object. I'm happy to share it here.

给定以下语法:

grammar Expression;

parse
 : expr EOF
 ;

expr
 : '(' expr ')'                          #nestedExpr
 | '-' expr                              #unartyMinusExpr
 | expr ( '*' | '/' | '%' ) expr         #multExpr
 | expr ( '+' | '-' ) expr               #addExpr
 | expr ( '>' | '>=' | '<' | '<=' ) expr #compareExpr
 | expr ( '=' | '!=' ) expr              #eqExpr
 | expr AND expr                         #andExpr
 | expr OR expr                          #orExpr
 | function_call                         #functionCallExpr
 | ID                                    #idExpr
 | NUMBER                                #numberExpr
 | STRING                                #stringExpr
 ;

function_call
 : ID args
 ;

args
 : '(' ( expr ( ',' expr )* )? ')'
 ;

ADD    : '+';
MINUS  : '-';
MULT   : '*';
DIV    : '/';
MOD    : '%';
OPAR   : '(';
CPAR   : ')';
LTE    : '<=';
LT     : '<';
GTE    : '>=';
GT     : '>';
EQ     : '=';
NEQ    : '!=';
AND    : 'and';
OR     : 'or';
NUMBER : ( [0-9]* '.' )? [0-9]+;
ID     : [a-zA-Z_] [a-zA-Z_0-9]*;
STRING : '"' ~["\r\n]* '"';
NL     : '\r'? '\n' | '\r';
SPACE  : [ \t] -> skip;

和下面的 Main 类,它处理输入 (1 + 2) * 3:

and the following Main class, which handles the input (1 + 2) * 3:

public class Examples {

  private static final Gson PRETTY_PRINT_GSON = new GsonBuilder().setPrettyPrinting().create();
  private static final Gson GSON = new Gson();

  public static String toJson(ParseTree tree) {
    return toJson(tree, true);
  }

  public static String toJson(ParseTree tree, boolean prettyPrint) {
    return prettyPrint ? PRETTY_PRINT_GSON.toJson(toMap(tree)) : GSON.toJson(toMap(tree));
  }

  public static Map<String, Object> toMap(ParseTree tree) {
    Map<String, Object> map = new LinkedHashMap<>();
    traverse(tree, map);
    return map;
  }

  public static void traverse(ParseTree tree, Map<String, Object> map) {

    if (tree instanceof TerminalNodeImpl) {
      Token token = ((TerminalNodeImpl) tree).getSymbol();
      map.put("type", token.getType());
      map.put("text", token.getText());
    }
    else {
      List<Map<String, Object>> children = new ArrayList<>();
      String name = tree.getClass().getSimpleName().replaceAll("Context$", "");
      map.put(Character.toLowerCase(name.charAt(0)) + name.substring(1), children);

      for (int i = 0; i < tree.getChildCount(); i++) {
        Map<String, Object> nested = new LinkedHashMap<>();
        children.add(nested);
        traverse(tree.getChild(i), nested);
      }
    }
  }

  public static void main(String[] args) {
    String source = "(1 + 2) * 3";
    ExpressionLexer lexer = new ExpressionLexer(CharStreams.fromString(source));
    ExpressionParser parser = new ExpressionParser(new CommonTokenStream(lexer));
    System.out.println(toJson(parser.parse()));
  }
}

您将看到以下内容打印到您的控制台:

you will see the following printed to your console:

{
  "parse": [
    {
      "multExpr": [
        {
          "nestedExpr": [
            {
              "type": 7,
              "text": "("
            },
            {
              "addExpr": [
                {
                  "numberExpr": [
                    {
                      "type": 17,
                      "text": "1"
                    }
                  ]
                },
                {
                  "type": 2,
                  "text": "+"
                },
                {
                  "numberExpr": [
                    {
                      "type": 17,
                      "text": "2"
                    }
                  ]
                }
              ]
            },
            {
              "type": 8,
              "text": ")"
            }
          ]
        },
        {
          "type": 4,
          "text": "*"
        },
        {
          "numberExpr": [
            {
              "type": 17,
              "text": "3"
            }
          ]
        }
      ]
    },
    {
      "type": -1,
      "text": "\u003cEOF\u003e"
    }
  ]
}

这篇关于将 ANTLR 解析树转换为 JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆