summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/Bracket.cs
blob: 6fd8756f8d038539b5e8048636d1d7fe2474c3d2 (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
124
125
126
127
128
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,
					symbol_meta = SymbolMeta
				};
			}

			// 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, UIntPtr lindex, IntPtr fun) {
				stack.Push (new Bracket ());
			}

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

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

				if (stack.Count == 0)
					final = b;
				else 
					stack.Peek ().AddChild (b);
			}
			
			private void SymbolMeta(IntPtr self, int meta_id) {
				stack.Peek().AddChild(new StringChildBracket("?"));
			}

			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() )
		 ) + "}";
    }


}