可视化使用ANTLR创建的AST(在.Net环境中)

Ben*_*zun 10 c# antlr antlrworks

对于一个宠物项目,我开始摆弄ANTLR.在完成一些教程后,我现在正在尝试为我自己的语言创建语法并生成AST.

现在我主要在ANTLRWorks中乱搞,但现在我已经验证了解析树看起来很好我想(迭代地,因为我还在学习并且仍然需要对最终结构做出一些决定)树)创建AST.似乎antlrworks不会将其可视化(或者至少不使用"Interpreter"功能,Debug不能在我的任何机器上运行).

底线:是以手动方式可视化AST的唯一方法,遍历/显示它还是以字符串表示形式将树打印到控制台?

我正在寻找的是从输入,语法 - >视觉AST表示到ANTLRWorks的"解释器"功能的简单方法.有任何想法吗?

Bar*_*ers 17

正确的是,解释器只显示解析过程中使用的规则,并忽略任何AST重写规则.

你可以做的是StringTemplate用来创建Graphviz DOT文件.创建这样的DOT文件后,您可以使用某些第三方查看器来显示此树(图形).

这是Java的快速演示(我知道很少C#,对不起).

采用产生AST的以下(过于简单化)表达式语法:

grammar ASTDemo;

options { 
  output=AST; 
}

tokens {
  ROOT;
  EXPRESSION;
}

parse
  :  (expression ';')+ -> ^(ROOT expression+) // omit the semi-colon
  ;

expression
  :  addExp -> ^(EXPRESSION addExp)
  ;

addExp
  :  multExp
     ( '+'^ multExp
     | '-'^ multExp
     )*
  ;

multExp
  :  powerExp
     ( '*'^ powerExp
     | '/'^ powerExp
     )*
  ;

powerExp
  :  atom ('^'^ atom)*
  ;

atom
  :  Number
  |  '(' expression ')' -> expression // omit the parenthesis
  ;

Number
  :  Digit+ ('.' Digit+)?
  ;

fragment
Digit
  :  '0'..'9'
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;
Run Code Online (Sandbox Code Playgroud)

首先让ANTLR从中生成词法分析器和解析器文件:

java -cp antlr-3.2.jar org.antlr.Tool ASTDemo.g 
Run Code Online (Sandbox Code Playgroud)

然后创建一个小测试工具来解析表达式"12 * (5 - 6); 2^3^(4 + 1);"并输出一个DOT文件:

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class MainASTDemo {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("12 * (5 - 6); 2^3^(4 + 1);");
        ASTDemoLexer lexer = new ASTDemoLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ASTDemoParser parser = new ASTDemoParser(tokens);
        ASTDemoParser.parse_return returnValue = parser.parse();
        CommonTree tree = (CommonTree)returnValue.getTree();
        DOTTreeGenerator gen = new DOTTreeGenerator();
        StringTemplate st = gen.toDOT(tree);
        System.out.println(st);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译所有.java文件:

// *nix & MacOS
javac -cp .:antlr-3.2.jar *.java

// Windows
javac -cp .;antlr-3.2.jar *.java
Run Code Online (Sandbox Code Playgroud)

然后运行主类并将其输出传递给名为的文件ast-tree.dot:

// *nix & MacOS
java -cp .:antlr-3.2.jar MainASTDemo > ast-tree.dot

// Windows
java -cp .;antlr-3.2.jar MainASTDemo > ast-tree.dot
Run Code Online (Sandbox Code Playgroud)

该文件ast-tree.dot现在包含:

digraph {

    ordering=out;
    ranksep=.4;
    bgcolor="lightgrey"; node [shape=box, fixedsize=false, fontsize=12, fontname="Helvetica-bold", fontcolor="blue"
        width=.25, height=.25, color="black", fillcolor="white", style="filled, solid, bold"];
    edge [arrowsize=.5, color="black", style="bold"]

  n0 [label="ROOT"];
  n1 [label="EXPRESSION"];
  n1 [label="EXPRESSION"];
  n2 [label="*"];
  n2 [label="*"];
  n3 [label="12"];
  n4 [label="EXPRESSION"];
  n4 [label="EXPRESSION"];
  n5 [label="-"];
  n5 [label="-"];
  n6 [label="5"];
  n7 [label="6"];
  n8 [label="EXPRESSION"];
  n8 [label="EXPRESSION"];
  n9 [label="^"];
  n9 [label="^"];
  n10 [label="^"];
  n10 [label="^"];
  n11 [label="2"];
  n12 [label="3"];
  n13 [label="EXPRESSION"];
  n13 [label="EXPRESSION"];
  n14 [label="+"];
  n14 [label="+"];
  n15 [label="4"];
  n16 [label="1"];

  n0 -> n1 // "ROOT" -> "EXPRESSION"
  n1 -> n2 // "EXPRESSION" -> "*"
  n2 -> n3 // "*" -> "12"
  n2 -> n4 // "*" -> "EXPRESSION"
  n4 -> n5 // "EXPRESSION" -> "-"
  n5 -> n6 // "-" -> "5"
  n5 -> n7 // "-" -> "6"
  n0 -> n8 // "ROOT" -> "EXPRESSION"
  n8 -> n9 // "EXPRESSION" -> "^"
  n9 -> n10 // "^" -> "^"
  n10 -> n11 // "^" -> "2"
  n10 -> n12 // "^" -> "3"
  n9 -> n13 // "^" -> "EXPRESSION"
  n13 -> n14 // "EXPRESSION" -> "+"
  n14 -> n15 // "+" -> "4"
  n14 -> n16 // "+" -> "1"

}
Run Code Online (Sandbox Code Playgroud)

可以与众多观众中的一个观看.甚至还有在线观众.以此为例:http://graph.gafol.net/

喂食内容时ast-tree.dot,会产生以下图像:

alt text http://img19.imageshack.us/img19/4836/expression.png

  • 哇,谢谢你的详细回答。为此+1(似乎做我想做的事)。我会在白天尝试一下,然后可能会接受。遗憾的是,似乎不存在更快的方式(即没有对涉及的每个更改进行编译,针对示例输入/流的“实时”预览)。 (2认同)
  • 不客气@Benjamin。如果您使用 Eclipse,您可能想尝试插件“ANTLR IDE”:http://antlrv3ide.sourceforge.net/ 我相信它可以选择动态创建 AST 图像。但我对此没有个人经验。 (2认同)