Mercury.Formats library  1.0
The library provides format parsers for the Mercury library components.
 All Classes Namespaces Files Functions Properties
ModuleLoader.cs
Go to the documentation of this file.
1 using Mercury.Formats.Basic;
2 using Mercury.Interpreting;
3 using Mercury.Scanning;
4 using Mercury.Syntax;
5 using System.Collections.Generic;
6 using System.IO;
7 
8 //
9 // EXPERIMENTAL
10 // ============
11 //
12 // Do not use. For your own safety.
13 // Might set your keyboard on fire or whatnot.
14 //
15 
16 namespace Mercury.Experimental
17 {
18  internal class GrammarLoaderInternal<T> where T : class
19  {
20  private string grammarcwd;
21  private Grammar grammar;
22 
23  private IList<InterpreterAction<T>> actions;
24 
25  private IScanner GetScanner()
26  {
27  List<IScanner> scanners = new List<IScanner>();
28  /*
29  if (GrammarInfo.UseMercuryScanner) scanners.Add(new BasicScanner(BasicScannerMap.Identity));
30 
31  var libdata = GrammarInfo.Scanners.ToMultiDictionary(x => x.Key, x => x.Value);
32  foreach(var libname in libdata.Keys)
33  {
34  Assembly lib = Assembly.Load(Path.Combine(grammarcwd, libname));
35  foreach(var objname in libdata[libname])
36  {
37  Type objtype = lib.GetType(objname);
38  var scanner = (IScanner) Activator.CreateInstance(objtype);
39 
40  if (scanner == null)
41  throw new InvalidOperationException(string.Format("'{0}' is not a scanner", objtype.Name));
42 
43  scanners.Add(scanner);
44  }
45  }
46  */
47  return scanners.Count == 1 ? scanners[0] : new CompositeScanner(scanners);
48  }
49 
50  private Grammar GetGrammar()
51  {
52  var gb = new GrammarBuilder(new Symbol(GrammarInfo.Root), new Symbol(GrammarInfo.Epsilon, SymbolType.Epsilon));
53 
54  foreach(var gname in GrammarInfo.GrammarFiles)
55  {
56  var gparser = new GrammarParser(Path.Combine(GrammarInfo.Path, gname));
57  gb.Include(gparser.GetBuilder());
58  }
59 
60  return gb.GetGrammar();
61  }
62 
63  private IList<InterpreterAction<T>> GetActions()
64  {
65  var actions = new List<InterpreterAction<T>>() { };
66  /*
67  if (GrammarInfo.UseStringActions)
68  {
69  actions.Add((IInterpreterAction<T>) new ConstantAction() );
70  actions.Add((IInterpreterAction<T>) new PreterminalAction());
71  actions.Add((IInterpreterAction<T>) new SimpleAction() );
72  }
73 
74  var libdata = GrammarInfo.Actions.ToMultiDictionary(x => x.Key, x => x.Value);
75  foreach (var libname in libdata.Keys)
76  {
77  Assembly lib = Assembly.Load(Path.Combine(grammarcwd, libname));
78  foreach (var objname in libdata[libname])
79  {
80  Type objtype = lib.GetType(objname);
81  var action = (IInterpreterAction<T>)Activator.CreateInstance(objtype);
82 
83  if (action == null)
84  throw new InvalidOperationException(string.Format("'{0}' is not a valid action of type '{1}'", objtype.Name, typeof(T).Name));
85 
86  actions.Add(action);
87  }
88  }
89  */
90  return actions;
91  }
92 
93  private RewriteRuleCollection<T> GetRwRules()
94  {
95  var rwrb = new RewriteRuleCollectionBuilder<T>();
96 
97  foreach (var rwrname in GrammarInfo.RwRulesFiles)
98  {
99  var iparser = new RewriteRulesParser<T>(rwrname, new Symbol(GrammarInfo.Epsilon, SymbolType.Epsilon), actions);
100  rwrb.AddRules(iparser.GetRules());
101  }
102 
103  return rwrb.GetCollection();
104  }
105 
106  public GrammarLoaderInternal(GrammarInfo grminf)
107  {
108  this.GrammarInfo = grminf;
109  this.grammarcwd = grminf.Path;
110  }
111 
112  public LanguageInfo<T> GetLanguageInfo()
113  {
114  grammar = GetGrammar();
115  actions = GetActions();
116  return new LanguageInfo<T>(GrammarInfo.Name, new Tokenizer(), GetScanner(), grammar, GetRwRules());
117  }
118 
119  public GrammarInfo GrammarInfo { get; private set; }
120  }
121 
122  internal static class GrammarLoader<T> where T : class
123  {
124  public static LanguageInfo<T> GetLanguageInfo(GrammarInfo grminf)
125  { return (new GrammarLoaderInternal<T>(grminf)).GetLanguageInfo(); }
126 
127  public static LanguageInfo<T> GetLanguageInfo(string file)
128  { return GetLanguageInfo(GrammarInfo.FromXML(file)); }
129 
130  public static Analyser<T> GetAnalyzer(GrammarInfo grminf)
131  { return new Analyser<T>(new GrammarLoaderInternal<T>(grminf).GetLanguageInfo()); }
132 
133  public static Analyser<T> GetAnalyzer(string file)
134  { return GetAnalyzer(GrammarInfo.FromXML(file)); }
135  }
136 }
Parses a grammar from a StreamReader. Grammar is expected in the format
Parses the file containing rewrite rules. It is of the following format: