예제 #1
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);
        }
예제 #2
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);
                }
            }
        }