Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Attribute.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Attribute.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Attribute.cs	(revision 10051)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Grammars {
+  public class Attribute : IAttribute {
+    public AttributeType AttributeType { get; private set; }
+    public string Type { get; private set; }
+    public string Name { get; private set; }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/AttributedGrammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/AttributedGrammar.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/AttributedGrammar.cs	(revision 10051)
@@ -0,0 +1,61 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.Grammars {
+  public class AttributedGrammar : Grammar {
+    public AttributedGrammar(ISymbol startSymbol)
+      : base(startSymbol) {
+      Debug.Assert(!startSymbol.Equals(EmptySymbol));
+      this.StartSymbol = startSymbol;
+    }
+
+    private static Regex ruleExpr = new Regex(@"\s*(?<ntSymbol>\w+)\s*(?<formPar>\<\w+\>)+\s*->\s*(?<alternative>\w+\s*(?<actPar>\<\w+\>)+(?:\s+\w+\s*(?<actPar>\<\w+\>)+)*)(?:\s*\|\s*(?<alternative>\w+\s*(?<formPar>\<\w+\>)+(?:\s+\w+\s*(?<formPar>\<\w+\>)+)*))*");
+    private static Regex empty = new Regex(@"^\s*$");
+    public static Grammar FromString(string gStr) {
+      var lines = gStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+      lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines
+
+      // first line is the rule for the start-symbol
+      var m = ruleExpr.Match(lines.First());
+      var startSymbol = new Symbol(m.Groups["ntSymbol"].Value);
+      
+      var g = new Grammar(startSymbol);
+      foreach (var alt in m.Groups["alternative"].Captures) {
+        g.AddProductionRule(startSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));
+      }
+      foreach (var line in lines.Skip(1)) {
+        m = ruleExpr.Match(line);
+        var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value);
+        foreach (var alt in m.Groups["alternative"].Captures) {
+          g.AddProductionRule(ntSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));
+        }
+      }
+
+      return g;
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs	(revision 10051)
@@ -22,36 +22,39 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Text.RegularExpressions;
 
 namespace HeuristicLab.Grammars {
-  using Sequence = IEnumerable<string>;
+  public class Grammar : IGrammar {
+    public static readonly ISymbol EmptySymbol = new Symbol("EPS");
+    private Dictionary<ISymbol, List<Sequence>> rules = new Dictionary<ISymbol, List<Sequence>>();
+    private HashSet<ISymbol> allSymbols = new HashSet<ISymbol>();
 
-  public class Grammar : IGrammar {
-    private Dictionary<string, List<Sequence>> rules = new Dictionary<string, List<Sequence>>();
-    private HashSet<string> allSymbols = new HashSet<string>();
+    public ISymbol StartSymbol { get; set; }
+    public IEnumerable<ISymbol> TerminalSymbols { get { return allSymbols.Except(NonTerminalSymbols); } }
+    public IEnumerable<ISymbol> NonTerminalSymbols { get { return rules.Keys; } }
+    public IEnumerable<ISymbol> Symbols { get { return allSymbols; } }
 
-    public string StartSymbol { get; set; }
-    public IEnumerable<string> TerminalSymbols { get { return allSymbols.Except(NonTerminalSymbols); } }
-    public IEnumerable<string> NonTerminalSymbols { get { return rules.Keys; } }
-    public IEnumerable<string> Symbols { get { return allSymbols; } }
-
-    public Grammar(string startSymbol) {
+    public Grammar(ISymbol startSymbol) {
+      Debug.Assert(startSymbol != EmptySymbol);
       this.StartSymbol = startSymbol;
     }
 
-    public int NumberOfAlternatives(string ntSymbol) {
+    public int NumberOfAlternatives(ISymbol ntSymbol) {
       return rules[ntSymbol].Count;
     }
 
-    public IEnumerable<Sequence> GetAlternatives(string ntSymbol) {
+    public IEnumerable<Sequence> GetAlternatives(ISymbol ntSymbol) {
       return rules[ntSymbol].AsReadOnly();
     }
 
-    public Sequence GetAlternative(string ntSymbol, int index) {
+    public Sequence GetAlternative(ISymbol ntSymbol, int index) {
       return rules[ntSymbol][index];
     }
 
-    public void AddProductionRule(string ntSymbol, Sequence production) {
+    public void AddProductionRule(ISymbol ntSymbol, Sequence production) {
+      Debug.Assert(ntSymbol != EmptySymbol);
+
       List<Sequence> l;
       if (!rules.TryGetValue(ntSymbol, out l)) {
@@ -61,4 +64,7 @@
         allSymbols.Add(ntSymbol); // register new nt-symbol
       }
+      // check if the same production exists already
+      Debug.Assert(!l.Any(s => s.SequenceEqual(production)));
+
       l.Add(production);
 
@@ -66,7 +72,20 @@
     }
 
+    public bool IsTerminal(ISymbol symbol) {
+      return !rules.ContainsKey(symbol) && allSymbols.Contains(symbol);
+    }
+    public bool IsNonTerminal(ISymbol symbol) {
+      return rules.ContainsKey(symbol);
+    }
+
+    // checks if a rule exists for each NT symbol
+    public bool IsComplete() {
+      return rules.ContainsKey(StartSymbol) &&
+             NonTerminalSymbols.All(nt => rules.ContainsKey(nt));
+    }
+
     private static Regex ruleExpr = new Regex(@"\s*(?<ntSymbol>\w+)\s*->\s*(?<alternative>\w+(?:\s+\w+)*)(?:\s*\|\s*(?<alternative>\w+(?:\s+\w+)*))*");
     private static Regex empty = new Regex(@"^\s*$");
-    public static IGrammar FromString(string gStr) {
+    public static Grammar FromString(string gStr) {
       var lines = gStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
       lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines
@@ -74,16 +93,17 @@
       // first line is the rule for the start-symbol
       var m = ruleExpr.Match(lines.First());
-      var startSymbol = m.Groups["ntSymbol"].Value;
+      var startSymbol = new Symbol(m.Groups["ntSymbol"].Value);
       var g = new Grammar(startSymbol);
       foreach (var alt in m.Groups["alternative"].Captures) {
-        g.AddProductionRule(startSymbol, alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
+        g.AddProductionRule(startSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));
       }
       foreach (var line in lines.Skip(1)) {
         m = ruleExpr.Match(line);
-        var ntSymbol = m.Groups["ntSymbol"].Value;
+        var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value);
         foreach (var alt in m.Groups["alternative"].Captures) {
-          g.AddProductionRule(ntSymbol, alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
+          g.AddProductionRule(ntSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));
         }
       }
+
       return g;
     }
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/HeuristicLab.Grammars-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/HeuristicLab.Grammars-3.3.csproj	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/HeuristicLab.Grammars-3.3.csproj	(revision 10051)
@@ -7,5 +7,5 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{A5452B63-B33B-4F9F-9E81-98B75EDB5612}</ProjectGuid>
-    <OutputType>Library</OutputType>
+    <OutputType>Exe</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>HeuristicLab.Grammars</RootNamespace>
@@ -93,4 +93,7 @@
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
@@ -115,7 +118,12 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AttributedGrammar.cs" />
+    <Compile Include="Attribute.cs" />
+    <Compile Include="Sequence.cs" />
+    <Compile Include="Test.cs" />
+    <Compile Include="Symbol.cs" />
+    <Compile Include="Language.cs" />
     <Compile Include="Grammar.cs" />
     <Compile Include="Interfaces\IAttribute.cs" />
-    <Compile Include="Interfaces\IAttributedGrammar.cs" />
     <Compile Include="Interfaces\ISymbol.cs" />
     <Compile Include="Interfaces\IGrammar.cs" />
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttribute.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttribute.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttribute.cs	(revision 10051)
@@ -22,5 +22,5 @@
 namespace HeuristicLab.Grammars {
   public enum AttributeType { In, Out, Ref };
-  interface IAttribute {
+  public interface IAttribute {
     AttributeType AttributeType { get; }
     string Type { get; }
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttributedGrammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttributedGrammar.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IAttributedGrammar.cs	(revision 10051)
@@ -24,6 +24,16 @@
 namespace HeuristicLab.Grammars {
   interface IAttributedGrammar : IGrammar {
-    IEnumerable<IAttribute> GetAttributes(string symbol);
-    void AddAttribute(string symbol, IAttribute attribute);
+    ISymbol StartSymbol { get; set; }
+    IEnumerable<ISymbol> TerminalSymbols { get; }
+    IEnumerable<ISymbol> NonTerminalSymbols { get; }
+    IEnumerable<ISymbol> Symbols { get; }
+    bool IsTerminal(ISymbol symbol);
+    bool IsNonTerminal(ISymbol symbol);
+
+    int NumberOfAlternatives(ISymbol ntSymbol);
+    IEnumerable<Sequence> GetAlternatives(ISymbol ntSymbol);
+    Sequence GetAlternative(ISymbol ntSymbol, int index);
+
+    void AddProductionRule(ISymbol ntSymbol, Sequence production);
   }
 }
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IGrammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IGrammar.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/IGrammar.cs	(revision 10051)
@@ -23,17 +23,18 @@
 
 namespace HeuristicLab.Grammars {
-  using Sequence = IEnumerable<string>;
 
   public interface IGrammar {
-    string StartSymbol { get; set; }
-    IEnumerable<string> TerminalSymbols { get; }
-    IEnumerable<string> NonTerminalSymbols { get; }
-    IEnumerable<string> Symbols { get; }
+    ISymbol StartSymbol { get; set; }
+    IEnumerable<ISymbol> TerminalSymbols { get; }
+    IEnumerable<ISymbol> NonTerminalSymbols { get; }
+    IEnumerable<ISymbol> Symbols { get; }
+    bool IsTerminal(ISymbol symbol);
+    bool IsNonTerminal(ISymbol symbol);
 
-    int NumberOfAlternatives(string ntSymbol);
-    IEnumerable<Sequence> GetAlternatives(string ntSymbol);
-    Sequence GetAlternative(string ntSymbol, int index);
+    int NumberOfAlternatives(ISymbol ntSymbol);
+    IEnumerable<Sequence> GetAlternatives(ISymbol ntSymbol);
+    Sequence GetAlternative(ISymbol ntSymbol, int index);
 
-    void AddProductionRule(string ntSymbol, Sequence production);
+    void AddProductionRule(ISymbol ntSymbol, Sequence production);
   }
 }
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/ISymbol.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/ISymbol.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Interfaces/ISymbol.cs	(revision 10051)
@@ -20,10 +20,8 @@
 #endregion
 
-/*
 namespace HeuristicLab.Grammars {
-  interface ISymbol {
+  public interface ISymbol {
     string Name { get; }
-    bool IsTerminal { get; }
+    IAttribute Attribute { get; }
   }
 }
-*/
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Language.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Language.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Language.cs	(revision 10051)
@@ -0,0 +1,143 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.Grammars {
+
+  public class Language : IEnumerable<IEnumerable<string>> {
+    private class PartiallyProcessedSequence {
+      private Sequence terminalSeq;
+      private Sequence remainingSeq;
+      private IGrammar grammar;
+
+      private PartiallyProcessedSequence parent;
+      private PartiallyProcessedSequence(PartiallyProcessedSequence parent) {
+        this.parent = parent;
+        this.terminalSeq = new Sequence();
+      }
+
+      public PartiallyProcessedSequence(Sequence seq, IGrammar g) {
+        this.terminalSeq = new Sequence();
+        this.remainingSeq = seq;
+        this.grammar = g;
+      }
+      public bool ProcessToNextNonTerminal(out ISymbol ntSymbol) {
+        var enumerator = remainingSeq.GetEnumerator();
+        int i = 0;
+        while (enumerator.MoveNext() && grammar.IsTerminal(enumerator.Current)) {
+          terminalSeq.Add(enumerator.Current);
+          i++;
+        }
+        if (enumerator.Current == null) {
+          ntSymbol = null;
+          return false;
+        } else {
+          ntSymbol = enumerator.Current;
+
+          remainingSeq = new Sequence(remainingSeq.Skip(i + 1));
+          return true;
+        }
+      }
+      public PartiallyProcessedSequence CreateAlternativeSequence(Sequence seq) {
+        var p = new PartiallyProcessedSequence(this);
+        p.grammar = grammar;
+        p.remainingSeq = new Sequence(seq.Concat(remainingSeq));
+        return p;
+      }
+      public Sequence GetSequence() {
+        if (parent == null) return terminalSeq;
+        else {
+          return new Sequence(parent.GetSequence().Concat(terminalSeq));
+        }
+      }
+    }
+
+    private class LanguageEnumerator : IEnumerator<IEnumerable<string>> {
+      private IGrammar g;
+      private IEnumerable<string> currentSentence;
+      private Queue<PartiallyProcessedSequence> queue = new Queue<PartiallyProcessedSequence>();
+      public LanguageEnumerator(IGrammar g) {
+        this.g = g;
+        Reset();
+      }
+
+      public void Dispose() {
+        // nothing to do
+      }
+
+      public bool MoveNext() {
+        if (!queue.Any()) return false;
+
+        // iterate until a sequence with only non-terminals is found
+        do {
+          var f = queue.Dequeue();
+          ISymbol ntSymbol = null;
+          if (f.ProcessToNextNonTerminal(out ntSymbol) == true) {
+
+            // find first non-terminal and create chains for each alternative
+            foreach (var p in g.GetAlternatives(ntSymbol)) {
+              var chain = f.CreateAlternativeSequence(p);
+              queue.Enqueue(chain);
+            }
+          } else {
+            // only terminals in the chain => return as sentence
+            currentSentence = f.GetSequence().Select(symb => symb.Name);
+            return true;
+          }
+        } while (true);
+      }
+
+      public void Reset() {
+        queue.Clear();
+        foreach (var p in g.GetAlternatives(g.StartSymbol)) {
+          queue.Enqueue(new PartiallyProcessedSequence(p, g));
+        }
+      }
+
+      public IEnumerable<string> Current { get { return currentSentence; } }
+
+      object IEnumerator.Current {
+        get { return Current; }
+      }
+    }
+
+    private readonly IGrammar grammar;
+
+    public Language(IGrammar g) {
+      this.grammar = g;
+    }
+
+    public IEnumerator<IEnumerable<string>> GetEnumerator() {
+      return new LanguageEnumerator(grammar);
+    }
+
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Sequence.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Sequence.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Sequence.cs	(revision 10051)
@@ -0,0 +1,58 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Grammars {
+  public class Sequence : List<ISymbol> {
+    public Sequence()
+      : base() {
+    }
+
+    public Sequence(IEnumerable<ISymbol> seq)
+      : base() {
+      this.AddRange(seq);
+    }
+    public IEnumerator<ISymbol> GetEnumerator() {
+      return (IEnumerator<ISymbol>)base.GetEnumerator();
+    }
+
+    public override bool Equals(object obj) {
+      if (obj == this) return true;
+      Sequence other = obj as Sequence;
+      if (other == null || Count != other.Count) return false;
+      return this.SequenceEqual(other);
+    }
+
+    public override int GetHashCode() {
+      return this.Aggregate(0, (h, s) => h + s.GetHashCode());
+    }
+
+    public override string ToString() {
+      var b = new StringBuilder();
+      ForEach(s => b.AppendFormat("{0} ", s));
+      return b.ToString();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Symbol.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Symbol.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Symbol.cs	(revision 10051)
@@ -0,0 +1,50 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Grammars {
+  public class Symbol : ISymbol, IEquatable<ISymbol> {
+    public string Name { get; private set; }
+    public IAttribute Attribute { get; private set; }
+    public Symbol(string name, IAttribute attribute = null) {
+      this.Name = name;
+      this.Attribute = attribute;
+    }
+
+    public bool Equals(ISymbol other) {
+      return Name == other.Name;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj == null) return false;
+      if (obj == this) return true;
+      var other = obj as ISymbol;
+      if (other == null) return false;
+      return Equals(other);
+    }
+
+    public override int GetHashCode() {
+      return Name.GetHashCode();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Test.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Test.cs	(revision 10051)
+++ /branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Test.cs	(revision 10051)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Grammars {
+  public class Test {
+    public static void Main(string[] args) {
+      var gStr =
+        @"S -> a B | b A
+          A-> a | a S | b A A 
+          B -> b | b S | a B B
+         ";
+      var g = HeuristicLab.Grammars.Grammar.FromString(gStr);
+      var l = new Language(g);
+      var s2 = new string[][]
+        {
+          new string[] {"a", "b"},
+          new string[] {"b", "a"}
+        };
+      var s4 = new string[][]
+        {
+          new string[] {"a", "a", "b", "b"},
+          new string[] {"a", "b", "a", "b"},
+          new string[] {"a", "b", "b", "a"},
+          new string[] {"b", "b", "a", "a"},
+          new string[] {"b", "a", "b", "a"},
+          new string[] {"b", "a", "a", "b"}
+        };
+
+      var watch = new Stopwatch();
+      watch.Start();
+      var lPrime = l.Take(100000);
+      int s = 0;
+      foreach (var c in lPrime) {
+        s++;
+        /*
+        foreach (var symb in c)
+          Console.Write(symb);
+        Console.WriteLine();
+        */
+      }
+      watch.Stop();
+      Console.WriteLine(s);
+      Console.WriteLine("Generating 10000 sentences: {0}ms", watch.ElapsedMilliseconds);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GPDL/Test/Test.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/Test/Test.csproj	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/Test/Test.csproj	(revision 10051)
@@ -22,5 +22,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\trunk\sources\bin\</OutputPath>
+    <OutputPath>..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -128,4 +128,8 @@
       <Name>HeuristicLab.Grammars-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Problems.GPDL.CodeGen\3.4\HeuristicLab.Problems.GPDL.CodeGen-3.4.csproj">
+      <Project>{F8481248-2A5B-48A0-A485-D3E1619C1E44}</Project>
+      <Name>HeuristicLab.Problems.GPDL.CodeGen-3.4</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Problems.GPDL.Views\3.4\HeuristicLab.Problems.GPDL.Views-3.4.csproj">
       <Project>{3f9e665a-3dcb-49c3-8806-0e47fc48ea52}</Project>
Index: /branches/HeuristicLab.Problems.GPDL/Test/TestGpdlExamples.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/Test/TestGpdlExamples.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/Test/TestGpdlExamples.cs	(revision 10051)
@@ -27,4 +27,5 @@
 using HeuristicLab.Algorithms.GeneticAlgorithm;
 using HeuristicLab.Problems.GPDL;
+using HeuristicLab.Problems.GPDL.CodeGen;
 using HeuristicLab.Problems.GPDL.Views;
 using HeuristicLab.SequentialEngine;
@@ -41,5 +42,5 @@
         Parser parser = new Parser(scanner);
         parser.Parse();
-        Assert.IsNotNull(parser.problem);
+        Assert.IsNotNull(parser.AbstractSyntaxTree);
 
         // test: run one generation
@@ -48,5 +49,7 @@
         ga.PopulationSize.Value = 100;
         ga.MaximumGenerations.Value = 1;
-        ga.Problem = parser.problem;
+
+        var problemGenerator = new ProblemGenerator();
+        ga.Problem = problemGenerator.GenerateFromAst(parser.AbstractSyntaxTree);
 
         var wh = new AutoResetEvent(false);
Index: /branches/HeuristicLab.Problems.GPDL/Test/TestGrammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GPDL/Test/TestGrammar.cs	(revision 10050)
+++ /branches/HeuristicLab.Problems.GPDL/Test/TestGrammar.cs	(revision 10051)
@@ -20,4 +20,6 @@
 #endregion
 
+using System;
+using System.Collections.Generic;
 using System.Linq;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -31,16 +33,83 @@
         @"S -> A
           A->a B
-          B ->S b | S a|B b 
-          B-> a  aa   aaa
+          B ->S b | S a|C b 
+          C-> a  aa   aaa
          ";
       var g = HeuristicLab.Grammars.Grammar.FromString(gStr);
-      Assert.AreEqual(g.StartSymbol, "S");
+      Assert.AreEqual(g.StartSymbol, new Symbol("S"));
       Assert.AreEqual(g.TerminalSymbols.Count(), 4);
-      Assert.AreEqual(g.NonTerminalSymbols.Count(), 3);
-      Assert.IsTrue(g.TerminalSymbols.Contains("aaa"));
-      Assert.IsTrue(g.TerminalSymbols.Contains("aa"));
-      Assert.IsTrue(g.NonTerminalSymbols.Contains("S"));
-      Assert.IsTrue(g.NonTerminalSymbols.Contains("B"));
-      Assert.IsTrue(g.NonTerminalSymbols.Contains("A"));
+      Assert.AreEqual(g.NonTerminalSymbols.Count(), 4);
+      Assert.IsTrue(g.TerminalSymbols.Contains(new Symbol("aaa")));
+      Assert.IsTrue(g.TerminalSymbols.Contains(new Symbol("aa")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("S")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("B")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("C")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("A")));
+    }
+
+
+    [TestMethod]
+    public void TestAttributedGrammar() {
+      var gStr =
+        @"S -> A
+          A<int a0, out int a1>->a B<a0, a1>
+          B<int a0, ref int a1> ->S b | S a|C<a0, a1> b 
+          C<int a0, ref int a1> -> a  aa   aaa
+         ";
+      var g = HeuristicLab.Grammars.AttributedGrammar.FromString(gStr);
+      Assert.AreEqual(g.StartSymbol, new Symbol("S"));
+      Assert.AreEqual(g.TerminalSymbols.Count(), 4);
+      Assert.AreEqual(g.NonTerminalSymbols.Count(), 4);
+      Assert.IsTrue(g.TerminalSymbols.Contains(new Symbol("aaa")));
+      Assert.IsTrue(g.TerminalSymbols.Contains(new Symbol("aa")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("S")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("B")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("A")));
+      Assert.IsTrue(g.NonTerminalSymbols.Contains(new Symbol("C")));
+    }
+
+
+    [TestMethod]
+    public void TestLanguage() {
+      var gStr =
+        @"S -> a B | b A
+          A-> a | a S | b A A 
+          B -> b | b S | a B B
+         ";
+      var g = HeuristicLab.Grammars.Grammar.FromString(gStr);
+      var l = new Language(g);
+      var s2 = new string[][]
+        {
+          new string[] {"a", "b"},
+          new string[] {"b", "a"}
+        };
+      var s4 = new string[][]
+        {
+          new [] {"a", "a", "b", "b"},
+          new [] {"a", "b", "a", "b"},
+          new [] {"a", "b", "b", "a"},
+          new [] {"b", "b", "a", "a"},
+          new [] {"b", "a", "b", "a"},
+          new [] {"b", "a", "a", "b"}
+        };
+
+
+      var l2 = l.Where(s => s.Count() == 2).Take(2);
+      var l4 = l.Where(s => s.Count() == 4).Take(6);
+
+      Assert.IsTrue(l2.Intersect(s2, new SequenceComparer()).Count() == l2.Count());
+      Assert.IsTrue(l4.Intersect(s4, new SequenceComparer()).Count() == l4.Count());
+    }
+  }
+
+  public class SequenceComparer : IEqualityComparer<IEnumerable<string>> {
+    public bool Equals(IEnumerable<string> x, IEnumerable<string> y) {
+      return x.Count() == y.Count() &&
+        x.Zip(y, (s, t) => s == t).All(eq => eq);
+    }
+
+    public int GetHashCode(IEnumerable<string> obj) {
+      if (!obj.Any()) return 0;
+      else return obj.First().GetHashCode();
     }
   }
