c# - 创建 ParseTree(不是 AST)

标签 c# antlr antlr3

我想用目标语言 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/

相关文章:

java - Antlr 输入字符串时出错

antlr - 左递归ANTLR文法

java - 我的开始规则的第二个选择

java - Java 和 C# 之间的加密差异

antlr - 将小写字母与 ANTLR 匹配

c# - 公共(public)静态 Dictionary<String,GameObject> 中的游戏对象在 Unity 中的场景更改时被销毁

parsing - ANTLR 赋值表达式消歧

parsing - ANTLR 解析器卡在 proxy.handshake 调用上

c# - 条件运算符和 if-else 之间的差异 :

c# - 在 C# WinForm 应用程序中写入数据库时​​出现问题