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; }
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; }
public InverseKeyType(NonTerminalObject[] p, int h, bool isStart) { Production = p.Select(nonterminal => new NonTerminalObject(nonterminal)).ToArray(); HeadPosition = h; IsStartSymbol = isStart; }
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); } }
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; }