2012-12-10 3 views
2

대상 언어 C#의 ANTLR을 사용하여 구문 분석 트리 (AST 아님)를 만들고 싶습니다. 이것은 덜 사소한 것 같습니다, 아마도 나는 모든 잘못된 장소를보고 있습니다. ParseTreeParseTree (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; 
    } 

} 

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을 사용하는 생성자가 없습니다.

지금까지?

답변

2

나는 내 문제에 대해 다소 합리적인 해결책을 찾았습니다. 그것은 주요 단점을 가지고 있습니다 : 그것은 단지 토큰으로 구성된 생산 규칙의 텍스트만을 처리합니다. 이것은 나를 위해 충분하지만, 당신을 위해 않을 수도 있습니다. 올바른 구현에는 토큰 노드도 있어야하므로 제대로 걸을 수 있습니다.

어댑터 :

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


    } 

파스 트리 구현 :

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

    } 
+0

솔루션을 게시 해 주셔서 감사합니다. 'CommonTreeAdaptor'에 대한 클래스 정의도 나타낼 수 있습니까? – Annie

+0

그것은 ANTLR – Martijn

-2

당신이이 기사를 읽었다 http://www.antlr.org/wiki/pages/viewpage.action?pageId=1760

이 예제는 Java이지만 동일한 클래스가 C# 대상에도 구현되어있는 것으로 생각됩니다.

+2

의 일부입니다. 질문은 "나는 http://www.antlr.org/wiki/pages/viewpage.action?pageId=1760을 보았지만 생성 된 파서에는 ParseTreeBuilder를 사용하는 생성자가 없습니다 " – Martijn

+0

이것은 때때로 stackoverflow가 어리석은 이유입니다. –

+0

그걸 좀 자세히 설명해 주시겠습니까? 나는 내가 따르고 있다고 생각하지 않는다. – Martijn