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");
        }
Example #4
0
		public override void VisitExecute(PrioritizedChoice expression)
		{
		}
Example #5
0
		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;
				}
				);
		}
Example #6
0
		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]);
		}
Example #7
0
		public override void VisitEnter(PrioritizedChoice expression)
		{
		}
Example #8
0
 public abstract void VisitExecute(PrioritizedChoice expression);
Example #9
0
		public override void VisitExecute(PrioritizedChoice expression)
		{
			terminal.Peek().Append(" / ");
		}
Example #10
0
 public abstract void VisitEnter(PrioritizedChoice expression);
Example #11
0
 public abstract void VisitLeave(PrioritizedChoice expression);
Example #12
0
        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);
        }