示例#1
0
 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;
 }
示例#2
0
 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;
 }
示例#3
0
 public InverseKeyType(NonTerminalObject[] p, int h, bool isStart)
 {
     Production = p.Select(nonterminal => new NonTerminalObject(nonterminal)).ToArray();
     HeadPosition = h;
     IsStartSymbol = isStart;
 }
示例#4
0
        private void Predict(Column col, List<Rule> ruleList, State state, NonTerminalObject currObject)
        {
            if (generator)
            {
                var rule = Grammar.GetRandomRuleForAGivenLHS(currObject.NonTerminal, true);
                ruleList = new List<Rule> {rule};
            }

            foreach (var rule in ruleList)
            {
                //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.
                if (rule.IsEpsilonRule() && Grammar.nullableProductions.ContainsKey(currObject))
                {
                    //states that are the result of a spontenous dot shift (due to nullable production) 
                    //have already been added to the agendas in Column.Add()
                    continue;
                }


                //if current stack is empty but predicted stack is not, mismatch - do not predict this rule.
                if (currObject.IsStackEmpty() && !rule.IsInitialOrDotStack()) 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];

                    //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)) continue;

                    //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
                {
                    if (createdRule.Name.Stack.Peek() != "." && currObject.Stack.Top != Grammar.Epsilon &&
                        currObject.Stack.Top != createdRule.Name.Stack.Peek())
                        continue;
                    //if tops of the stacks do not match, continue. e.g created rule PP[PP] -> epsilon, current object: PP[NP].

                    //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);
            }
        }
示例#5
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;

            NonTerminalStack arg1 = null;
            //deep copy the stacks in order not to alter the graphs of past stacks.
            if (nextTerm.Stack != null)
                arg1 = new NonTerminalStack(nextTerm.Stack, true);
            NonTerminalStack arg2 = null;
            if (completedTerm.Stack != null)
                arg2 = new NonTerminalStack(completedTerm.Stack, true);

            intersection = NonTerminalStack.Intersect(arg1, arg2, new HashSet<NonTerminalStack>(),
                new HashSet<NonTerminalStack>(),
                new Dictionary<NonTerminalStack, HashSet<NonTerminalStack>>());
            return intersection != null;
        }