Mercury.Formats library  1.0
The library provides format parsers for the Mercury library components.
 All Classes Namespaces Files Functions Properties
RewriteRulesFileParser.cs
Go to the documentation of this file.
1 using Mercury.Scanning;
2 using Mercury.Interpreting;
3 using Mercury.Syntax;
4 using System;
5 using System.Collections.Generic;
6 using System.IO;
7 using System.Linq;
8 
9 namespace Mercury.Formats.Basic
10 {
53  public class RewriteRulesParser<T> : IDisposable
54  where T : class
55  {
56  private static Tokenizer inputTokenizer = null;
57 
58  //--[ Private fields ]-----------------------------------------------
59 
60  private StreamReader source = null;
61  private string filename = null;
62  private Symbol epsilon;
63 
64  private IReadOnlyDictionary<string, InterpreterAction<T>> actions;
65  private IReadOnlyDictionary<string, string> aliases;
66 
67  //--[ Constructors ]-------------------------------------------------
68 
81  public RewriteRulesParser(StreamReader reader, Symbol epsilon,
82  IEnumerable<InterpreterAction<T>> actions, IReadOnlyDictionary<string,string> aliases = null)
83  {
84  if (reader == null) throw new ArgumentNullException("reader");
85  if (actions == null) throw new ArgumentNullException("actions");
86 
87  this.source = reader;
88  this.epsilon = epsilon;
89 
90  this.actions = actions.ToDictionary(x => x.Name, StringComparer.OrdinalIgnoreCase);
91  this.aliases = aliases ?? new Dictionary<string, string>();
92 
93  var keywords = new[] { "==>" }.Concat(this.aliases.Select(x => x.Key));
94 
95  inputTokenizer = new Tokenizer("@_", keywords, TokenizerOptions.CompiledMatch);
96  }
97 
98  public RewriteRulesParser(string filename, Symbol epsilon,
99  IEnumerable<InterpreterAction<T>> actions, IReadOnlyDictionary<string, string> aliases = null)
100  : this(new StreamReader(filename), epsilon, actions, aliases)
101  { this.filename = filename; }
102 
103  //--[ Methods ]------------------------------------------------------
104 
105  private RewriteRuleCollection<T> GetRules(ref int linenum)
106  {
107  string line = null;
108 
109  var tokens = new List<Token>();
110  var ruletok = new List<Token>();
111  var builder = new RewriteRuleCollectionBuilder<T>();
112 
113  var iep = new InterpreterEntityParser<T>(epsilon, actions, aliases);
114 
115  Action parse = delegate()
116  {
117  if (ruletok.Count != 0)
118  builder.AddRewriteRule(iep.ParseRewriteRule(ruletok));
119  ruletok.Clear();
120  };
121 
122  int actline = 0;
123  linenum = 1;
124  while((line = source.ReadLine()) != null)
125  {
126  ++actline;
127  tokens.Clear();
128  tokens.AddRange(inputTokenizer.Tokenize(line));
129 
130  if ((tokens.Count == 0) || (tokens[0].Value == "#"))
131  continue;
132 
133  if (tokens.Any(x => (x.Type == TokenType.Keyword) && (x.Value == "==>")))
134  {
135  parse.Invoke();
136  ruletok.Clear();
137  linenum = actline;
138  }
139 
140  ruletok.AddRange(tokens);
141  }
142 
143  if (ruletok.Count != 0)
144  parse.Invoke();
145 
146  return builder.GetCollection();
147  }
148 
154  public RewriteRuleCollection<T> GetRules()
155  {
156  int linenum = 0;
157 
158  try
159  { return GetRules(ref linenum); }
160  catch (Exception ex)
161  {
162  string msg = filename == null
163  ? string.Format("In {0}: {1}", linenum, ex.Message)
164  : string.Format("In {0} line {1}: {2}", filename, linenum, ex.Message);
165 
166  throw new FormatException(msg, ex);
167  }
168  }
169 
170  //--[ Interface implementation ]-----------------------------------------------
171 
172  #region [ IDisposable ]
173 
174  public void Dispose()
175  { if (filename != null) source.Close(); }
176 
177  #endregion
178 
179  }
180 }
Class for parsing interpreter entities used in Mercury. Since there is a lot of tokens to scan...
RewriteRuleCollection< T > GetRules()
Parses the stream and returns the collection of rules.
RewriteRulesParser(StreamReader reader, Symbol epsilon, IEnumerable< InterpreterAction< T >> actions, IReadOnlyDictionary< string, string > aliases=null)
Initializes a new instance of the RewriteRulesParser{T} class.
RewriteRulesParser(string filename, Symbol epsilon, IEnumerable< InterpreterAction< T >> actions, IReadOnlyDictionary< string, string > aliases=null)