Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/17/13 15:19:45 (11 years ago)
Author:
gkronber
Message:

#2026 worked on a plugin for grammars (work-in-progress)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs

    r10031 r10051  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Diagnostics;
    2425using System.Linq;
    2526using System.Text.RegularExpressions;
    2627
    2728namespace 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>();
    2933
    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; } }
    3338
    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);
    4041      this.StartSymbol = startSymbol;
    4142    }
    4243
    43     public int NumberOfAlternatives(string ntSymbol) {
     44    public int NumberOfAlternatives(ISymbol ntSymbol) {
    4445      return rules[ntSymbol].Count;
    4546    }
    4647
    47     public IEnumerable<Sequence> GetAlternatives(string ntSymbol) {
     48    public IEnumerable<Sequence> GetAlternatives(ISymbol ntSymbol) {
    4849      return rules[ntSymbol].AsReadOnly();
    4950    }
    5051
    51     public Sequence GetAlternative(string ntSymbol, int index) {
     52    public Sequence GetAlternative(ISymbol ntSymbol, int index) {
    5253      return rules[ntSymbol][index];
    5354    }
    5455
    55     public void AddProductionRule(string ntSymbol, Sequence production) {
     56    public void AddProductionRule(ISymbol ntSymbol, Sequence production) {
     57      Debug.Assert(ntSymbol != EmptySymbol);
     58
    5659      List<Sequence> l;
    5760      if (!rules.TryGetValue(ntSymbol, out l)) {
     
    6164        allSymbols.Add(ntSymbol); // register new nt-symbol
    6265      }
     66      // check if the same production exists already
     67      Debug.Assert(!l.Any(s => s.SequenceEqual(production)));
     68
    6369      l.Add(production);
    6470
     
    6672    }
    6773
     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
    6887    private static Regex ruleExpr = new Regex(@"\s*(?<ntSymbol>\w+)\s*->\s*(?<alternative>\w+(?:\s+\w+)*)(?:\s*\|\s*(?<alternative>\w+(?:\s+\w+)*))*");
    6988    private static Regex empty = new Regex(@"^\s*$");
    70     public static IGrammar FromString(string gStr) {
     89    public static Grammar FromString(string gStr) {
    7190      var lines = gStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
    7291      lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines
     
    7493      // first line is the rule for the start-symbol
    7594      var m = ruleExpr.Match(lines.First());
    76       var startSymbol = m.Groups["ntSymbol"].Value;
     95      var startSymbol = new Symbol(m.Groups["ntSymbol"].Value);
    7796      var g = new Grammar(startSymbol);
    7897      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))));
    8099      }
    81100      foreach (var line in lines.Skip(1)) {
    82101        m = ruleExpr.Match(line);
    83         var ntSymbol = m.Groups["ntSymbol"].Value;
     102        var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value);
    84103        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))));
    86105        }
    87106      }
     107
    88108      return g;
    89109    }
Note: See TracChangeset for help on using the changeset viewer.