public void CompositeVisitor_Recursiveness() { var whitespace = new CharacterClass {ClassExpression = "[ \t\r\n\v]"}; var terminal = new PrioritizedChoice( new CapturingGroup("AnyCharacter", new Literal {MatchText = "."}) , new CapturingGroup("CapturingGroup", new Sequence( new Literal {MatchText = "(?<"}, new CapturingGroup("ReplacementNode", new OneOrMore( new CharacterClass {ClassExpression = "[a-z0-9A-Z]"} ) ) ) .Sequence(new Literal {MatchText = ">"}) .Sequence(new RecursionCall("Expression")) .Sequence(new Literal {MatchText = ")"}) ) ); var sequence = new CapturingGroup( "Sequence", new Sequence( terminal, new ZeroOrMore(whitespace) ).Plus() ) {DoReplaceBySingleChildNode = true}; var prioritizedchoice = new CapturingGroup("PrioritizedChoice", new Sequence( sequence, new Literal {MatchText = "/"} ) .Sequence(new ZeroOrMore(whitespace)) .Sequence(sequence) .Sequence( new ZeroOrMore( new Sequence( new ZeroOrMore(whitespace), new Literal {MatchText = "/"} ) .Sequence(new ZeroOrMore(whitespace)) .Sequence(sequence) .Plus() ) ) ); var expression = new CapturingGroup("Root", new RecursionCreate("Expression", new PrioritizedChoice(prioritizedchoice, sequence))); var input = @"(?<NPEGNode>./.. )"; var bytes = Encoding.UTF8.GetBytes(input); var iterator = new ByteInputIterator(bytes); var visitor = new NpegParserVisitor(iterator); expression.Accept(visitor); Assert.IsTrue(visitor.IsMatch); AstNode node = visitor.AST; Assert.IsTrue(node.Token.Name == "Root"); Assert.IsTrue(node.Children.Count == 1); Assert.IsTrue(node.Children.Count == 1); Assert.IsTrue(node.Children[0].Token.Name == "CapturingGroup"); Assert.IsTrue(node.Children[0].Children.Count == 2); Assert.IsTrue(node.Children[0].Children[0].Token.Name == "ReplacementNode"); Assert.IsTrue(node.Children[0].Children[1].Token.Name == "PrioritizedChoice"); Assert.IsTrue(node.Children[0].Children[1].Children[0].Token.Name == "AnyCharacter"); Assert.IsTrue(node.Children[0].Children[1].Children[1].Token.Name == "Sequence"); Assert.IsTrue(node.Children[0].Children[1].Children[1].Children[0].Token.Name == "AnyCharacter"); Assert.IsTrue(node.Children[0].Children[1].Children[1].Children[1].Token.Name == "AnyCharacter"); }
public void CompositeVisitor_CapturingGroup_SandBoxTest_PriorityChoice3() { var prefix = new PrioritizedChoice( new CapturingGroup("AndPredicate", new Literal {MatchText = "&"}), new CapturingGroup("NotPredicate", new Literal {MatchText = "!"}) ); PrioritizedChoice suffix = new PrioritizedChoice( new CapturingGroup("ZeroOrMore", new Literal {MatchText = "*"}), new CapturingGroup("OneOrMore", new Literal {MatchText = "+"}) ) .Or(new CapturingGroup("Optional", new Literal {MatchText = "?"})); var terminal = new CapturingGroup("AnyCharacter", new Literal {MatchText = "."}); var expression = new CapturingGroup("Expression", new PrioritizedChoice( // match prefixes first prefix.Plus() .Sequence(terminal) , // match suffixes next terminal .Sequence( suffix.Plus() ) ) .Or(terminal) .Plus() ); var input = "."; var bytes = Encoding.UTF8.GetBytes(input); var iterator = new ByteInputIterator(bytes); var visitor = new NpegParserVisitor(iterator); expression.Accept(visitor); Assert.IsTrue(visitor.IsMatch); AstNode node = visitor.AST; Assert.IsTrue(node.Children.Count == 1); Assert.IsTrue(node.Token.Name == "Expression"); Assert.IsTrue(node.Token.ValueAsString(iterator) == "."); Assert.IsTrue(node.Children[0].Token.Name == "AnyCharacter"); }
public void CompositeVisitor_CapturingGroup_SandBoxTest_PriorityChoice1() { PrioritizedChoice newline = new PrioritizedChoice( new Literal {MatchText = "\r\n"}, // windows new Literal {MatchText = "\r\r"} // old macs ) .Or(new Literal {MatchText = "\n"}); // linux // Single Line Comment var singleLineComment = new Sequence( new Literal {MatchText = "//"}, new Sequence( new NotPredicate(newline), new AnyCharacter() ) .Star() ); // Multiline Comment var multiLineComment = new Sequence( new Literal {MatchText = "/*"}, new Sequence( new NotPredicate(new Literal {MatchText = "*/"}), new AnyCharacter() ) .Star() .Sequence(new Literal {MatchText = "*/"}) ); var comment = new PrioritizedChoice(singleLineComment, multiLineComment); var whitespace = new PrioritizedChoice( new CharacterClass {ClassExpression = "[ \t\r\n\v]"}, comment ); var label = new CapturingGroup("Label", new Sequence( new CharacterClass {ClassExpression = "[a-zA-Z_]"}, // must start with alpha character new ZeroOrMore(new CharacterClass {ClassExpression = "[a-zA-Z0-9_]"}) ) ); var backreference = new CapturingGroup("DynamicBackReferencing", new Sequence( new Literal {MatchText = @"\k<"}, new Sequence(new ZeroOrMore(whitespace), label).Sequence( new ZeroOrMore(whitespace)) ) .Sequence( new Optional( new Sequence( new Sequence( new Literal {MatchText = "["}, new CapturingGroup("CaseSensitive", new Literal {MatchText = @"\i"} ) ), new Literal {MatchText = "]"} ) ) ) .Sequence( new Sequence(new ZeroOrMore(whitespace), new Literal {MatchText = ">"}) ) ); var root = new CapturingGroup("Test", new Sequence( backreference, new NotPredicate(new AnyCharacter()) ) ); var input = @"\k< CapturedLabelVariableName >"; var bytes = Encoding.UTF8.GetBytes(input); var iterator = new ByteInputIterator(bytes); var visitor = new NpegParserVisitor(iterator); root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); AstNode node = visitor.AST; Assert.IsTrue(node.Token.Name == "Test"); Assert.IsTrue(node.Children[0].Token.Name == "DynamicBackReferencing"); Assert.IsTrue(node.Children[0].Children[0].Token.Name == "Label"); Assert.IsTrue(node.Children[0].Children[0].Token.ValueAsString(iterator) == "CapturedLabelVariableName"); }
public override void VisitExecute(PrioritizedChoice expression) { }
public override void VisitLeave(PrioritizedChoice expression) { IsMatchPredicate localRight = _matchStack.Pop(); IsMatchPredicate localLeft = _matchStack.Pop(); _matchStack.Push( delegate(IInputIterator iterator) { Int32 savePosition = iterator.Index; _sandbox.Push(new Stack<AstNode>()); _sandbox.Peek().Push(new AstNode()); // create new sandbox which capturing group works in. // have a dummy node to act as parent container (CapturedGroup logic) if (localLeft(iterator)) { Stack<AstNode> s = _sandbox.Pop(); if (s.Count >= 1) { AstNode child = s.Pop(); if (_sandbox.Peek().Count == 0) { _sandbox.Peek().Push(child); } else { _sandbox.Peek().Peek().Children.AddRange(child.Children); // our dummy node for this sandbox is child. // move important data over to the previous sandbox. } } return true; } _sandbox.Pop(); // destory sandbox since anything captured is no longer valid. iterator.Index = savePosition; _sandbox.Push(new Stack<AstNode>()); _sandbox.Peek().Push(new AstNode()); // create new sandbox which capturing group works in. // have a dummy node to act as parent container (CapturedGroup logic) if (localRight(iterator)) { Stack<AstNode> s = _sandbox.Pop(); if (s.Count >= 1) { AstNode child = s.Pop(); if (_sandbox.Peek().Count == 0) { _sandbox.Peek().Push(child); } else { _sandbox.Peek().Peek().Children.AddRange(child.Children); // our dummy node for this sandbox is child. // move important data over to the previous sandbox. } } return true; } _sandbox.Pop(); // destory sandbox since anything captured is no longer valid. return false; } ); }
public override void VisitLeave(PrioritizedChoice expression) { terminal.Peek().Append(")"); //String input = terminal.Pop().ToString(); //if (!this.uniqueBranches.ContainsKey(input)) //{ // String nodename = "node" + branchcount++; // this.uniqueBranches.Add(input, nodename); // this.statements.Add( String.Format("{0}: {1};", nodename, input) ); //} //// remember last node is always a captured group so peek should not throw exceptions //// insert terminal name //terminal.Peek().Append(this.uniqueBranches[input]); }
public override void VisitEnter(PrioritizedChoice expression) { }
public abstract void VisitExecute(PrioritizedChoice expression);
public override void VisitExecute(PrioritizedChoice expression) { terminal.Peek().Append(" / "); }
public abstract void VisitEnter(PrioritizedChoice expression);
public abstract void VisitLeave(PrioritizedChoice expression);
private static AExpression mSuffix() { // MathExpression var variable = new CapturingGroup("VARIABLE", new Sequence( new Literal() { IsCaseSensitive = false, MatchText = @"\k<" } , new ZeroOrMore(mSpace()) ) .Sequence( new CapturingGroup("NAME", new Sequence( new CharacterClass { ClassExpression = "[a-zA-Z]" } , new ZeroOrMore( new CharacterClass { ClassExpression = "[a-zA-Z0-9]" } ) ) ) ) .Sequence( new ZeroOrMore(mSpace()) ) .Sequence( new Literal() { IsCaseSensitive = false, MatchText = @">" } ) ); var digit = new CapturingGroup("DIGIT", new Sequence( new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"}) , new Sequence(new Literal(){MatchText = "."}, new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"})).Optional() ) ); var value = new PrioritizedChoice( variable, digit ) .Or( new Sequence( new Literal { MatchText = "(" }, new ZeroOrMore(mSpace()) ) .Sequence(new RecursionCall("VariableLengthExpressionFunction")) .Sequence(new ZeroOrMore(mSpace())) .Sequence(new Literal { MatchText = ")" }) ); var product = new CapturingGroup("PRODUCT", new Sequence( new Sequence(value, new ZeroOrMore(mSpace())) , new Sequence( new CapturingGroup("SYMBOL", new PrioritizedChoice( new Literal { MatchText = "*" }, new Literal { MatchText = "/" } ) ), new Sequence(new ZeroOrMore(mSpace()), value) ).Star() ) ); var sum = new CapturingGroup("SUM", new Sequence( new Sequence(product, new ZeroOrMore(mSpace())) , new Sequence( new CapturingGroup("SYMBOL", new PrioritizedChoice( new Literal { MatchText = "+" }, new Literal { MatchText = "-" } ) ), new Sequence(new ZeroOrMore(mSpace()), product) ).Star() ) ); AExpression variableLengthExpression = new RecursionCreate("VariableLengthExpressionFunction", new CapturingGroup("VariableLength", new Sequence( new ZeroOrMore(mSpace()), sum) .Sequence( new ZeroOrMore(mSpace()) ) ) ); return new CapturingGroup("Suffix", new PrioritizedChoice( new CapturingGroup("ZeroOrMore", new Sequence( mTerminal(), new ZeroOrMore(mSpace()) ) .Sequence(new Literal {MatchText = "*"}) ), new CapturingGroup("OneOrMore", new Sequence( mTerminal(), new ZeroOrMore(mSpace()) ) .Sequence(new Literal {MatchText = "+"}) ) ) .Or( new CapturingGroup("Optional", new Sequence( mTerminal(), new ZeroOrMore(mSpace()) ) .Sequence(new Literal {MatchText = "?"}) ) ) .Or( new CapturingGroup("LimitingRepetition", new Sequence( mTerminal(), new ZeroOrMore(mSpace()) ) .Sequence( new Sequence( new Sequence( new Literal {MatchText = "{"}, new ZeroOrMore(mSpace()) ), new PrioritizedChoice( // {min,max} new CapturingGroup("BETWEEN", new Sequence( new CapturingGroup("Min", new OneOrMore( new CharacterClass { ClassExpression = "[0-9]" })).Sequence( new ZeroOrMore( mSpace())), new Literal {MatchText = ","} ) .Sequence( new Sequence(new ZeroOrMore(mSpace()), new CapturingGroup("Max", new OneOrMore (new CharacterClass { ClassExpression = "[0-9]" }))) ) ) , //{,max} new CapturingGroup("ATMOST", new Sequence( new Literal {MatchText = ","} , new Sequence(new ZeroOrMore(mSpace()), new CapturingGroup("Max", new OneOrMore( new CharacterClass { ClassExpression = "[0-9]" }))) ) ) ) .Or ( //{min,} new CapturingGroup("ATLEAST", new Sequence( new Sequence(new ZeroOrMore(mSpace()), new CapturingGroup("Min", new OneOrMore( new CharacterClass { ClassExpression = "[0-9]" }))) .Sequence(new ZeroOrMore(mSpace())) , new Literal {MatchText = ","} ) ) ) .Or ( new CapturingGroup("EXACT", new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"})) ) .Or ( //{(\k<C2> - \k<C1>)+1} variable-length protocol support with backreferencing variableLengthExpression ) ) .Sequence( new ZeroOrMore(mSpace()) ) .Sequence( new Literal {MatchText = "}"} ) ) ) ) ); }
public void PracticalExample_BooleanAlgebra() { #region Composite //AND: */AND AExpression AND = new PrioritizedChoice(new Literal {MatchText = "*"}, new Literal {MatchText = "AND"}); //NAND: ~*/NAND AExpression NAND = new PrioritizedChoice(new Literal {MatchText = "~*"}, new Literal {MatchText = "NAND"}); //OR: +/OR AExpression OR = new PrioritizedChoice(new Literal {MatchText = "+"}, new Literal {MatchText = "OR"}); //NOR: ~+/NOR AExpression NOR = new PrioritizedChoice(new Literal {MatchText = "~+"}, new Literal {MatchText = "NOR"}); //XOR: ^/XOR AExpression XOR = new PrioritizedChoice(new Literal {MatchText = "^"}, new Literal {MatchText = "XOR"}); //XNOR: ~^/XNOR AExpression XNOR = new PrioritizedChoice(new Literal {MatchText = "~^"}, new Literal {MatchText = "XNOR"}); AExpression GATE = new CapturingGroup("GATE", new PrioritizedChoice(AND, NAND).Or(OR).Or(NOR).Or(XOR).Or(XNOR)); // Variable: "[a-zA-Z0-9]+" / '[a-zA-Z0-9]+' / [a-zA-Z] AExpression VARIABLE = new PrioritizedChoice( new Sequence( new Literal {MatchText = "\""}, new CapturingGroup("VARIABLE", new OneOrMore(new CharacterClass {ClassExpression = "[a-zA-Z0-9]"})) ).Sequence(new Literal {MatchText = "\""}), new Sequence( new Literal {MatchText = "'"}, new CapturingGroup("VARIABLE", new OneOrMore(new CharacterClass {ClassExpression = "[a-zA-Z0-9]"})) ).Sequence(new Literal {MatchText = "'"}) ).Or( new CapturingGroup("VARIABLE", new CharacterClass {ClassExpression = "[a-zA-Z]"}) ); // Variable: Variable / !Variable VARIABLE = new PrioritizedChoice( VARIABLE , new CapturingGroup("INVERTOR", new Sequence( new Literal {MatchText = "!"}, VARIABLE ) ) ); // Variable: Variable / Expression / !Expression VARIABLE = new PrioritizedChoice( VARIABLE , new Sequence( new Literal {MatchText = "("}, new RecursionCall("RECURSIONEXPRESSION") ).Sequence(new Literal {MatchText = ")"}) ).Or( new CapturingGroup("INVERTOR", new Sequence( new Literal {MatchText = "!"} , new Sequence( new Literal {MatchText = "("}, new RecursionCall("RECURSIONEXPRESSION") ).Sequence(new Literal {MatchText = ")"}) ) ) ); AExpression Root = new CapturingGroup("BOOLEANEQUATION", new Sequence( new RecursionCreate("RECURSIONEXPRESSION", //Expression: Variable ((AND|NAND|OR|NOR|XOR|XNOR) Variable)* new Sequence(VARIABLE, new Sequence(GATE, VARIABLE).Star()) ) , // ensure reaches end of file new NotPredicate(new AnyCharacter()) ) ); #endregion // single variable var input = "A*!B+!A*B"; var bytes = Encoding.UTF8.GetBytes(input); var iterator = new ByteInputIterator(bytes); var visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); AstNode node = visitor.AST; Assert.IsTrue(node.Token.Name == "BOOLEANEQUATION"); Assert.IsTrue(node.Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[0].Token.ValueAsString(iterator) == "A"); Assert.IsTrue(node.Children[1].Token.Name == "GATE"); Assert.IsTrue(node.Children[1].Token.ValueAsString(iterator) == "*"); Assert.IsTrue(node.Children[2].Token.Name == "INVERTOR"); Assert.IsTrue(node.Children[2].Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[2].Children[0].Token.ValueAsString(iterator) == "B"); Assert.IsTrue(node.Children[3].Token.Name == "GATE"); Assert.IsTrue(node.Children[4].Token.Name == "INVERTOR"); Assert.IsTrue(node.Children[4].Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[4].Children[0].Token.ValueAsString(iterator) == "A"); Assert.IsTrue(node.Children[5].Token.Name == "GATE"); Assert.IsTrue(node.Children[6].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[6].Token.ValueAsString(iterator) == "B"); // quoted variable input = "'aA'*!'bB'+!'aA'*'bB'"; bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; Assert.IsTrue(node.Token.Name == "BOOLEANEQUATION"); Assert.IsTrue(node.Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[0].Token.ValueAsString(iterator) == "aA"); Assert.IsTrue(node.Children[1].Token.Name == "GATE"); Assert.IsTrue(node.Children[1].Token.ValueAsString(iterator) == "*"); Assert.IsTrue(node.Children[2].Token.Name == "INVERTOR"); Assert.IsTrue(node.Children[2].Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[2].Children[0].Token.ValueAsString(iterator) == "bB"); Assert.IsTrue(node.Children[3].Token.Name == "GATE"); Assert.IsTrue(node.Children[4].Token.Name == "INVERTOR"); Assert.IsTrue(node.Children[4].Children[0].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[4].Children[0].Token.ValueAsString(iterator) == "aA"); Assert.IsTrue(node.Children[5].Token.Name == "GATE"); Assert.IsTrue(node.Children[6].Token.Name == "VARIABLE"); Assert.IsTrue(node.Children[6].Token.ValueAsString(iterator) == "bB"); // expression + gate + variable .star() input = "A*!B*C+!A*B*C"; bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); // parethesis input = "((A)*(!B)+(!A)*(B))"; bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = "((A)*!(B)+!(A)*(B))"; bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = "((A)*(!(B))+(!(A))*(B))"; bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = ("(!X*Y*!Z)"); bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = ("(!X*Y*!Z)+(!X*Y*Z)"); bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = ("(X*Z)"); bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = ("(!X*Y*!Z)+(!X*Y*Z)+(X*Z)"); bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); input = ("((((!X*Y*Z)+(!X*Y*!Z)+(X*Z))))"); bytes = Encoding.UTF8.GetBytes(input); iterator = new ByteInputIterator(bytes); visitor = new NpegParserVisitor(iterator); Root.Accept(visitor); Assert.IsTrue(visitor.IsMatch); node = visitor.AST; #warning Assert.IsTrue(node.Token.Value == input); }
public void PracticalExample_MathematicalFormula() { #region Composite var VALUE = new PrioritizedChoice( new CapturingGroup("VALUE", new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"}) ) , new Sequence( new Literal {MatchText = "("}, new RecursionCall("ParethesisFunction") ) .Sequence(new Literal {MatchText = ")"}) ); var PRODUCT = new Sequence( VALUE, new Sequence( new CapturingGroup("SYMBOL", new PrioritizedChoice( new Literal {MatchText = "*"}, new Literal {MatchText = "/"} ) ), VALUE ).Star() ); var SUM = new Sequence( PRODUCT, new Sequence( new CapturingGroup("SYMBOL", new PrioritizedChoice( new Literal {MatchText = "+"}, new Literal {MatchText = "-"} ) ), PRODUCT ).Star() ); AExpression EXPRESSION = new RecursionCreate("ParethesisFunction", new CapturingGroup("EXPRESSION", SUM)); #endregion var input = "((((12/3)+5-2*(81/9))+1))"; var bytes = Encoding.UTF8.GetBytes(input); var iterator = new ByteInputIterator(bytes); var visitor = new NpegParserVisitor(iterator); EXPRESSION.Accept(visitor); Assert.IsTrue(visitor.IsMatch); AstNode node = visitor.AST; Assert.IsTrue(node.Token.ValueAsString(iterator) == input); }