-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathGrammar.cs
121 lines (105 loc) · 5.09 KB
/
Grammar.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
117
118
119
120
121
using System.Linq;
using System.Collections.Generic;
namespace Exolutio.Model.PSM.Grammar
{
public class Grammar
{
private readonly List<Terminal> terminals = new List<Terminal>();
public List<Terminal> Terminals { get { return terminals; } }
private readonly List<NonTerminal> nonTerminals = new List<NonTerminal>();
public List<NonTerminal> NonTerminals { get { return nonTerminals; } }
private readonly List<ProductionRule> productionRules = new List<ProductionRule>();
public List<ProductionRule> ProductionRules { get { return productionRules; } }
private readonly List<NonTerminal> initialNonTerminals = new List<NonTerminal>();
public List<NonTerminal> InitialNonTerminals { get { return initialNonTerminals; } }
private readonly Dictionary<PSMComponent, NonTerminal> nonTermialsDictionary = new Dictionary<PSMComponent, NonTerminal>();
public Dictionary<PSMComponent, NonTerminal> NonTermialsDictionary { get { return nonTermialsDictionary; } }
private readonly Dictionary<NonTerminal, PSMComponent> interpretation = new Dictionary<NonTerminal, PSMComponent>();
public Dictionary<NonTerminal, PSMComponent> Interpretation { get { return interpretation; } }
public IEnumerable<ProductionRule> AttributeDeclarations
{
get
{
return ProductionRules.Where(
r => r.RightHandSide is RightHandAttributeDeclaration);
}
}
public IEnumerable<ProductionRule> ElementDeclarations
{
get
{
return ProductionRules.Where(
r => (r.RightHandSide is RightHandElementSimpleContentDeclaration) || (r.RightHandSide is RightHandElementComplexContentDeclaration));
}
}
public NonTerminal GetNonTerminal(PSMComponent psmComponent)
{
NonTerminal nonTerminal;
if (!NonTermialsDictionary.TryGetValue(psmComponent, out nonTerminal))
{
nonTerminal = new NonTerminal(psmComponent);
if (!Exolutio.SupportingClasses.NameSuggestor<NonTerminal>.IsNameUnique(NonTerminals, nonTerminal.ToString(), n => n.ToString()))
{
string name = Exolutio.SupportingClasses.NameSuggestor<NonTerminal>.SuggestUniqueName(NonTerminals, nonTerminal.ToString(), n => n.ToString(), true, false);
nonTerminal.UniqueName = name;
}
NonTermialsDictionary[psmComponent] = nonTerminal;
NonTerminals.Add(nonTerminal);
}
return nonTerminal;
}
public Terminal GetTerminal(string term)
{
Terminal result = Terminals.FirstOrDefault(t => t.Term == term);
if (result == null)
{
result = new Terminal(term);
}
return result;
}
public void OrderProductionRules()
{
Dictionary<ProductionRule, int> orderDict = new Dictionary<ProductionRule, int>();
Queue<ProductionRule> q = new Queue<ProductionRule>();
int num = 0;
foreach (NonTerminal initialNonTerminal in InitialNonTerminals)
{
foreach (ProductionRule productionRule in ProductionRules.Where(r => r.LeftHandNonTerminal == initialNonTerminal))
{
if (!q.Contains(productionRule) && !orderDict.ContainsKey(productionRule))
{
q.Enqueue(productionRule);
orderDict[productionRule] = num++;
}
}
}
while (q.Count != 0)
{
ProductionRule takenRule = q.Dequeue();
foreach (ProductionRuleToken productionRuleToken in takenRule.RightHandSide.GetTokens())
{
if (productionRuleToken is NonTerminalToken)
{
foreach (ProductionRule productionRule in ProductionRules.Where(r => r.LeftHandNonTerminal == ((NonTerminalToken)productionRuleToken).NonTerminal))
{
if (!q.Contains(productionRule) && !orderDict.ContainsKey(productionRule))
{
q.Enqueue(productionRule);
orderDict[productionRule] = num++;
}
}
}
}
}
foreach (ProductionRule productionRule in ProductionRules)
{
if (!orderDict.ContainsKey(productionRule))
{
q.Enqueue(productionRule);
orderDict[productionRule] = num++;
}
}
productionRules.Sort(delegate(ProductionRule r1, ProductionRule r2) { return orderDict[r1].CompareTo(orderDict[r2]); });
}
}
}