public AstNode Parse(IInputIterator inputIterator)
        {
            string grammar = @"
				WhiteSpace: [\s\n\t ]+;
				Comment: '/*' (!'*/' .)* '*/';
				(?<S>): (WhiteSpace / Comment)*;
				(?<Variable>): '\k<' S (?<Name>[a-zA-Z][a-zA-Z0-9]*) S '>';
				(?<Digit>): [0-9]+('.'[0-9]+)?;
				Value: Variable / Digit / '(' S Expr S ')';
				(?<Product \rsc>): Value S ((?<Symbol> '*' / '/') S Value)*;
				(?<Sum \rsc>): Product S ((?<Symbol>'+' / '-') S Product)*;
				(?<Expr \rsc>): S Sum S;
            ".Trim();

            AExpression rules = PEGrammar.Load(grammar);

            var visitor = new NpegParserVisitor(inputIterator);

            rules.Accept(visitor);

            if (visitor.IsMatch)
            {
                return(visitor.AST);
            }

            throw new InvalidInputException();
        }
        public void PEGrammar_PhoneNumber()
        {
            var input = "123-456-7890";

            var PhoneNumber = PEGrammar.Load(
                @"
                        (?<ThreeDigitCode>): [0-9] [0-9] [0-9];
                        (?<FourDigitCode>): [0-9] [0-9] [0-9] [0-9];
                        (?<PhoneNumber>): ThreeDigitCode '-' ThreeDigitCode '-' FourDigitCode;
                    "
                .Trim());

            var bytes    = Encoding.UTF8.GetBytes(input);
            var iterator = new ByteInputIterator(bytes);
            var visitor  = new NpegParserVisitor(iterator);

            PhoneNumber.Accept(visitor);

            Assert.IsTrue(visitor.IsMatch);
            AstNode node = visitor.AST;

            Assert.IsTrue(node.Token.Name == "PhoneNumber");
            Assert.IsTrue(node.Token.ValueAsString(iterator) == input);
            Assert.IsTrue(node.Children[0].Token.Name == "ThreeDigitCode");
            Assert.IsTrue(node.Children[0].Token.ValueAsString(iterator) == "123");
            Assert.IsTrue(node.Children[1].Token.Name == "ThreeDigitCode");
            Assert.IsTrue(node.Children[1].Token.ValueAsString(iterator) == "456");
            Assert.IsTrue(node.Children[2].Token.Name == "FourDigitCode");
            Assert.IsTrue(node.Children[2].Token.ValueAsString(iterator) == "7890");
        }
        public void PEGrammar_LimitingRepetition()
        {
            var grammar =
                @"
                                (?<ThreeDigitCode>): [0-9]{3,3};
                                (?<PhoneNumber>): ThreeDigitCode '-' ThreeDigitCode '-' (?<FourDigitCode>[0-9]{4});
                              ";

            var ROOT = PEGrammar.Load(grammar);

            var input    = "123-456-7890";
            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 == "PhoneNumber");
            Assert.IsTrue(node.Token.ValueAsString(iterator) == input);
            Assert.IsTrue(node.Children[0].Token.Name == "ThreeDigitCode");
            Assert.IsTrue(node.Children[0].Token.ValueAsString(iterator) == "123");
            Assert.IsTrue(node.Children[1].Token.Name == "ThreeDigitCode");
            Assert.IsTrue(node.Children[1].Token.ValueAsString(iterator) == "456");
            Assert.IsTrue(node.Children[2].Token.Name == "FourDigitCode");
            Assert.IsTrue(node.Children[2].Token.ValueAsString(iterator) == "7890");
        }
        //[ExpectedException(typeof (InfiniteLoopDetectedException))]
        public void PEGrammar_OneOrMore_InfiniteLoopTest()
        {
            string      input         = "";
            AExpression caseSensitive = PEGrammar.Load(@"(?<Expression>): (.*)+;");

            var bytes   = Encoding.UTF8.GetBytes(input);
            var visitor = new NpegParserVisitor(new ByteInputIterator(bytes));

            caseSensitive.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
        }
        public void PEGrammar_Interpreter_CodePoint()
        {
            AExpression ROOT = PEGrammar.Load(
                @"
                    (?<Value>): #x20;
                "
                );

            String input    = " ";
            var    bytes    = Encoding.UTF8.GetBytes(input);
            var    iterator = new ByteInputIterator(bytes);
            var    visitor  = new NpegParserVisitor(iterator);

            ROOT.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
        }
        public void PEGrammar_Literal()
        {
            AExpression caseSensitive = PEGrammar.Load(@"(?<Expression>): 'Hello World';");

            var input    = "hello world";
            var bytes    = Encoding.UTF8.GetBytes(input);
            var iterator = new ByteInputIterator(bytes);
            var visitor  = new NpegParserVisitor(iterator);

            caseSensitive.Accept(visitor);
            Assert.IsFalse(visitor.IsMatch);

            AExpression notCaseSensitive = PEGrammar.Load(@"(?<Expression>): 'Hello World'\i;");

            input    = "hello world";
            bytes    = Encoding.UTF8.GetBytes(input);
            iterator = new ByteInputIterator(bytes);
            visitor  = new NpegParserVisitor(iterator);
            notCaseSensitive.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            AstNode node = visitor.AST;

            Assert.IsTrue(node.Token.Name == "Expression");
            Assert.IsTrue(node.Token.ValueAsString(iterator) == input);


            // not sure if it would be better to use verbatim identifier @"" for escaping
            // escape back slash inside double quotes
            input = @"\";
            AExpression escape = PEGrammar.Load(@"(?<Literal>): ""\\"";");

            bytes    = Encoding.UTF8.GetBytes(input);
            iterator = new ByteInputIterator(bytes);
            visitor  = new NpegParserVisitor(iterator);
            escape.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            Assert.IsTrue(@"\" == visitor.AST.Token.ValueAsString(iterator));

            input    = @"\";
            escape   = PEGrammar.Load(@"(?<Literal>): '\\';");
            bytes    = Encoding.UTF8.GetBytes(input);
            iterator = new ByteInputIterator(bytes);
            visitor  = new NpegParserVisitor(iterator);
            escape.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            Assert.IsTrue(@"\" == visitor.AST.Token.ValueAsString(iterator));
        }
        public void PEGrammar_LimitingRepetition_VariableExpression()
        {
            var grammar =
                @"
					(?<ESC_AMP_Y>): . . . (?<C1>.) (?<C2>.) 
					(
						((?<X> .) (?<D> .{3})) 
					){(\k<C2> - \k<C1>)+1};

             ";

            var ROOT = PEGrammar.Load(grammar);

            //.     .      .    C1    C2    X     D     D      D
            var bytes    = new byte[] { 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 };
            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 == "ESC_AMP_Y");
            Assert.IsTrue(node.Token.End == bytes.Length - 1);             // zero index

            //.     .      .    C1    C2
            bytes = new byte[] { 0x00, 0x00, 0x00, 0x01, 0x02,
                                 0x00, 0x00, 0x00, 0x00, //X     D     D      D
                                 0x00, 0x00, 0x00, 0x00, //X     D     D      D
                                 0x00 };
            iterator = new ByteInputIterator(bytes);
            visitor  = new NpegParserVisitor(iterator);
            ROOT.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            node = visitor.AST;

            Assert.IsTrue(node.Token.Name == "ESC_AMP_Y");
            Assert.IsTrue(node.Token.End == bytes.Length - 2);             // zero index - expect additional character to not be consumed
        }
        public void Recursive_Grammar_Used_In_Predicate_Should_Not_Append_To_Ast()
        {
            var rules = PEGrammar.Load(@"
NewLine: [\r][\n] / [\n][\r] / [\n] / [\r];
Space: ' ';
Tab: [\t];
s: ( Space / Tab  )+;
S: ( NewLine )+;
W: (s / S);
(?<Notes>): 'Notes'\i s* ':' (!Scenario .)+;
(?<Scenario>): 'Scenario'\i s* ':'  (?<Title> (!S .)+ ) W+ Notes?;
(?<Document>): W* (Scenario W*)+ !. ;
			"            );

            var bytes = Encoding.UTF8.GetBytes(
                @"
Scenario:	User creates a new template with a name  
	 
Notes: (markdown)

 
Scenario:	User creates a new template with case information 

Notes: (markdown)
");
            var visitor = new NpegParserVisitor(new ByteInputIterator(bytes));

            rules.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            var ast       = visitor.AST;
            var scenarios = ast.Children.Where(x => x.Token.Name.Equals("Scenario")).ToList();

            Assert.IsTrue(scenarios.Count == 2);
            var notes = scenarios[0].Children["Notes"];

            Assert.IsTrue(!notes.Children.Any(), "notes should not have any children");
            // previously Notes would contain nested Scenario due to predicate !Scenario
        }
        public void PEGrammar_MathematicalFormula_Recursion()
        {
            AExpression ROOT = PEGrammar.Load(
                @"
                    (?<Value>): [0-9]+ / '(' Expr ')';
                    (?<Product>): Value ((?<Symbol>'*' / '/') Value)*;
                    (?<Sum>): Product ((?<Symbol>'+' / '-') Product)*;
                    (?<Expr>): Sum;
                "
                );

            String input    = "((((12/3)+5-2*(81/9))+1))";
            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);
#warning does not specify expected tree
        }
        public void PEGrammar_RecursiveParentheses()
        {
            var input = "((((((123))))))";
            var bytes = Encoding.UTF8.GetBytes(input);

            AExpression ROOT = PEGrammar.Load(
                @"
                        (?<DIGITS>): ([0-9])+;
                        (?<ENCLOSEDDIGITS>): '(' ParethesisFunction ')';
                        ParethesisFunction: (DIGITS / ENCLOSEDDIGITS);
                        (?<RECURSIONTEST>): ParethesisFunction;
                    "
                .Trim());

            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);
        }
        public void PEGrammar_DynamicBackReference_Xml()
        {
            var grammar =
                @"
					(?<Tag>): [a-zA-Z0-9]+;
					(?<StartTag>): '<' Tag '>';
					(?<EndTag>): '</' \k<Tag> '>' ;
					(?<Body>): (Xml / (!EndTag .))+;
					(?<Xml>): (StartTag Body EndTag )+;
			"            ;

            var input = @"
					<test>
						test data start
						<test1>
							test1 data start
							<test2>
								text2 data start
								text2 data end
							</test2>
							test1 data end
						</test1>
						test data end
					</test>
			"            .Trim();

            var ROOT     = PEGrammar.Load(grammar);
            var iterator = new ByteInputIterator(Encoding.UTF8.GetBytes(input));
            var visitor  = new NpegParserVisitor(iterator);

            ROOT.Accept(visitor);
            Assert.IsTrue(visitor.IsMatch);
            AstNode node = visitor.AST;

            throw new NotImplementedException("Refactoring - plan on changing backreferencing logic inside NPEGParser - just placeholder of failing test for now; conserve memory");
        }
        public void PEGrammar_BooleanAlgebra()
        {
            String grammar =
                @"
					S: [\s]+;
                    (?<Gate>): ('*' / 'AND') / ('~*' / 'NAND') / ('+' / 'OR') / ('~+' / 'NOR') / ('^' / 'XOR') / ('~^' / 'XNOR');
                    ValidVariable: '""' (?<Variable>[a-zA-Z0-9]+) '""'  / '\'' (?<Variable>[a-zA-Z0-9]+) '\'' / (?<Variable>[a-zA-Z]);
                    VarProjection1: ValidVariable /  (?<Invertor>'!' ValidVariable);
                    VarProjection2: VarProjection1 / '(' Expression ')' / (?<Invertor>'!' '(' Expression ')');
                    Expression: S? VarProjection2 S? (Gate S? VarProjection2 S?)*;
                    (?<BooleanEquation>): Expression !.;
                "
                .Trim();

            AExpression ROOT = PEGrammar.Load(grammar);

            // 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;

#warning Assert.IsTrue(node.Token.Value == input);


            // 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;
#warning             Assert.IsTrue(node.Token.Value == input);

            // 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);
        }