Mercury library  1.0
Translation of CFG grammars into an object model (Bachelor's thesis).
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
Analyser.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.Diagnostics;
7 using System.Linq;
8 
9 namespace Mercury
10 {
11 //=============================================================================
12 // Analyser
13 //=============================================================================
14 
18  public class Analyser<T, TResult>
19  where T : class
20  where TResult : class
21  {
22  private Func<T, TResult> rselect;
23 
24  //--[ Constructors ]-------------------------------------------------
25 
33  public Analyser(LanguageInfo<T> langinfo, Func<T,TResult> resultSelector,
34  IInterpreterContextFactory contextFactory = null)
35  : this(langinfo.Tokenizer, langinfo.Scanner, new ChartParser(langinfo.Grammar),
36  langinfo.RewriteRules == null ? null : new Interpreter<T>(langinfo.RewriteRules, contextFactory),
37  resultSelector)
38  { }
39 
52  public Analyser(ITokenizer tokenizer, IScanner scanner, IParser parser,
53  IInterpreter<T> interpreter, Func<T,TResult> resultSelector)
54  {
55  if (tokenizer == null) throw new ArgumentNullException("tokenizer");
56  if (parser == null) throw new ArgumentNullException("parser");
57 
58  if (interpreter != null && (resultSelector == null))
59  throw new ArgumentNullException("resultSelector");
60 
61  Tokenizer = tokenizer;
62  Scanner = scanner;
63  Parser = parser;
64  Interpreter = interpreter;
65 
66  this.rselect = resultSelector;
67  }
68 
69  //--[ Properties ]---------------------------------------------------
70 
72  public ITokenizer Tokenizer { get; private set; }
73 
75  public IScanner Scanner { get; private set; }
76 
78  public IParser Parser { get; private set; }
79 
81  public IInterpreter<T> Interpreter { get; private set; }
82 
83  //--[ Methods ]------------------------------------------------------
84 
90  public AnalyserResult<T, TResult> Analyze(string input)
91  {
92  if (input == null)
93  throw new ArgumentNullException("Null input? What am I supposed to do with that?");
94 
95  var result = new AnalyserResult<T, TResult>();
96 
97  IList<Token> tokens = null;
98  var rules = new List<Rule>();
99  var watch = new Stopwatch();
100 
101  // Ready... Steady... GO!
102  watch.Start();
103 
104  //--< Tokenizer stage >------------------------------------------
105  try
106  { tokens = Tokenizer.Tokenize(input); }
107  catch (Exception ex)
108  {
109  watch.Stop();
110  result.SetStatus(watch.Elapsed, AnalyserStatus.TokenizerFail, ex: ex);
111  return result;
112  }
113 
114  //--< Scanner stage >--------------------------------------------
115  if (Scanner != null)
116  try
117  { rules.AddRange(Scanner.Scan(tokens)); }
118  catch (Exception ex)
119  {
120  watch.Stop();
121  result.SetStatus(watch.Elapsed, AnalyserStatus.ScannerFail, ex: ex);
122  return result;
123  }
124 
125  //--< Parser stage >---------------------------------------------
126  try
127  {
128  result.ParserTime = watch.Elapsed;
129  result.ParserResult = Parser.Parse(tokens, rules);
130  result.ParserTime = watch.Elapsed - result.ParserTime;
131  }
132  catch (Exception ex)
133  {
134  watch.Stop();
135  result.SetStatus(watch.Elapsed, AnalyserStatus.ParserFail, ex: ex);
136  return result;
137  }
138 
139  if (!result.ParserResult.Accepted)
140  {
141  watch.Stop();
142  result.SetStatus(watch.Elapsed, AnalyserStatus.ParserFail, FailReason.NoResult);
143  return result;
144  }
145 
146  //--< Interpreter stage >----------------------------------------
147  if (Interpreter != null)
148  try
149  {
150  var sw = new Stopwatch();
151  var ok = false;
152 
153  sw.Start();
154  result.InterpreterResults = Interpreter.Interpret(result.ParserResult.Trees);
155  sw.Stop();
156 
157  var rvals = new TResult[result.InterpreterResults.Count];
158 
159  for (int ix = 0; ix < result.InterpreterResults.Count; ++ix )
160  {
161  var b = result.InterpreterResults[ix].Success;
162  ok |= b;
163  rvals[ix] = b ? rselect(result.InterpreterResults[ix].Result) : default(TResult);
164  }
165 
166  result.Interpretations = rvals;
167  result.InterpreterTime = sw.Elapsed;
168 
169  if (!ok)
170  {
171  watch.Stop();
172  result.SetStatus(watch.Elapsed, AnalyserStatus.InterpreterFail, FailReason.NoResult);
173  return result;
174  }
175 
176  }
177  catch(Exception ex)
178  {
179  watch.Stop();
180  result.SetStatus(watch.Elapsed, AnalyserStatus.InterpreterFail, ex: ex);
181  return result;
182  }
183 
184 
185  //--< Finalization >---------------------------------------------
186  watch.Stop();
187  result.SetStatus(watch.Elapsed, AnalyserStatus.Success, FailReason.None);
188 
189  return result;
190  }
191  }
192 
195  public class Analyser<T> : Analyser<T,T> where T : class
196  {
202  public Analyser(LanguageInfo<T> langinfo, IInterpreterContextFactory contextFactory = null)
203  : base(langinfo, x => x, contextFactory)
204  { }
205 
214  public Analyser(ITokenizer tokenizer, IScanner scanner, IParser parser, IInterpreter<T> interpreter)
215  : base(tokenizer, scanner, parser, interpreter, x => x)
216  { }
217  }
218 
219 }
Thread-safe wrapper for ChartParserInternal class.
Definition: Parser.cs:298
Represents a collection of information required to analyze a language with Mercury Mercury...
Definition: LanguageInfo.cs:13
Creates a derivation tree from the list of input tokens
Definition: Parser.cs:15
A default implementation of ITokenizer interface using Microsoft Regular Expressions. Splits tokens in the following fashion:
Definition: Tokenizer.cs:71
AnalyserResult< T, TResult > Analyze(string input)
Analyzes the specified input and returns the Mercury.AnalyserResult{T,TResult}.
Definition: Analyser.cs:90
Analyser(LanguageInfo< T > langinfo, IInterpreterContextFactory contextFactory=null)
Initializes a new instance of the Analyser{T} class.
Definition: Analyser.cs:202
Analyser(ITokenizer tokenizer, IScanner scanner, IParser parser, IInterpreter< T > interpreter, Func< T, TResult > resultSelector)
Initializes a new instance of analyzer from the class. Scanner and Interpreter can be null (if so...
Definition: Analyser.cs:52
An exception has been thrown
Analyser(ITokenizer tokenizer, IScanner scanner, IParser parser, IInterpreter< T > interpreter)
Initializes a new instance of the Analyser{T} class. See Mercury.Analyser{T,TResult} for more informa...
Definition: Analyser.cs:214
The tokenizer interface.
Definition: Tokenizer.cs:14
Holds the result of analysis. The fields hold information according to the following table: ...
Interface for interpreters that create objects from derivation trees according to RewriteRules...
Definition: Interpreter.cs:20
Scanner scans input tokens and creates additional rules for parsing.
Definition: Scanner.cs:20
Represents a Context-Free Grammar. This is an immutable class, to create a grammar use Mercury...
Definition: Grammar.cs:18
Analyser(LanguageInfo< T > langinfo, Func< T, TResult > resultSelector, IInterpreterContextFactory contextFactory=null)
Initializes a new instance of the Analyser{T,TResult} class from the provided language information...
Definition: Analyser.cs:33