-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathCfgLL1ParseTable.cs
116 lines (113 loc) · 2.96 KB
/
CfgLL1ParseTable.cs
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
using System;
using System.Collections.Generic;
using System.Text;
namespace Pck
{
public struct CfgLL1ParseTableEntry
{
public CfgRule Rule;
public CfgLL1ParseTableEntry(CfgRule rule)
{
Rule = rule;
}
}
public class CfgLL1ParseTable : Dictionary<string, IDictionary<string, CfgLL1ParseTableEntry>>
{
static string _MakeSafeCsv(string field)
{
if (-1 < field.IndexOfAny(new char[] { ',', '\"', '\n', '\r' }))
return string.Concat("\"", field.Replace("\"", "\"\""), "\"");
return field;
}
public override string ToString()
{
var sb = new StringBuilder();
var ntl = new List<string>();
var tl = new List<string>();
foreach (var entry in this)
{
ntl.Add(entry.Key);
foreach (var entry2 in entry.Value)
if (!tl.Contains(entry2.Key))
tl.Add(entry2.Key);
}
sb.Append("LL(1) Parse Table");
foreach (var t in tl)
{
sb.Append(",");
sb.Append(_MakeSafeCsv(t));
}
sb.AppendLine();
foreach (var nt in ntl)
{
sb.Append(_MakeSafeCsv(nt));
foreach (var t in tl)
{
if (!Equals("#ERROR", t))
{
sb.Append(",");
CfgLL1ParseTableEntry lr;
IDictionary<string, CfgLL1ParseTableEntry> d;
if (TryGetValue(nt, out d) && d.TryGetValue(t, out lr))
{
var r = lr.Rule;
sb.Append(_MakeSafeCsv(r.Left));
sb.Append(" ->");
foreach (var sym in r.Right)
{
sb.Append(" ");
sb.Append(_MakeSafeCsv(sym));
}
}
}
}
sb.AppendLine();
}
return sb.ToString();
}
public int[][][] ToArray(IEnumerable<string> symbolTable= null)
{
var stbl = symbolTable as IList<string>;
if (null == stbl && null != symbolTable)
stbl = new List<string>(symbolTable);
if (null == stbl)
{
stbl = new List<string>();
var ntl = new List<string>();
var tl = new List<string>();
foreach (var entry in this)
{
ntl.Add(entry.Key);
foreach (var entry2 in entry.Value)
if (!tl.Contains(entry2.Key))
tl.Add(entry2.Key);
}
stbl.AddRange(ntl);
stbl.AddRange(tl);
}
var result = new int[Count][][];
foreach (var r in this)
{
var ntid = stbl.IndexOf(r.Key);
if (0 > ntid) throw new ArgumentException(string.Concat("Non-terminal \"", r.Key, "\" not present in the symbol table"), "symbolTable");
result[ntid] = new int[stbl.Count - Count][];
foreach (var rr in r.Value)
{
var tid = stbl.IndexOf(rr.Key);
if (0 > tid) throw new ArgumentException(string.Concat("Terminal \"", rr.Key, "\" not present in the symbol table"), "symbolTable");
tid -= Count;
result[ntid][tid] = new int[rr.Value.Rule.Right.Count];
var i = 0;
foreach (var sym in rr.Value.Rule.Right)
{
var sid = stbl.IndexOf(sym);
if (0 > sid) throw new ArgumentException(string.Concat("Symbol \"", sym, "\" not present in the symbol table"), "symbolTable");
result[ntid][tid][i] = sid;
++i;
}
}
}
return result;
}
}
}