- Timestamp:
- 10/17/13 15:19:45 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs
r10031 r10051 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Diagnostics; 24 25 using System.Linq; 25 26 using System.Text.RegularExpressions; 26 27 27 28 namespace HeuristicLab.Grammars { 28 using Sequence = IEnumerable<string>; 29 public class Grammar : IGrammar { 30 public static readonly ISymbol EmptySymbol = new Symbol("EPS"); 31 private Dictionary<ISymbol, List<Sequence>> rules = new Dictionary<ISymbol, List<Sequence>>(); 32 private HashSet<ISymbol> allSymbols = new HashSet<ISymbol>(); 29 33 30 public class Grammar : IGrammar { 31 private Dictionary<string, List<Sequence>> rules = new Dictionary<string, List<Sequence>>(); 32 private HashSet<string> allSymbols = new HashSet<string>(); 34 public ISymbol StartSymbol { get; set; } 35 public IEnumerable<ISymbol> TerminalSymbols { get { return allSymbols.Except(NonTerminalSymbols); } } 36 public IEnumerable<ISymbol> NonTerminalSymbols { get { return rules.Keys; } } 37 public IEnumerable<ISymbol> Symbols { get { return allSymbols; } } 33 38 34 public string StartSymbol { get; set; } 35 public IEnumerable<string> TerminalSymbols { get { return allSymbols.Except(NonTerminalSymbols); } } 36 public IEnumerable<string> NonTerminalSymbols { get { return rules.Keys; } } 37 public IEnumerable<string> Symbols { get { return allSymbols; } } 38 39 public Grammar(string startSymbol) { 39 public Grammar(ISymbol startSymbol) { 40 Debug.Assert(startSymbol != EmptySymbol); 40 41 this.StartSymbol = startSymbol; 41 42 } 42 43 43 public int NumberOfAlternatives( stringntSymbol) {44 public int NumberOfAlternatives(ISymbol ntSymbol) { 44 45 return rules[ntSymbol].Count; 45 46 } 46 47 47 public IEnumerable<Sequence> GetAlternatives( stringntSymbol) {48 public IEnumerable<Sequence> GetAlternatives(ISymbol ntSymbol) { 48 49 return rules[ntSymbol].AsReadOnly(); 49 50 } 50 51 51 public Sequence GetAlternative( stringntSymbol, int index) {52 public Sequence GetAlternative(ISymbol ntSymbol, int index) { 52 53 return rules[ntSymbol][index]; 53 54 } 54 55 55 public void AddProductionRule(string ntSymbol, Sequence production) { 56 public void AddProductionRule(ISymbol ntSymbol, Sequence production) { 57 Debug.Assert(ntSymbol != EmptySymbol); 58 56 59 List<Sequence> l; 57 60 if (!rules.TryGetValue(ntSymbol, out l)) { … … 61 64 allSymbols.Add(ntSymbol); // register new nt-symbol 62 65 } 66 // check if the same production exists already 67 Debug.Assert(!l.Any(s => s.SequenceEqual(production))); 68 63 69 l.Add(production); 64 70 … … 66 72 } 67 73 74 public bool IsTerminal(ISymbol symbol) { 75 return !rules.ContainsKey(symbol) && allSymbols.Contains(symbol); 76 } 77 public bool IsNonTerminal(ISymbol symbol) { 78 return rules.ContainsKey(symbol); 79 } 80 81 // checks if a rule exists for each NT symbol 82 public bool IsComplete() { 83 return rules.ContainsKey(StartSymbol) && 84 NonTerminalSymbols.All(nt => rules.ContainsKey(nt)); 85 } 86 68 87 private static Regex ruleExpr = new Regex(@"\s*(?<ntSymbol>\w+)\s*->\s*(?<alternative>\w+(?:\s+\w+)*)(?:\s*\|\s*(?<alternative>\w+(?:\s+\w+)*))*"); 69 88 private static Regex empty = new Regex(@"^\s*$"); 70 public static IGrammar FromString(string gStr) {89 public static Grammar FromString(string gStr) { 71 90 var lines = gStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); 72 91 lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines … … 74 93 // first line is the rule for the start-symbol 75 94 var m = ruleExpr.Match(lines.First()); 76 var startSymbol = m.Groups["ntSymbol"].Value;95 var startSymbol = new Symbol(m.Groups["ntSymbol"].Value); 77 96 var g = new Grammar(startSymbol); 78 97 foreach (var alt in m.Groups["alternative"].Captures) { 79 g.AddProductionRule(startSymbol, alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));98 g.AddProductionRule(startSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n)))); 80 99 } 81 100 foreach (var line in lines.Skip(1)) { 82 101 m = ruleExpr.Match(line); 83 var ntSymbol = m.Groups["ntSymbol"].Value;102 var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value); 84 103 foreach (var alt in m.Groups["alternative"].Captures) { 85 g.AddProductionRule(ntSymbol, alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));104 g.AddProductionRule(ntSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n)))); 86 105 } 87 106 } 107 88 108 return g; 89 109 }
Note: See TracChangeset
for help on using the changeset viewer.