/// <summary>Find the rule to a RuleLink.</summary> /// <param name="rules"></param> /// <param name="link"></param> /// <param name="status"></param> /// <returns></returns> private static Rule InitializeResolve(List <Rule> rules, RuleLink link, ParserStatus status) { Rule rule = rules.FirstOrDefault(r => r.Name == link.Value); if (rule == null) { status.AddBuildError(() => MessageRes.itc24, link.DefinitionCodeElement, link.Value); } return(rule); }
/// <summary>Each RuleLink has a level of recursive calls to stop infite loops.</summary> /// <param name="link">The RuleLink.</param> /// <returns>Loop level.</returns> internal LoopLevel GetLoopLoad(RuleLink link) { LoopLevel level; if (!_recursiveLoad.TryGetValue(link, out level)) { level = new LoopLevel() { LastInvokePos = NotValidPtr }; _recursiveLoad.Add(link, level); } return(level); }
public void ITC15ExpressionSetPrecedence() { string exprName = "expr"; string plusName = "plus"; // "plus = expr '+' expr;" var link1 = new RuleLink(exprName); var link2 = new RuleLink(exprName); var ruleP = new Rule( plusName, link1, new WordSymbol("+"), link2 ); // "expr = expr * expr | plus | identifyer;" var ruleE = new Rule(exprName, new Or(new RuleLink(plusName) { RuleElement = ruleP }, new WordIdent())); link2.RuleElement = link1.RuleElement = ruleE; var expr = new Expression(ruleE, ruleE.ChildNodes[0] as Or); //ruleE.ReplaceSubElement(ruleE.SubElements[0], expr); Assert.AreEqual(1, expr._binaryOperators.Count, "expr 1: 1 operators."); Assert.AreEqual(1, expr._binaryOperators[0].Precedence, "expr 1: precedence = 1."); ExpressionSetPrecedenceMakeOperators(expr, "expr x", new[] { 0, 0, 0, 0, 0 }); ExpressionSetPrecedenceTestOperators(expr, "expr 2", new[] { 5, 4, 3, 2, 1 }); ExpressionSetPrecedenceMakeOperators(expr, "expr x", new[] { 0, 2, 0, 2, 0, 1, 0, 1, 0 }); ExpressionSetPrecedenceTestOperators(expr, "expr 3", new[] { 9, 8, 7, 8, 6, 5, 4, 5, 3 }); ExpressionSetPrecedenceMakeOperators(expr, "expr x", new[] { 0, 9, 0, 9, 0, 7, 0, 7, 0 }); ExpressionSetPrecedenceTestOperators(expr, "expr 4", new[] { 9, 8, 7, 8, 6, 5, 4, 5, 3 }); // silly order test ExpressionSetPrecedenceMakeOperators(expr, "expr x", new[] { 0, 3, 0, 3, 0, 7, 0, 7, 0 }); ExpressionSetPrecedenceTestOperators(expr, "expr 5", new[] { 9, 7, 6, 7, 5, 8, 4, 8, 3 }); // silly order test ExpressionSetPrecedenceMakeOperators(expr, "expr x", new[] { 0, 3, 0, 3, 0, 7, 0, 8, 0, 2, 2 }); ExpressionSetPrecedenceTestOperators(expr, "expr 6", new[] { 11, 8, 7, 8, 6, 9, 5, 10, 4, 3, 3 }); }
public void ITC15ExpressionCreate() { string exprName = "expr"; string plusName = "plus"; // "plus = expr '+' expr;" var link1 = new RuleLink(exprName); var link2 = new RuleLink(exprName); var link3 = new RuleLink(exprName); var link4 = new RuleLink(exprName); var ruleP = new Rule( plusName, link1, new WordSymbol("+"), link2 ); // "expr = expr * expr | plus | identifyer;" var ruleE = new Rule(exprName, new Or( new SetOfElements( link3, new WordSymbol("*") { Precedence = 2 }, link4), new Or(new RuleLink(plusName) { RuleElement = ruleP }, new WordIdent()))); link4.RuleElement = link3.RuleElement = link2.RuleElement = link1.RuleElement = ruleE; var expr = new Expression(ruleE, ruleE.ChildNodes[0] as Or); //ruleE.ReplaceSubElement(ruleE.SubElements[0], expr); Assert.AreEqual(2, expr._binaryOperators.Count, "There should be 2 operators."); Assert.AreEqual("*", expr._binaryOperators[0].Name, "There multiplier name."); Assert.AreEqual(2, expr._binaryOperators[0].Precedence, "There multiplier precedence."); Assert.AreEqual(plusName, expr._binaryOperators[1].Name, "There sum name."); Assert.AreEqual(1, expr._otherForms.Count, "There should be 1 other form."); Assert.IsInstanceOfType(expr._otherForms[0], typeof(WordIdent), "Type of other form"); Assert.AreEqual("identifier", ((WordIdent)expr._otherForms[0]).Name, "Name of ident."); }
internal LoopLevel GetLoopLast(RuleLink link) { if (link == null) { _recursiveLast.Clear(); return(null); } LoopLevel level; if (!_recursiveLast.TryGetValue(link, out level)) { level = new LoopLevel() { LastInvokePos = NotValidPtr }; _recursiveLast.Add(link, level); } return(level); }
public override bool InitializeLoopHasWord(RuleLink link, List <RuleLink> subPath, ref bool linkFound) { return(true); }
private static List <ParserElementBase> BuildExpression(Parser parser, IEnumerable <CodeElement> docNodes, ParserStatus status) { //string debug1 = "(" + parser.Name + ")".NL() + docNotes.Aggregate("", (s, n) => s + n.ToMarkupProtected("")); List <ParserElementBase> elements = new List <ParserElementBase>(); foreach (CodeElement element in docNodes) { switch (element.Name) { case MetaParser.Expression_: if (docNodes.Count() > 1) { status.AddBuildError(() => MessageRes.itc29, element, parser.Name); } return(BuildExpression(parser, element.Codes(), status)); case MetaParser.Or_________: ParserElementBase el1, el2; List <CodeElement> orNodes = docNodes.ToList(); // find position int pos = 0; while (pos + 2 < orNodes.Count() && orNodes[++pos] != element) { } if (pos < 1 || pos + 2 > orNodes.Count()) { status.AddBuildError(() => MessageRes.itc30, element, parser.Name); } if (pos == 1) { el1 = elements[0]; } else { el1 = new SetOfElements(elements.ToArray()); } var elementElements2 = new List <CodeElement>(); for (int i = pos + 1; i < orNodes.Count(); i++) { elementElements2.Add(orNodes[i]); } List <ParserElementBase> elements2 = BuildExpression(parser, elementElements2, status); if (elements2.Count() == 1) { el2 = elements2[0]; } else { el2 = new SetOfElements(elements2.ToArray()); } return(new List <ParserElementBase> { new Or(el1, el2) }); case MetaParser.WordIdent__: ParserElementBase elem; switch (element.Value) { case MetaParser.WordString_: elem = new WordString(); break; case MetaParser.WordInt____: elem = new WordInt(); break; case MetaParser.WordFloat__: elem = new WordFloat(); break; case MetaParser.WordIdent__: elem = new WordIdent(); break; case MetaParser.WordBool___: elem = new WordBool(); break; default: elem = new RuleLink(element.Value); elem.DefinitionCodeElement = element; break; } elements.Add(elem); break; case MetaParser.WordSymbol_: elements.Add(new WordSymbol(element.Value)); break; case MetaParser.Sequence___: elements.Add(new Sequence(BuildExpression(parser, element.Codes(), status).ToArray())); break; case MetaParser.Optional___: elements.Add(new Optional(BuildExpression(parser, element.Codes(), status).ToArray())); break; case MetaParser.Parentheses: elements.Add(new Parentheses(BuildExpression(parser, element.Codes(), status).ToArray())); break; case MetaParser.Comment____: break; default: status.AddBuildError(() => MessageRes.itc31, element, element.Name); break; } } return(elements); }
/// <summary>Find out if there is a mandatory word before a recursive RuleLink.</summary> /// <param name="link">The RuleLink.</param> /// <returns>0: Link found (No words). 1: Mandatory word before link. 2: No words, no link. </returns> public abstract bool InitializeLoopHasWord(RuleLink link, List <RuleLink> subPath, ref bool linkFound);