예제 #1
0
 public CYKTable(A[] word, PerformanceCFG cfg)
 {
     this.word = word;
     this.cfg  = cfg;
     InitializeCykTable();
     CalculateEpsilonSymbols();
     if (word.Length > 0)
     {
         FillTable();
     }
 }
예제 #2
0
 /// <summary>
 /// builds a filled CYK-table out of the cfg
 /// </summary>
 /// <param name="word"></param>
 /// <param name="cfg">cfg in 2NF</param>
 public CYKTable(A[] word, ContextFreeGrammar cfg)
 {
     this.word = word;
     this.cfg  = new PerformanceCFG(cfg);
     InitializeCykTable();
     CalculateEpsilonSymbols();
     if (word.Length > 0)
     {
         FillTable();
     }
 }
예제 #3
0
        private static void AddChainAndEpsilonEntriesForNextEntry(Dictionary <int, DerivationNode <A> > entries, PerformanceCFG cfg, Dictionary <int, DerivationNode <A> > epsilonSymbols, Queue <DerivationNode <A> > newEntries)
        {
            var next = newEntries.Dequeue();
            var productionsWithNextOnRightHandsSide = cfg.GetProductionsWhereRightHandSideContains(next.Symbol);

            foreach (var prod in productionsWithNextOnRightHandsSide)
            {
                //only add new entries; so maybe not all derivations are found, but only one is needed
                if (!entries.ContainsKey(prod.Lhs.UnqiueId))
                {
                    AddChainAndEpsilonEntriesForProduction(entries, epsilonSymbols, newEntries, next, prod);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// adds to the given dictionary recursively all entries, that have a production with only epsilon-symbols on the right hand side, except exactly one of the symbols in entries
        /// </summary>
        /// <param name="entries"></param>
        /// <param name="cfg"></param>
        /// <param name="epsilonSymbols">symbols, that can reach epsilon without derivate a letter</param>
        internal static void AddChainAndEpsilonEntries(Dictionary <int, DerivationNode <A> > entries, PerformanceCFG cfg, Dictionary <int, DerivationNode <A> > epsilonSymbols)
        {
            var newEntries = new Queue <DerivationNode <A> >(entries.Values);

            while (newEntries.Count > 0)
            {
                AddChainAndEpsilonEntriesForNextEntry(entries, cfg, epsilonSymbols, newEntries);
            }
        }
예제 #5
0
        /// <summary>
        /// creats an entry for the given CYK-table at the defined position
        /// </summary>
        /// <param name="cykTable"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <param name="epsilonSymbols"></param>
        /// <param name="cfg"></param>
        /// <returns></returns>
        public static TableField <A> CreateTableFieldForCYKTable(TableField <A>[][] cykTable, int row, int column, Dictionary <int, DerivationNode <A> > epsilonSymbols, PerformanceCFG cfg)
        {
            var entries = new Dictionary <int, DerivationNode <A> >();

            for (int i = 0; i < row; i++)
            {
                CombineTwoTableFields(entries, cykTable[i][column], cykTable[row - i - 1][column + i + 1], epsilonSymbols, cfg);
            }
            return(new TableField <A>(entries, epsilonSymbols, cfg));
        }
예제 #6
0
 private static void CombineTwoTableFields(Dictionary <int, DerivationNode <A> > entries, TableField <A> left, TableField <A> right, Dictionary <int, DerivationNode <A> > epsilonSymbols, PerformanceCFG cfg)
 {
     foreach (var prod in cfg.BinaryProductions)
     {
         if (left.Entries.TryGetValue(prod.Rhs[0].UnqiueId, out DerivationNode <A> leftNode))
         {
             if (right.Entries.TryGetValue(prod.Rhs[1].UnqiueId, out DerivationNode <A> rightNode))
             {
                 if (!entries.ContainsKey(prod.Lhs.UnqiueId))
                 {
                     entries.Add(prod.Lhs.UnqiueId, new DerivationNode <A>(prod, new List <DerivationNode <A> >()
                     {
                         leftNode, rightNode
                     }));
                 }
             }
         }
     }
 }
예제 #7
0
        /// <summary>
        /// creates an entry with a single terminal
        /// </summary>
        /// <param name="terminal"></param>
        /// <param name="epsilonSymbols"></param>
        /// <param name="cfg"></param>
        /// <returns></returns>
        public static TableField <A> WithTerminal(Exprinal <A> terminal, Dictionary <int, DerivationNode <A> > epsilonSymbols, PerformanceCFG cfg)
        {
            var entries = new Dictionary <int, DerivationNode <A> >
            {
                { terminal.UnqiueId, new DerivationNode <A>(terminal) }
            };

            return(new TableField <A>(entries, epsilonSymbols, cfg));
        }
예제 #8
0
 private TableField(Dictionary <int, DerivationNode <A> > entries, Dictionary <int, DerivationNode <A> > epsilonSymbols, PerformanceCFG cfg)
 {
     Entries = entries;
     CFGChainExtender <A> .AddChainAndEpsilonEntries(entries, cfg, epsilonSymbols);
 }