抽象语法树和打印
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象语法树和打印相关的知识,希望对你有一定的参考价值。
目标是使用提供的Node,IDNode,INTNode和StringNode类在JavaCC中创建AST。我相信这部分很好,但我还需要创建一个打印方法,它接受一个Node参数并打印AST节点标签。最初,我的问题是Nodes的子节点是LinkedLists,它们无法转换为Node进行递归打印。目前,我收到编译错误,声称Node n可能尚未在AST的几个部分中初始化。
我已经尝试过递归打印和循环打印以及直接从LinkedList对象访问标签而不是从Node对象访问标签。我甚至无法测试以确保AST按预期工作(我按照我在课堂和实验表中显示的方式编写代码),因为我无法编译java。
public class Node
{
String label;
LinkedList<Node> children;
public Node(String label)
{
this.label = label;
}
public void addChild(Node n)
{
if(children == null)
children = new LinkedList<Node>();
children.add(n);
}
}
public class IDNode extends Node
{
String id;
public IDNode(String id)
{
super("ID");
this.id = id;
}
}
public class INTNode extends Node
{
int value;
public INTNode(String value)
{
super("INT");
this.value = Integer.parseInt(value);
}
}
public class StringNode extends Node
{
String text;
public StringNode(String text)
{
super("STRING");
this.text = text;
}
}
PARSER_BEGIN(PPL)
import java.io.*;
import java.util.LinkedList;
class PPL
{
public static void main(String[] args) throws ParseException, TokenMgrError
{
if(args.length > 0)
{
try
{
PPL scan = new PPL(new FileInputStream(args[0]));
scan.Program();
}
catch(FileNotFoundException ex)
{
System.out.println("File " + args[0] + " not found.");
}
}
else
{
System.out.println("Must specify source code file name.");
}
Node n = Program();
printAST(n);
}
public static void printAST(Node n)
{
if(n == null)
{
return;
}
System.out.println(n.label);
while(n != null)
{
LinkedList<Node> m = n.children;
System.out.println(m.label);
}
}
}
/* JavaCC input file for PPL
/* Author: Michael Lord
*/
PARSER_BEGIN(PPL)
import java.io.*;
import java.util.LinkedList;
class PPL
{
public static void main(String[] args) throws ParseException, TokenMgrError
{
if(args.length > 0)
{
try
{
PPL scan = new PPL(new FileInputStream(args[0]));
scan.Program();
}
catch(FileNotFoundException ex)
{
System.out.println("File " + args[0] + " not found.");
}
}
else
{
System.out.println("Must specify source code file name.");
}
Node n = Program();
printAST(n);
}
public static void printAST(Node n)
{
if(n == null)
{
return;
}
System.out.println(n.label);
while(n != null)
{
LinkedList<Node> m = n.children;
System.out.println(m.label);
}
}
}
PARSER_END(PPL)
SKIP : { " " }
TOKEN : { <NEWLINE : "
"> }
TOKEN : { <TAB : " "> }
TOKEN : { <IN : "IN"> }
TOKEN : { <OUT : "OUT"> }
TOKEN : { <IS : "IS"> }
TOKEN : { <IF : "IF"> }
TOKEN : { <ELSE : "ELSE"> }
TOKEN : { <REPEATIF : "REPEATIF"> }
TOKEN : { <PLUS : "+"> }
TOKEN : { <MINUS : "-"> }
TOKEN : { <MUL : "*"> }
TOKEN : { <DIV : "/"> }
TOKEN : { <LEFT_PAREN : "("> }
TOKEN : { <RIGHT_PAREN : ")"> }
TOKEN : { <LESS_THAN : "<"> }
TOKEN : { <MORE_THAN : ">"> }
TOKEN : { <LESS_THAN_OR_EQUAL : "<="> }
TOKEN : { <MORE_THAN_OR_EQUAL : ">=">}
TOKEN : { <NOT_EQUAL : "NOT="> }
TOKEN : { <EQUAL : "="> }
TOKEN : { <AND : "AND"> }
TOKEN : { <OR : "OR"> }
TOKEN : { <NOT : "NOT"> }
TOKEN : { <INT : "0" | ["1" - "9"](["0" - "9"])*> }
TOKEN : { <ID : (["a" - "z", "A" - "Z"])+ ((["0" - "9"] | ["_"])* (["a" - "z", "A" - "Z"])*)* > }
TOKEN : { <OPEN_STRING: """> : STRING }
<STRING> TOKEN : { <STRING_BODY : ("\\" | "\"" | ~[""", "\"])+> }
<STRING> TOKEN : { <CLOSE_STRING : """> : DEFAULT }
Node Program():
{
Node n, child;
}
{
{ n = new Node("Program"); }
child = Statement_List() { n.addChild(child); }
<EOF>
{ return n; }
}
Node Statement_List():
{
Node n, child;
}
{
{ n = new Node("Statement_list"); }
child = Statement() { n.addChild(child); }
(
child = Statement_List() { n.addChild(child); }
)?
{ return n; }
}
Node Statement():
{
Node n, child;
}
{
{ n = new Node("Statement"); }
child = Input() { n.addChild(child); }
|
child = Output() { n.addChild(child); }
|
child = Assign() { n.addChild(child); }
|
child = Conditional() { n.addChild(child); }
|
child = Loop() { n.addChild(child); }
|
<NEWLINE>
{ return n; }
}
Node Input():
{
Node n, child;
}
{
{ n = new Node("IN"); }
<IN>
child = Identifier() { n.addChild(child); }
<NEWLINE>
{ return n; }
}
Node Output():
{
Node n, child;
Token t;
}
{
{ n = new Node("OUT"); }
<OUT>
<LEFT_PAREN>
(
<OPEN_STRING>
t = <STRING_BODY> { n.addChild(new StringNode(t.image)); }
<CLOSE_STRING>
(
child = Concatenate() { n.addChild(child); }
child = Factor() { n.addChild(child); }
(
child = Concatenate() { n.addChild(child); }
<OPEN_STRING>
t = <STRING_BODY> { n.addChild(new StringNode(t.image)); }
<CLOSE_STRING>
)?)?)
<RIGHT_PAREN>
<NEWLINE>
{ return n; }
}
Node Assign():
{
Node n, child;
}
{
{ n = new Node("IS"); }
child = Identifier() { n.addChild(child); }
<IS>
child = Expression() { n.addChild(child); }
<NEWLINE>
{ return n; }
}
Node Conditional():
{
Node n, child;
}
{
{ n = new Node("IF"); }
<IF>
<LEFT_PAREN>
child = Comparison() { n.addChild(child); }
<RIGHT_PAREN>
<NEWLINE>
child = Block() { n.addChild(child); }
(
<ELSE>
child = Block() { n.addChild(child); }
)?
{return n; }
}
Node Loop():
{
Node n, child;
}
{
<REPEATIF> { n = new Node("REPEATIF"); }
<LEFT_PAREN>
child = Comparison() { n.addChild(child); }
<RIGHT_PAREN>
<NEWLINE>
child = Block() { n.addChild(child); }
{ return n; }
}
Node Block():
{
Node n, child;
}
{
{ n = new Node("Block"); }
(
<TAB>
child = Statement() { n.addChild(child); }
)+
<NEWLINE>
{ return n; }
}
Node Expression():
{
Node n, child;
}
{
{ n = new Node("Expression"); }
child = Term() { n.addChild(child); }
((
<PLUS> { n.addChild(new Node("PLUS")); }
|
<MINUS> { n.addChild(new Node("MINUS")); }
)
child = Term() { n.addChild(child); }
)*
{ return n; }
}
Node Term():
{
Node n, child;
}
{
{ n = new Node("Term"); }
child = Factor() { n.addChild(child); }
((
<MUL> { n.addChild(new Node("MUL")); }
|
<DIV> { n.addChild(new Node("DIV")); }
)
child = Factor() { n.addChild(child); }
)*
{ return n; }
}
Node Factor():
{
Node n, child;
}
{
{ n = new Node("Factor"); }
child = Identifier() { n.addChild(child); }
|
child = Integer() { n.addChild(child); }
|
<LEFT_PAREN>
child = Expression() { n.addChild(child); }
<RIGHT_PAREN>
{ return n; }
}
IDNode Identifier():
{
Token t;
}
{
t = <ID> { return new IDNode(t.image); }
}
INTNode Integer():
{
Token t;
}
{
t = <INT> { return new INTNode(t.image); }
}
Node Comparison():
{
Node n, child;
}
{
{ n = new Node("Comparison"); }
child = Factor() { n.addChild(child); }
(
child = Compare_Operator() { n.addChild(child); }
child = Factor() { n.addChild(child); }
)?
{ return n; }
}
Node Compare_Operator():
{
Node n;
}
{
{ n = new Node("Compare_Operator"); }
<LESS_THAN> { n.addChild(new Node("LESS THAN")); }
|
<MORE_THAN> { n.addChild(new Node("MORE THAN")); }
|
<LESS_THAN_OR_EQUAL> { n.addChild(new Node("LESS THAN OR EQUAL")); }
|
<MORE_THAN_OR_EQUAL> { n.addChild(new Node("MORE THAN OR EQUAL")); }
|
<NOT_EQUAL> { n.addChild(new Node("NOT EQUAL")); }
|
<EQUAL> { n.addChild(new Node("EQUAL")); }
{ return n; }
}
Node Concatenate():
{
}
{
<PLUS> { return new Node("PLUS"); }
}
期望构建AST并按顺序打印节点的标签。相反,我得到编译错误,使用一些打印方法我得到转换错误或LinkedList和Node之间不兼容的类型错误。在一些语法方法中,它开始说“n可能没有被初始化”的其他方法,即使它是。
我认为主要的问题在于你如何编写Statement
和类似的例程。你有
Node Statement():
{
Node n, child;
}
{
{ n = new Node("Statement"); }
child = Input() { n.addChild(child); }
|
child = Output() { n.addChild(child); }
|
etc etc
|
<NEWLINE>
{ return n; }
}
问题是组合的优先级高于交替。你需要括号。像这样。
Node Statement():
{
Node n, child;
}
{
{ n = new Node("Statement"); }
(
child = Input() { n.addChild(child); }
|
child = Output() { n.addChild(child); }
|
etc etc
|
<NEWLINE>
)
{ return n; }
}
在Term
,Factor
和Compare_Operator
中也存在类似的错误。
这是一种任务递归。你没有列出你所有的错误,所以我不知道这是否会解决它,但它是朝着正确方向迈出的一步。你的问题是你试图打印m的标签,但m是LinkedList,而不是节点。您需要打印LinkedList中包含的节点的标签。
public static void printAST(Node n)
{
if(n == null)
{
return;
}
System.out.println(n.label);
if (n.children == null) {
return;
}
for (Node m : n.children)
{
printAST(m);
}
}
以上是关于抽象语法树和打印的主要内容,如果未能解决你的问题,请参考以下文章
使用 BaggingClassifier 时打印决策树和 feature_importance
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情