summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/Bracket.cs
blob: 8fa005704b35661c94d49f70dc403bf9988629f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PGFSharp
{
	// Brackets should only be constructed from the Concrete class.
	// These classes just store the data, they do not own or use
	// unmanaged memory (except in the builder class).
	
	public interface IBracketChild {
		bool IsString {get;}
		string AsStringChild {get;}
		Bracket AsBracketChild {get;}
	}

	/// <summary>
	/// A representation for a syntactic constituent in the parse tree
    /// of a sentence.
    /// </summary>
	public class Bracket : IBracketChild
    {
		public class StringChildBracket : IBracketChild {

			string str;
			internal StringChildBracket(string str) {
				this.str = str;
			}

			public bool IsString => true;
			public string AsStringChild => str;
			public Bracket AsBracketChild {
				get {
					throw new NotImplementedException ();
				}
			}

			public override string ToString () => AsStringChild;
		}

		internal class BracketBuilder {
			internal Native.PgfLinFuncs LinFuncs { get; private set; }

			private Stack<Bracket> stack = new Stack<Bracket> ();
			private Bracket final = null;
			internal BracketBuilder() {
				LinFuncs = new Native.PgfLinFuncs {
					symbol_token = SymbolToken,
					begin_prase = BeginPhrase,
					end_phrase = EndPhrase,
					symbol_ne = null,
					symbol_bind = null,
					symbol_capit = null
				};
			}

			// TODO: the Python wrapper discards begin/end phrase pairs
			// which don't have any tokens. Is this correct and/or necessary?
			private void SymbolToken(IntPtr self, IntPtr token) {
				var str = Native.NativeString.StringFromNativeUtf8 (token);
				stack.Peek ().AddChild (new StringChildBracket (str));
			}

			private void BeginPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun) {
				stack.Push (new Bracket ());
			}

			private void EndPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun) {
				var b = stack.Pop ();

				b.CatName = Native.NativeString.StringFromNativeUtf8 (cat);
				b.FunName = Native.NativeString.StringFromNativeUtf8 (fun);
				b.FId = fid;
				b.LIndex = lindex;

				if (stack.Count == 0)
					final = b;
				else 
					stack.Peek ().AddChild (b);
			}

			public Bracket Build() {
				return final;
			}
		}

		private List<IBracketChild> _children = new List<IBracketChild> ();
		private Bracket() {
		}

		private void AddChild(IBracketChild c) {
			_children.Add(c);
		}

		public bool IsString => false;
		public Bracket AsBracketChild => this;
		public string AsStringChild {
			get {
				throw new NotImplementedException ();
			}
		}

		public IEnumerable<IBracketChild> Children { get { return _children; } }

		public string CatName { get; private set; }
		public string FunName { get; private set; }
		public int FId { get; private set; }
		public int LIndex { get; private set; }

		public override string ToString ()
		{
			return "(" + CatName + ":" + FId + " " + String.Join (" ", Children) + ")";
		}

		public string ToBracketsString =>  "{" + String.Join(" ", 
			Children.Select(c => (c is Bracket) ? ((Bracket)c).ToBracketsString : c.ToString() )
		 ) + "}";
    }


}