public void CompositeVisitor_RecursiveParentheses()
        {
            #region Composite

            AExpression DIGITS = new CapturingGroup("DIGITS", new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"}));
            AExpression ENCLOSEDDIGITS = new RecursionCreate("ParethesisFunction",
                                                             new PrioritizedChoice(
                                                             	DIGITS
                                                             	,
                                                             	new CapturingGroup("ENCLOSEDDIGITS",
                                                             	                   new Sequence(
                                                             	                   	new Literal {MatchText = "("},
                                                             	                   	new RecursionCall("ParethesisFunction")
                                                             	                   	).Sequence(new Literal {MatchText = ")"})
                                                             		)
                                                             	)
                );

            AExpression ROOT = new CapturingGroup("RECURSIONTEST", ENCLOSEDDIGITS);

            #endregion

            var input = Encoding.UTF8.GetBytes("((((((123))))))");
            var visitor = new NpegParserVisitor(new ByteInputIterator(input));
            ROOT.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            AstNode node = visitor.AST;
            Assert.IsTrue(node.Token.Name == "RECURSIONTEST");
            Assert.IsTrue(node.Children.Count == 1);
            Assert.IsTrue(node.Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Token.Name == "ENCLOSEDDIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Token.Name == "DIGITS");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Children.Count == 0);
        }
		public override void VisitLeave(RecursionCreate expression)
		{
			IsMatchPredicate local = _matchStack.Pop();
			if (!_recursiveMethod.ContainsKey(expression.FunctionName))
				_recursiveMethod.Add(
					expression.FunctionName
					,
					delegate(IInputIterator iterator) { return local(iterator); }
				);

			_matchStack.Push(_recursiveMethod[expression.FunctionName]);
		}
        public void CompositeVisitor_NestedRecursive()
        {
            #region Composite

            var DIGITS = new CapturingGroup("DIGITS", new OneOrMore(new CharacterClass {ClassExpression = "[0-9]"}));
            var LTENCLOSED = new RecursionCreate("RECURSIONLTENCLOSED",
                                                 new PrioritizedChoice(DIGITS,
                                                                       new CapturingGroup("LTENCLOSED",
                                                                                          new Sequence(
                                                                                          	new Literal {MatchText = "<"},
                                                                                          	new RecursionCall(
                                                                                          		"RECURSIONLTENCLOSED")
                                                                                          	).Sequence(new Literal
                                                                                          	           	{MatchText = ">"})
                                                                       	)
                                                 	)
                );
            var PENCLOSED = new RecursionCreate("RECURSIONPENCLOSED",
                                                new PrioritizedChoice(LTENCLOSED,
                                                                      new CapturingGroup("PENCLOSED",
                                                                                         new Sequence(
                                                                                         	new Literal {MatchText = "("},
                                                                                         	new RecursionCall("RECURSIONPENCLOSED")
                                                                                         	).Sequence(new Literal
                                                                                         	           	{MatchText = ")"})
                                                                      	)
                                                    )
                );

            AExpression ROOT = new CapturingGroup("NESTEDRECURSIONTEST", PENCLOSED);

            #endregion

            var input = "(((<<<123>>>)))";
            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.ValueAsString(iterator) == input);
            Assert.IsTrue(node.Token.Name == "NESTEDRECURSIONTEST");
            Assert.IsTrue(node.Children.Count == 1);
            Assert.IsTrue(node.Children[0].Token.Name == "PENCLOSED");
            Assert.IsTrue(node.Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Token.Name == "PENCLOSED");
            Assert.IsTrue(node.Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Token.Name == "PENCLOSED");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Token.Name == "LTENCLOSED");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Token.Name == "LTENCLOSED");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Token.Name == "LTENCLOSED");
            Assert.IsTrue(node.Children[0].Children[0].Children[0].Children[0].Children[0].Children[0].Children.Count == 1);
        }
		public override void VisitEnter(RecursionCreate expression)
		{
		}
		public override void VisitExecute(RecursionCreate expression)
		{
		}
		//rule, name
		public override void VisitEnter(RecursionCreate expression)
		{
			terminal.Push(new StringBuilder());
		}
		public override void VisitLeave(RecursionCreate expression)
		{
			String rule = terminal.Pop().ToString();
			if (!uniqueRecursionBlocks.ContainsKey(rule))
			{
				uniqueRecursionBlocks.Add(rule, expression.FunctionName);

				var nodeText = new StringBuilder();
				nodeText.AppendFormat("{0}: {1};", expression.FunctionName, rule);
				statements.Add(nodeText.ToString());
			}

			if (terminal.Count > 0)
				terminal.Peek().Append(uniqueRecursionBlocks[rule]);
		}
 public abstract void VisitEnter(RecursionCreate expression);
 public abstract void VisitLeave(RecursionCreate expression);
 public abstract void VisitExecute(RecursionCreate expression);
Exemple #11
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_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);
        }