예제 #1
0
        private bool IsCompletedTermConsistentWithNextTerm(NonTerminalObject completedTerm, NonTerminalObject nextTerm,
                                                           out NonTerminalStack intersection)
        {
            intersection = null;
            if (nextTerm == null)
            {
                return(false);
            }
            //the above case happens where the rule to be continued is already completed at the start column (next term = null).
            //this can only happen in a single case: that rule was an epsilon rule.

            if (completedTerm.NonTerminal != nextTerm.NonTerminal)
            {
                return(false);
            }

            if (nextTerm.Stack == null && completedTerm.Stack == null)
            {
                return(true);
            }

            var intersectAlgo = new StackGraphIntersect();

            intersection = intersectAlgo.Execute(nextTerm.Stack, completedTerm.Stack);

            return(intersection != null);
        }
예제 #2
0
 public NonTerminalObject(NonTerminalObject otherNonTerminalObject)
 {
     NonTerminal = otherNonTerminalObject.NonTerminal;
     if (otherNonTerminalObject.Stack != null)
     {
         Stack = otherNonTerminalObject.Stack; //shallow copy
     }
 }
예제 #3
0
파일: Rule.cs 프로젝트: JosephPotashnik/LIG
 public Rule(Rule otherRule)
 {
     Name               = new NonTerminalObject(otherRule.Name);
     Production         = otherRule.Production.Select(nonterminal => new NonTerminalObject(nonterminal)).ToArray();
     HeadPosition       = otherRule.HeadPosition;
     ComplementPosition = otherRule.ComplementPosition;
     Number             = otherRule.Number;
     Occurrences        = otherRule.Occurrences;
 }
예제 #4
0
파일: Rule.cs 프로젝트: JosephPotashnik/LIG
 public Rule(int occurrences, string name, string[] prod, int headPos = 0, int compPos = 1, int num = -1)
 {
     Name = new NonTerminalObject(name);
     if (prod != null)
     {
         Production = prod.Select(nonterminal => new NonTerminalObject(nonterminal)).ToArray();
     }
     HeadPosition       = headPos;
     ComplementPosition = compPos;
     Number             = num;
     Occurrences        = occurrences;
 }
예제 #5
0
        private RuleConsistentWithDerivation IsPredictedRuleConsistentWithCurrentDerivation(
            NonTerminalObject currObject, Rule rule)
        {
            //TODO: change later to skip -all- rules whose derivation leads to the empty string.
            //I.e,  A-> B.C , C -> D E. D -> epsilon, E -> epsilon. C itself is not an epsilon rule.

            //1. states that are the result of a spontenous dot shift (due to nullable production)
            //have already been added to the agendas in Column.Add()
            if (rule.IsEpsilonRule() && Grammar.nullableProductions.ContainsKey(currObject))
            {
                return(RuleConsistentWithDerivation.SkipGeneration);
            }

            //2. if current stack is empty but predicted stack is not, mismatch - do not predict this rule.
            if (currObject.IsStackEmpty() && !rule.IsInitialOrDotStack())
            {
                return(RuleConsistentWithDerivation.RuleInconsistent);
            }

            if (rule.IsInitialRule())
            {
                var complementPositionObject = rule.Production[rule.ComplementPosition];

                //3. if current stack is not empty, but the complement position does not allow for stacks (POS),
                //mismatch - do not predict this rule.
                if (!currObject.IsStackEmpty() && Grammar.IsPOS(complementPositionObject.NonTerminal))
                {
                    return(RuleConsistentWithDerivation.RuleInconsistent);
                }
            }
            else
            {
                //4. if tops of the stacks do not match, continue. e.g created rule PP[PP] -> epsilon, current object: PP[NP].
                if (rule.Name.Stack.Peek() != "." &&
                    !currObject.Stack.GetListOfTopSymbols().Contains(rule.Name.Stack.Peek()))
                {
                    return(RuleConsistentWithDerivation.RuleInconsistent);
                }
            }
            return(RuleConsistentWithDerivation.RuleConsistent);
        }
예제 #6
0
        private void Predict(Column col, List <Rule> ruleList, State state, NonTerminalObject currObject)
        {
            //if (generator)
            //{
            //    var rule = Grammar.GetRandomRuleForAGivenLHS(currObject.NonTerminal, Grammar.Rules[currObject.NonTerminal]);
            //    ruleList = new List<Rule> { rule };
            //}

            //var preds = GenerateSetOfPredictions();

            if (generator)
            {
                Rule rule = null;

                var l             = Grammar.Rules[currObject.NonTerminal];
                var feasibleRules = new List <Rule>();

                //when generating, predict only rules that terminate the derivation successfully.
                foreach (var candidate in l)
                {
                    var c = IsPredictedRuleConsistentWithCurrentDerivation(currObject, candidate);
                    if (c == RuleConsistentWithDerivation.SkipGeneration)
                    {
                        return;
                    }

                    //temporary: do not push another symbol if the current stack already contains a symbol
                    //in other words: allow only one symbol.
                    var complementPositionObject = candidate.Production[candidate.ComplementPosition];
                    var isPushRule = !complementPositionObject.IsStackEmpty() &&
                                     complementPositionObject.Stack.Top != Grammar.Epsilon;


                    if (!currObject.IsStackEmpty() && isPushRule)
                    {
                        continue;
                    }

                    if (c == RuleConsistentWithDerivation.RuleConsistent)
                    {
                        feasibleRules.Add(candidate);
                    }
                }

                if (feasibleRules.Count == 0) //no feasible rules to predict
                {
                    return;
                }

                rule     = Grammar.GetRandomRuleForAGivenLHS(currObject.NonTerminal, feasibleRules);
                ruleList = new List <Rule> {
                    rule
                };
            }

            foreach (var rule in ruleList)
            {
                if (IsPredictedRuleConsistentWithCurrentDerivation(currObject, rule) !=
                    RuleConsistentWithDerivation.RuleConsistent)
                {
                    continue;
                }

                //prepare new rule based on the stack information contained in the current state
                //and based on the predicted rule.
                var createdRule = new Rule(rule);

                //if the rule is not a stack manipulating rule,
                if (rule.IsInitialRule())
                {
                    var complementPositionObject = createdRule.Production[createdRule.ComplementPosition];
                    //the stack of the LHS of the created rule is the stack of the current object:
                    createdRule.Name = currObject;
                    //copy the stack to the complement position.
                    complementPositionObject.Stack = currObject.Stack;
                }
                else
                {
                    //create left hand side of new rule.
                    createdRule.Name.Stack       = currObject.Stack;
                    createdRule.Name.NonTerminal = currObject.NonTerminal;

                    //create right hand side of new rule.
                    NonTerminalStack contentOfDot;
                    if (rule.Name.Stack.Peek() == ".")
                    {
                        contentOfDot = currObject.Stack; //e.g. A[..]
                    }
                    else
                    {
                        contentOfDot = currObject.Stack.GetPrefixListStackObjectOfGivenTop(rule.Name.Stack.Peek());
                    }
                    //e.g A[..X]

                    for (var i = 0; i < rule.Production.Length; i++)
                    {
                        var s = rule.Production[i].Stack;

                        if (s != null)
                        {
                            if (s.Peek() == ".")
                            {
                                createdRule.Production[i].Stack = contentOfDot; // e.g, A[..] pop rule.
                            }
                            else if (s.PrefixList == null)
                            {
                                createdRule.Production[i].Stack = s; //e.g. A[X] //secondary constituent.
                            }
                            else
                            {
                                createdRule.Production[i].Stack = new NonTerminalStack(s.Peek(), contentOfDot);
                            }
                            //e.g. A[..X] - push rule.

                            //calculate the new weight of the top of the stack from the weights of its sons.
                            //if (createdRule.Production[i].Stack != null)
                            //    createdRule.Production[i].Stack.Weight = createdRule.Production[i].Stack.PrefixList != null ? createdRule.Production[i].Stack.PrefixList.Sum(x => x.Weight) : 1;
                        }
                    }
                }

                var newState = new State(createdRule, 0, col, null)
                {
                    LogProbability = ruleLogProbabilities[rule.Number]
                };

                if (newState.LogProbability < 0)
                {
                    throw new Exception("wrong probability");
                }

                var added = col.AddState(newState, ParsingOperation.Predict);

                if (Debug)
                {
                    Console.WriteLine("{0} & {1} & {2} & Predicted from State {3}, added: {4}\\\\", newState.StateNumber,
                                      newState,
                                      col.Index, state.StateNumber, added);
                }
            }
        }
예제 #7
0
        private HashSet <NonTerminalObject> GenerateSetOfPredictions(int maxElementsInStack = 2)
        {
            Queue <NonTerminalObject>   queue = new Queue <NonTerminalObject>();
            HashSet <NonTerminalObject> visitedNonTerminalObjects = new HashSet <NonTerminalObject>(new NonTerminalObjectStackComparer());

            NonTerminalObject o = null;

            foreach (var moveable in Grammar.Moveables)
            {
                o       = new NonTerminalObject(moveable);
                o.Stack = new NonTerminalStack(moveable);
                queue.Enqueue(o);
            }

            while (queue.Any())
            {
                var rhs = queue.Dequeue();
                visitedNonTerminalObjects.Add(rhs);

                var rulesforRHS = Grammar.RHSDictionary[rhs.NonTerminal].ToList();
                foreach (var item in rulesforRHS)
                {
                    o = null;
                    var rule        = Grammar.ruleNumberDictionary[item.Item1];
                    int RHSPosition = item.Item2;
                    if (rule.Name.NonTerminal == Grammar.StartSymbol)
                    {
                        continue;
                    }

                    if (rule.IsInitialRule())
                    {
                        if (rule.ComplementPosition == RHSPosition)
                        {
                            o       = new NonTerminalObject(rule.Name.NonTerminal);
                            o.Stack = new NonTerminalStack(rhs.Stack);
                            if (!visitedNonTerminalObjects.Contains(o))
                            {
                                queue.Enqueue(o);
                            }
                        }
                    }
                    else
                    {
                        NonTerminalStack contentOfDot;

                        var s = rule.Production[RHSPosition].Stack;
                        if (s != null)
                        {
                            if (s.Peek() == ".")
                            {
                                contentOfDot = rhs.Stack;
                            }
                            else if (s.PrefixList != null)
                            {
                                contentOfDot = rhs.Stack.GetPrefixListStackObjectOfGivenTop(rhs.Stack.Peek());
                            }
                            else
                            {
                                continue;
                            }
                            //assumption: if this is a secondary constituent (i.e, s.PrefixList == null), does not participate in the sharing of stacks,
                            //the LHS will be handled through the primary constituent (the distinguished descendant).


                            o = new NonTerminalObject(rule.Name.NonTerminal);
                            if (rule.Name.Stack.Peek() == ".")
                            {
                                if (contentOfDot != null)
                                {
                                    o.Stack = new NonTerminalStack(contentOfDot);
                                }
                            }
                            else
                            {
                                if (contentOfDot == null || contentOfDot.Depth() < maxElementsInStack)
                                {
                                    o.Stack = new NonTerminalStack(rule.Name.Stack.Peek(), contentOfDot);
                                }
                            }
                            if (o.Stack != null && !visitedNonTerminalObjects.Contains(o))
                            {
                                queue.Enqueue(o);
                            }
                        }
                    }
                }
            }

            return(visitedNonTerminalObjects);
        }