static public Predicate CreatePredicate(TFTreeNode <ParseTreeNodeData> node, out string error) { Predicate predicate = null; if (node.Children.Count < 1 || node.Children[0].Data.TheGoal.Symbol.TheSymbol == "Word") { Atom functor; if (node.Children.Any()) { if (node.Children[0].Data.Lexemes[0] == "true") { ; } functor = new Atom(node.Children[0].Data.Lexemes[0]); } else { functor = new Atom(node.Data.Lexemes[0]); } if (node.Children.Count > 1) { predicate = new Predicate(functor, new Term[node.Children.Count - 1]); } else { predicate = new Predicate(functor); } int count = 0; foreach (TFTreeNode <ParseTreeNodeData> childNode in node.Children.Skip(1)) { if (childNode.Data.TheGoal.Symbol.TheSymbol == "RelSent") { predicate.Arguments[count] = CreatePredicate(childNode, out error); if (predicate.Arguments[count] == null) { return(null); } } else if (childNode.Data.TheGoal.Symbol.TheSymbol == "Variable") { predicate.Arguments[count] = new Variable(childNode.Data.Lexemes[0].Substring(1, 1).ToUpper() + childNode.Data.Lexemes[0].Substring(2)); } else if (childNode.Data.TheGoal.Symbol.TheSymbol == "Word") { predicate.Arguments[count] = new Atom(childNode.Data.Lexemes[0]); } else if (childNode.Data.TheGoal.Symbol.TheSymbol == "Number") { predicate.Arguments[count] = new Number(childNode.Data.Lexemes[0]); } // ToDo: What do I do with quoted strings? count++; } } else { error = "First child of a Predicate is not a Word"; return(null); } error = String.Empty; return(predicate); }
public bool NewProcess(List <Token> input, int level, Stack <Goal> goalStack, Stack <RuleRange> ruleRangeStack, Stack <RuleInputMap> ruleInputMapStack, TFTreeNode <ParseTreeNodeData> parentParseTreeNode, TFTreeNode <Rule> ruleNode, StringBuilder debugOut, RuleCollection ruleCollection) { if (visitCount++ == 10000) { visitCount++; } try { string levelString = new string(Enumerable.Repeat(' ', level * 8).ToArray()); var goalEnterTime = Stopwatch.GetTimestamp(); goalStack.Push(this); int origGoalStackSize = goalStack.Count; var rules = ruleCollection.FindByLHS(Symbol); foreach (Rule rule in rules) { var ruleRange = new RuleRange(rule, InputPos, Length); var newRuleNode = ruleNode.AddNewChild(rule); ruleRangeStack.Push(ruleRange); int origRuleRangeStackSize = ruleRangeStack.Count; int origRuleInputMapStackSize = ruleInputMapStack.Count; #if DEBUG_OUT textBox1.AppendText(Environment.NewLine); textBox1.AppendText(levelString + "-----------------------------------------------------"); textBox1.AppendText(Environment.NewLine); textBox1.AppendText(levelString + rule); textBox1.AppendText(Environment.NewLine); textBox1.AppendText(levelString + "-----------------------------------------------------"); textBox1.AppendText(Environment.NewLine); #endif var ruleInputMapper = new RuleInputMapper(rule, InputPos, Length); foreach (List <int> ruleInputMap in ruleInputMapper.GetInputMap()) { ruleInputMapStack.Push(new RuleInputMap(ruleInputMap, InputPos)); // do a little preprocessing to see if we can quit this ruleInputMap earlier int symbolCount = 0; int currentPos = InputPos; foreach (int u in ruleInputMap) { if (rule.RHS[symbolCount].IsTerminal) { #if USE_TOKENTYPE_IN_SYMBOL if (u != 1 || rule.RHS[symbolCount].TheTokenType != input[currentPos].TheTokenType) #else if (u != 1 || rule.RHS[symbolCount].TheSymbol != input[currentPos].) #endif { goto NextRuleInputMap; } } if (!rule.RHS[symbolCount].IsTerminal && u < 1) { goto NextRuleInputMap; } /* * if (!rule.RHS[symbolCount].IsTerminal || u != 1) * { * goto NextRuleInputMap; * } * * if (rule.RHS[symbolCount].TheTokenType == TokenType.None) // this is a specific string in the rule * { * if (input[currentPos].TheTokenType != TokenType.String || input[currentPos].Lexeme != rule.RHS[symbolCount].TheSymbol) * { * goto NextRuleInputMap; * } * } * else if (rule.RHS[symbolCount].TheTokenType != input[currentPos].TheTokenType) * { * goto NextRuleInputMap; * } */ currentPos += u; symbolCount++; } symbolCount = 0; currentPos = InputPos; foreach (int u in ruleInputMap) { var newGoal = new Goal(rule.RHS[symbolCount], currentPos, u); if (rule.RHS[symbolCount].IsTerminal) { string subInput = null; if (u != 0) { subInput = input[currentPos].ToString(); } #if DEBUG_OUT textBox1.AppendText(levelString + String.Format("{0}{1}-->{2} (input/symbol mapping)", (symbolCount == 0 ? "" : ", "), rule.RHS[symbolCount].TheSymbol ?? "\u0190", subInput)); #endif if (rule.RHS[symbolCount].TheTokenType == TokenType.None && input[currentPos].TheTokenType == TokenType.String && input[currentPos].Lexeme == rule.RHS[symbolCount].TheSymbol) { #if DEBUG_OUT textBox1.AppendText(levelString + "TERMINAL MATCH ON TEXT!!" + Environment.NewLine); #endif var newNodeData = new ParseTreeNodeData(newGoal, ruleRange); newNodeData.Lexemes.Add(input[currentPos].Lexeme); newNodeData.IsAMatch = true; var newNode = new TFTreeNode <ParseTreeNodeData>(newNodeData); parentParseTreeNode.AddChild(newNode); } else if (rule.RHS[symbolCount].TheTokenType != TokenType.None && rule.RHS[symbolCount].TheTokenType == input[currentPos].TheTokenType) { #if DEBUG_OUT textBox1.AppendText(levelString + "TERMINAL MATCH ON TOKEN!!" + Environment.NewLine); #endif parentParseTreeNode.Data.Lexemes.Add(input[currentPos].Lexeme); var newNodeData = new ParseTreeNodeData(newGoal, ruleRange); newNodeData.Lexemes.Add(input[currentPos].Lexeme); newNodeData.IsAMatch = true; var newNode = new TFTreeNode <ParseTreeNodeData>(newNodeData); parentParseTreeNode.AddChild(newNode); } else { #if DEBUG_OUT textBox1.AppendText(levelString + "TERMINAL NO MATCH!!" + Environment.NewLine); #endif #if INCLUDE_UNSUCCESSFUL_NODES_IN_PARSE_TREE var newNodeData = new ParseTreeNodeData(newGoal, ruleRange); newNodeData.Lexemes.Add(input[currentPos].Lexeme); var newNode = new TFTreeNode <ParseTreeNodeData>(newNodeData); parentParseTreeNode.AddChild(newNode); #endif goto NextRuleInputMap; } } else { try { var newNodeData = new ParseTreeNodeData(newGoal, ruleRange); var newNode = new TFTreeNode <ParseTreeNodeData>(newNodeData); parentParseTreeNode.AddChild(newNode); if (!newGoal.NewProcess(input, level + 1, goalStack, ruleRangeStack, ruleInputMapStack, newNode, newRuleNode, debugOut, ruleCollection)) { #if INCLUDE_UNSUCCESSFUL_NODES_IN_PARSE_TREE #else parentParseTreeNode.RemoveChild(newNode); #endif // if we fail at any part of a rule input map we have failed the whole thing)) goto NextRuleInputMap; } foreach (string lexeme in newNode.Data.Lexemes) { parentParseTreeNode.Data.Lexemes.Add(lexeme); } } catch (Exception) { ; } } currentPos += u; symbolCount++; } // if we've arrived here we have a recognized ruleInputMap for this range of input for our grammar parentParseTreeNode.Data.TimeInNode = (long)Math.Truncate(((decimal)Stopwatch.GetTimestamp() - (decimal)goalEnterTime) * 1000000.0m / Stopwatch.Frequency); parentParseTreeNode.Data.IsAMatch = true; return(true); NextRuleInputMap: ruleInputMapStack.SetNewSize(origRuleInputMapStackSize); ruleRangeStack.SetNewSize(origRuleRangeStackSize); // Since we could have generated goals on the goal stack that were successful but // not all of the goals for that rule input map were successful we need to pop off those // successful goals. goalStack.SetNewSize(origGoalStackSize); } ruleRangeStack.Pop(); } #if DEBUG_OUT textBox1.AppendText(levelString + "-----------------------------------------------------"); textBox1.AppendText(Environment.NewLine); #endif goalStack.Pop(); //GC.Collect(); return(false); } catch (Exception ex) { //var numNodes = parentNode.Root.GetDepthFirstEnumerable(TreeTraversalDirection.TopDown).Count(); throw; } }
static public HornClause CreateHornClause(TFTreeNode <ParseTreeNodeData> node, out string error) { HornClause hornClause = null; Predicate head = null; Predicate[] body = null; if (node.Data.TheGoal.Symbol.TheSymbol == "LogSent") { // a LogSent will become a rule if (node.Children.Count < 2) { error = "LogSent has fewer than two children"; return(null); } if (node.Children[0].Data.TheGoal.Symbol.TheSymbol != "ImplicationToLeft") { error = "First child of LogSent is not ImplicationToLeft"; return(null); } if (node.Children[1].Data.TheGoal.Symbol.TheSymbol != "RelSent" && node.Children[1].Data.TheGoal.Symbol.TheSymbol != "Word") { error = "Second child of LogSent is not RelSent or Word"; return(null); } else { head = CreatePredicate(node.Children[1], out error); if (head == null) { return(null); } if (head.Functor.ToString() == "next") { ; } body = new Predicate[node.Children.Count - 2]; hornClause = new HornClause(head, body); } int count = 0; foreach (TFTreeNode <ParseTreeNodeData> childNode in node.Children.Skip(2)) { if (childNode.Data.TheGoal.Symbol.TheSymbol != "RelSent" && childNode.Data.TheGoal.Symbol.TheSymbol != "Word") { error = "A child of LogSent is not RelSent or Word"; return(null); } else { hornClause.Body[count] = CreatePredicate(node.Children[count + 2], out error); if (hornClause.Body[count] == null) { return(null); } } count++; } } else if (node.Data.TheGoal.Symbol.TheSymbol == "RelSent") { // a RelSent will become a fact if (node.Children.Count < 1) { error = "RelSent doesn't have any children"; return(null); } head = CreatePredicate(node, out error); if (head == null) { return(null); } hornClause = new HornClause(head); } else { error = "HornClause does not have either a LogSent or RelSent"; return(null); } hornClause = hornClause.RemoveFunctor(new Atom("true")); error = string.Empty; return(hornClause); }
private bool DoParse(bool useParallelTasks = true) { // put this in for debugging so we aren't running parallel "tasks" //sentences.RemoveRange(0, 2); //sentences.RemoveRange(1, sentences.Count-1); try { if (useParallelTasks) { Parallel.For(0, sentences.Count, new ParallelOptions() { MaxDegreeOfParallelism = -1 }, i => { var goal1 = new Goal(new Symbol("Sentence"), 0, sentences[i].Count); var ruleTree = new TFTree <Rule>(); ruleTree.Root = new TFTreeNode <Rule>( ruleCollection.Rules.ElementAt(0).Value as Rule); var ruleRangeStack = new Stack <RuleRange>(); var goalStack = new Stack <Goal>(); var ruleInputMapStack = new Stack <RuleInputMap>(); var parseTreeTopNode = new TFTreeNode <ParseTreeNodeData>(new ParseTreeNodeData(goal1, null)); var parseTree = new TFTree <ParseTreeNodeData>() { Root = parseTreeTopNode, XSLTFile = @"file:///D:/Temp/XMLPrettyPrint.xsl" }; if (goal1.NewProcess(sentences[i], 0, goalStack, ruleRangeStack, ruleInputMapStack, parseTreeTopNode, ruleTree.Root, null, ruleCollection)) { parseTrees[i] = parseTree; #if DEBUG_PARSER textBox1.AppendText( " \n---- rule input map stack ----------------------\n"); foreach (RuleInputMap ruleInputMap in ruleInputMapStack) { textBox1.AppendText(ruleInputMap.ToString(sentence) + Environment.NewLine); } textBox1.AppendText( " \n---- rule range stack ----------------------\n"); foreach (RuleRange ruleRange in ruleRangeStack) { textBox1.AppendText(ruleRange.TheRule + " (" + String.Join(", ", sentence.GetRange( ruleRange.InputPos, ruleRange.Length)) + ")" + Environment.NewLine); } textBox1.AppendText(" \n---- goal stack ----------------------\n"); foreach (Goal goal in goalStack) { textBox1.AppendText(goal.Symbol.TheSymbol + " (" + String.Join(", ", sentence.GetRange( goal.InputPos, goal.Length)) + ")" + Environment.NewLine); } textBox1.AppendText(" \n--------------------------\n"); long endTime = Stopwatch.GetTimestamp(); //var numNodes = parseTreeTopNode.GetDepthFirstEnumerable(TreeTraversalDirection.TopDown).Count(); //textBox1.AppendText(String.Format("Elapsed Time: {0}ms, # Nodes: {1}", 1000*(endTime-startTime)/Stopwatch.Frequency, numNodes)); //textBox1.Text = topNode.ToString(true); #endif } else { DebugAndTraceHelper.WriteTraceLine(String.Format("Could not parse {0}", String.Join(" ", sentences[i].Select(n => n.Lexeme.ToString())))); DebugAndTraceHelper.WriteTraceLine(String.Format(" {0}", String.Join(" ", sentences[i].Select(n => n.ToString())))); } }); } else // do a serial parsing { int sentenceCount = 0; foreach (List <Token> sentence in sentences) { var goal1 = new Goal(new Symbol("Sentence"), 0, sentences[sentenceCount].Count); var ruleTree = new TFTree <Rule>(); ruleTree.Root = new TFTreeNode <Rule>( ruleCollection.Rules.ElementAt(0).Value as Rule); var ruleRangeStack = new Stack <RuleRange>(); var goalStack = new Stack <Goal>(); var ruleInputMapStack = new Stack <RuleInputMap>(); var parseTreeTopNode = new TFTreeNode <ParseTreeNodeData>(new ParseTreeNodeData(goal1, null)); var parseTree = new TFTree <ParseTreeNodeData>() { Root = parseTreeTopNode, XSLTFile = @"file:///D:/Temp/XMLPrettyPrint.xsl" }; if (goal1.NewProcess(sentences[sentenceCount], 0, goalStack, ruleRangeStack, ruleInputMapStack, parseTreeTopNode, ruleTree.Root, null, ruleCollection)) { parseTrees[sentenceCount] = parseTree; } sentenceCount++; } } return(true); } catch (Exception) { throw; } }