代码之家  ›  专栏  ›  技术社区  ›  Benjamin Podszun

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

  •  10
  • Benjamin Podszun  · 技术社区  · 16 年前

    现在我主要在ANTLRWorks中混日子,但是现在我已经验证了解析树似乎很好了,我想(迭代地,因为我还在学习,仍然需要对树的最终结构做一些决定)创建AST。似乎antlrworks不会将其可视化(或者至少没有使用“解释器”特性,Debug在我的任何机器上都不起作用)。

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

    我要找的是一种简单的输入法,语法->视觉再现是ANTLRWorks的“解释器”特征。有什么想法吗?

    2 回复  |  直到 16 年前
        1
  •  17
  •   Stephan    6 年前

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

    你能做的就是使用 StringTemplate 创建 Graphviz DOT-file 点文件 ,您可以使用第三方查看器来显示此树(图形)。

    下面是一个Java的快速演示(对不起,我知道一些C语言)。

    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();}
      ;
    

    首先让ANTLR从中生成lexer和解析器文件:

    java -cp antlr-3.2.jar org.antlr.Tool ASTDemo.g 
    

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

    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);
        }
    }
    

    全部编译 .java 文件夹:

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

    然后运行main类并将其输出通过管道传输到名为 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
    

    ast树.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"
    
    }
    

    可以使用 viewers 在这里。甚至还有在线观众。以这个为例: https://dreampuf.github.io/GraphvizOnline/

    喂它的时候 ast树.dot ,生成以下图像:

    ast tree

        2
  •  -1
  •   Lex Li    16 年前

    推荐文章