gpt4 book ai didi

c# - 创建 ParseTree(不是 AST)

转载 作者:太空宇宙 更新时间:2023-11-03 16:21:16 24 4
gpt4 key购买 nike

我想用目标语言 C# 中的 ANTLR 创建一个解析树(不是 AST)。这似乎不那么微不足道,也许我在寻找所有错误的地方。

到目前为止,我尝试在生成的解析器中实现部分,如下所示:

public partial class TestParser
{

ParseTree pt = new ParseTree("root", null);

partial void EnterRule(string ruleName, int ruleIndex)
{
ParseTree child = new ParseTree(ruleName, pt);
pt.Children.Add(child);
this.pt = child;
}

partial void LeaveRule(string ruleName, int ruleIndex)
{
this.pt = pt.Parent;
}

}

ParseTree

public class ParseTree
{
private List<ParseTree> children = new List<ParseTree>();

public ParseTree(string name, ParseTree parent)
{
this.Parent = parent;
this.Rule = name;
}

public ParseTree Parent { get; private set; }
public string Rule { get; private set; }
public List<ParseTree> Children { get { return children; } }

public Boolean IsTerminal
{
get
{
return (children.Count == 0);
}
}

}

这行得通,但没有实现我的目标:我无法从这棵树中获取匹配的标记/文本。除此之外,它还有一个额外的缺点:如果我想对多个语法执行此操作,我必须在任何地方复制粘贴部分类,因为它是 TestParser 的一部分,没有什么比食物链更高的了。

我看过http://www.antlr.org/wiki/pages/viewpage.action?pageId=1760但是生成的解析器没有采用 ParseTreeBuilder 的构造函数。

现在要去哪里?

最佳答案

我找到了一个或多或少合理的解决方案来解决我的问题。它有一个主要缺点:它只处理仅由标记组成的生产规则文本。这对我来说已经足够了,但可能不适合你。一个正确的实现也应该有 token 节点,这样它就可以被正确地遍历。

适配器:

    public class ParseAdaptor : CommonTreeAdaptor
{
private C<ParseTree> container;

public ParseAdaptor(C<ParseTree> container)
: base()
{
this.container = container;
}

public override void AddChild(object t, object child)
{
base.AddChild(t, child);
this.container.Value.Text += base.GetTree(child).Text;
}


}

ParseTree 实现:

public class ParseTree
{
private string ownText;
private List<ParseTree> children = new List<ParseTree>();

public ParseTree(string name, ParseTree parent)
{
this.Parent = parent;
this.Rule = name;
}

public String Text
{
get
{
if (this.IsTerminal) return this.ownText;
else
{
StringBuilder builder = new StringBuilder();
foreach (ParseTree child in children)
{
builder.Append(child.Text);
}
return builder.ToString();
}
}
set
{
this.ownText = value;
}
}

public ParseTree Parent { get; private set; }
public string Rule { get; private set; }
public List<ParseTree> Children { get { return children; } }

public Boolean IsTerminal
{
get
{
return (children.Count == 0);
}
}

}
//Isn't this the silliest little thing you've ever seen?
//Where is a pointer when you need one?
public class C<T>
{
public T Value { get; set; }
}

它与分音粘在一起:

    public partial class TestParser
{

C<ParseTree> parseTreeContainer = new C<ParseTree>() { Value = new ParseTree("root", null) };

public ParseTree Tree
{
get
{
return parseTreeContainer.Value;
}
set
{
parseTreeContainer.Value = value;
}
}

partial void CreateTreeAdaptor(ref ITreeAdaptor adaptor)
{
adaptor = new ParseAdaptor(this.parseTreeContainer);
}

partial void EnterRule(string ruleName, int ruleIndex)
{
ParseTree child = new ParseTree(ruleName, Tree);
ParseTree parent = Tree;
parent.Children.Add(child);
Tree = child;
}

partial void LeaveRule(string ruleName, int ruleIndex)
{
Tree = Tree.Parent;
}

}

关于c# - 创建 ParseTree(不是 AST),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13800036/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com