예제 #1
0
        private static void TestXPathParser()
        {
            var parser  = new XPathParser <string>();
            var builder = new XPathStringBuilder();
            Queue <IXPathPart> queue;

            parser.Parse("/Person[@FirstName]", builder);

            queue = builder.PartQueue;

            foreach (var part in queue)
            {
                var debugInfo = part.ToString();
            }

            parser  = new XPathParser <string>();
            builder = new XPathStringBuilder();

            parser.Parse("$ABCCompany/Person[@FirstName]", builder);

            queue = builder.PartQueue;

            foreach (var part in queue)
            {
                var debugInfo = part.ToString();
            }
        }
예제 #2
0
        private void VerifyXPath()
        {
            string Xpath = mAction.ElementLocateValue;

            try
            {
                XPathParser <XElement> xpp = new XPathParser <XElement>();
                XElement xe1 = xpp.Parse(Xpath, new XPathTreeBuilder());
                xpp.GetOKPath();

                XElement xe = new XPathParser <XElement>().Parse(Xpath, new XPathTreeBuilder());

                XmlWriterSettings ws = new XmlWriterSettings();
                {
                    ws.Indent             = true;
                    ws.OmitXmlDeclaration = true;
                }
                StringBuilder sb = new StringBuilder();
                using (XmlWriter w = XmlWriter.Create(sb, ws))
                {
                    xe.WriteTo(w);
                }

                ResultLabel.Content = sb.ToString();
            }
            catch (Exception e)
            {
                ResultLabel.Content = e.Message;
            }
        }
예제 #3
0
        /*
         *   Predicate ::= '[' Expr ']'
         */
        private QilNode ParsePredicate(QilNode context)
        {
            Debug.Assert(_scanner.Kind == LexKind.LBracket);
            _scanner.NextLex();
            QilNode result = _predicateParser.Parse(_scanner, _ptrnBuilder.GetPredicateBuilder(context), LexKind.RBracket);

            Debug.Assert(_scanner.Kind == LexKind.RBracket);
            _scanner.NextLex();
            return(result);
        }
예제 #4
0
        public void TestXPath010()
        {
            AdkXPathStep[] steps = XPathParser.Parse("Foo");

            Assert.AreEqual(1, steps.Length);
            Assert.AreEqual("Foo", ((AdkNodeNameTest)steps[0].NodeTest).NodeName);

            steps = XPathParser.Parse("/Foo");
            Assert.AreEqual(1, steps.Length);
            Assert.AreEqual("Foo", ((AdkNodeNameTest)steps[0].NodeTest).NodeName);

            Console.WriteLine(steps[0]);
        }
예제 #5
0
        public QueryPathAttribute(string xpathExpression, QueryKind kind = QueryKind.None)
        {
            var parser  = new XPathParser <string>();
            var builder = new XPathStringBuilder();
            var id      = string.Empty;
            var path    = xpathExpression;

            this.XPathExpression = xpathExpression;
            this.QueryPathKind   = kind;

            parser.Parse(path, builder);

            this.PartQueue = builder.PartQueue;
        }
예제 #6
0
        private static List <GameObject> FindStartBag(string body, HttpListenerResponse response)
        {
            FindBody findBody = ParseFindElementBody(body, response);

            if (findBody == null)
            {
                return(null);
            }

            var steps = parser.Parse(findBody.selector);
            var step  = steps [0];

            Type type = parser.FindType(step.TagName);

            if (type == null)
            {
                //no type, we need to return an empty result test
                return(new List <GameObject>());
            }

            var tmpList = GameObject.FindObjectsOfType(type);

            List <GameObject> rootBag = new List <GameObject> ();

            //we need only root objects for this
            foreach (var obj in tmpList)
            {
                Component comp = obj as Component;

                if (comp == null)
                {
                    continue;
                }

                if (step.IsChild == true)
                {
                    if (comp.gameObject.transform.parent == null)
                    {
                        rootBag.Add(comp.gameObject);
                    }
                }
                else
                {
                    rootBag.Add(comp.gameObject);
                }
            }


            return(rootBag);
        }
예제 #7
0
        public void TestXPath020()
        {
            AdkXPathStep[] steps = XPathParser.Parse("Foo/Bar/Win");

            Assert.AreEqual(3, steps.Length);
            Assert.AreEqual("Foo", ((AdkNodeNameTest)steps[0].NodeTest).NodeName);
            Assert.AreEqual("Bar", ((AdkNodeNameTest)steps[1].NodeTest).NodeName);
            Assert.AreEqual("Win", ((AdkNodeNameTest)steps[2].NodeTest).NodeName);

            steps = XPathParser.Parse("/Foo/Bar/Win");
            Assert.AreEqual(3, steps.Length);
            Assert.AreEqual("Foo", ((AdkNodeNameTest)steps[0].NodeTest).NodeName);
            Assert.AreEqual("Bar", ((AdkNodeNameTest)steps[1].NodeTest).NodeName);
            Assert.AreEqual("Win", ((AdkNodeNameTest)steps[2].NodeTest).NodeName);
        }
예제 #8
0
        public void TestXPath040()
        {
            String path = "Foo[@Win='2']/Bar";

            AdkXPathStep[] steps = XPathParser.Parse(path);

            Assert.AreEqual(2, steps.Length);
            AssertStep(steps[0], "Foo", "Win", "2");
            Assert.AreEqual("Bar", ((AdkNodeNameTest)steps[1].NodeTest).NodeName);


            steps = XPathParser.Parse("/" + path);
            Assert.AreEqual(2, steps.Length);
            AssertStep(steps[0], "Foo", "Win", "2");
            Assert.AreEqual("Bar", ((AdkNodeNameTest)steps[1].NodeTest).NodeName);
        }
예제 #9
0
        public static IQueryable <T> GenerateByID <T>(this IProviderService service, string id)
        {
            var queue   = new Queue <string>();
            var parser  = new XPathParser <string>();
            var builder = new XPathStringBuilder();

            parser.Parse(id, builder);

            var axisElement = builder.AxisElementQueue.Last();

            var method = service.GetType().GetMethods().Single(m => m.ReturnType.Name == "IQueryable`1" && m.GetParameters().Length == 0 && m.ReturnType.GetGenericArguments().Any(a => a.Name == axisElement.Element));

            service.LogGenerateByID(id, method);

            var results = (IQueryable <IBase>)method.Invoke(service, null);

            service.PostLogGenerateByID();

            return(results.Where(b => b.ID == id).Cast <T>());
        }
예제 #10
0
        public static string GetID(this IBase baseObject)
        {
            if (CodeInterfaceExtensions.DebugInfoShowOptions.HasFlag(DebugInfoShowOptions.ShowCondensedID))
            {
                var parser  = new XPathParser <string>();
                var builder = new XPathStringBuilder();
                var id      = string.Empty;

                parser.Parse(baseObject.ID, builder);

                id  = string.Join("../", builder.AxisElementQueue.Select(e => e.Element));
                id += "[" + builder.AxisElementQueue.Last().Predicates.First().ToString() + "]";

                return(id);
            }
            else
            {
                return(baseObject.ID);
            }
        }
예제 #11
0
        public void TestXPath030()
        {
            String path = "Foo[@Win='2']/Bar[Type=5]/Win[Zone=\"yada\"]";

            AdkXPathStep[] steps = XPathParser.Parse(path);

            Assert.AreEqual(3, steps.Length);
            AssertStep(steps[0], "Foo", "Win", "2");
            AssertStep(steps[1], "Bar", "Type", 5);
            AssertStep(steps[2], "Win", "Zone", "yada");

            Console.WriteLine(steps[0] + "/" + steps[1] + "/" + steps[2]);


            steps = XPathParser.Parse("/" + path);
            Assert.AreEqual(3, steps.Length);
            AssertStep(steps[0], "Foo", "Win", "2");
            AssertStep(steps[1], "Bar", "Type", 5);
            AssertStep(steps[2], "Win", "Zone", "yada");
        }
예제 #12
0
        public static string GetID(this IBase baseObject)
        {
            if (AbstraXExtensions.DebugInfoShowOptions.HasFlag(DebugInfoShowOptions.ShowCondensedID))
            {
                var parser = new XPathParser<string>();
                var builder = new XPathStringBuilder();
                var id = string.Empty;

                parser.Parse(baseObject.ID, builder);

                id = string.Join("../", builder.PartQueue.OfType<XPathElement>().Select(e => e.Text));
                id += "[" + builder.PartQueue.OfType<XPathElement>().Last().Predicates.First().ToString() + "]";

                return id;
            }
            else
            {
                return baseObject.ID;
            }
        }
예제 #13
0
        public static IBase GenerateByID(this IAbstraXProviderService service, string id)
        {
            var queue = new Queue<string>();
            var parser = new XPathParser<string>();
            var builder = new XPathStringBuilder();

            parser.Parse(id, builder);

            if (builder.PartQueue.Count == 1)
            {
                var axisElement = builder.PartQueue.OfType<XPathElement>().Single();

                var method = service.GetType().GetMethods().Single(m => m.ReturnType.Name == axisElement.Text && m.GetParameters().Length == 0);

                service.LogGenerateByID(id, method);

                var rootObject = (IBase)method.Invoke(service, null);

                service.PostLogGenerateByID();

                return rootObject;
            }
            else
            {
                var axisElement = builder.PartQueue.OfType<XPathElement>().Last();

                var method = service.GetType().GetMethods().Single(m => m.ReturnType.Name == "IQueryable`1" && m.GetParameters().Length == 0 && m.ReturnType.GetGenericArguments().Any(a => a.Name == axisElement.Text));

                service.LogGenerateByID(id, method);

                var results = (IQueryable<IBase>)method.Invoke(service, null);

                service.PostLogGenerateByID();

                return results.Where(b => b.ID == id).Single();
            }
        }
예제 #14
0
        /// <summary>
        /// Manually builds out a path to support the necessary mapping needs of the
        /// ADK. By default, the JXPath implementation does not allow
        /// context-dependend predicates (e.g. PhoneNumber[@Type='0096'] to be used
        /// in XPaths that create the path. This implementation manually steps
        /// through the XPath and builds it out. It's primary intent is to provide
        /// the behavior that was present in the ADK before JXPath was used for
        /// mapping
        /// </summary>
        /// <param name="expr">The Path expression to build out</param>
        /// <param name="context"></param>
        /// <returns></returns>
        private INodePointer BuildADKPathWithPredicates(String expr, XsltContext context)
        {
            // Use the set of expression steps to determine which parts of the
            // path already exist. Note that the order of evaluation used is optimized
            // for first-time creation of elements. In other words, the path chosen was
            // to evalaute the expression steps from the beginning rather than the end
            // because for outbound mappings, that order will generally be the most efficient
            AdkXPathStep[] steps       = XPathParser.Parse(expr);
            int            currentStep = 0;
            StringBuilder  pathSoFar   = new StringBuilder();
            INodePointer   parent      = fContextPointer;
            INodePointer   current     = null;

            for ( ; currentStep < steps.Length; currentStep++)
            {
                current = FindChild(fDefaultNavigator, pathSoFar, steps[currentStep]);
                if (current == null)
                {
                    break;
                }
                pathSoFar.Append("/");
                pathSoFar.Append(steps[currentStep].ToString());
                parent = current;
            }
            if (current != null)
            {
                // We traversed the entire path and came up with a result.
                // That means that the element we are trying to build the
                // path to already exists. We will not create this path, so
                // return null;
                return(null);
            }

            // We've traversed down to the level where we think we need to
            // add a child. However, there are cases where this is not the proper
            // location. For example, in SIF 1.5r1, the StudentAddressList element is
            // repeatable and Address is not. It would not be proper to add a new Address
            // element under StudentAddressList. Instead, the algorithm needs to back
            // up the stack until it reaches the next repeatable element for the current
            // version of SIF
            // The following code is primarily in place for the StudentAddressList case, which is
            // why the isContextDependent() logic applies. Currently, there is no known other place
            // where this checking needs to occur.
            if (currentStep > 0 && steps[currentStep].IsContextDependent())
            {
                int          step       = currentStep;
                INodePointer stepParent = parent;
                while (step > -1)
                // don't evaluate step 0 at the root of the object because this problem doesn't apply there
                {
                    if (parent is SifElementPointer)
                    {
                        SifElementPointer sifParentPointer = (SifElementPointer)stepParent;
                        AdkNodeTest       nt = steps[step].NodeTest;
                        if (nt is AdkNodeNameTest)
                        {
                            SifElementPointer.AddChildDirective result =
                                sifParentPointer.GetAddChildDirective(((AdkNodeNameTest)nt).NodeName);
                            if (result != SifElementPointer.AddChildDirective.DONT_ADD_NOT_REPEATABLE)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                    step--;
                    stepParent = stepParent.Parent;
                }
                if (step > -1 && step != currentStep)
                {
                    currentStep = step;
                    parent      = stepParent;
                }
            }

            // At this point, we have a parent element and the index of the current
            // step to evaluate
            //InitialContext context = new InitialContext( new RootContext( this, (NodePointer) getContextPointer()));
            for ( ; currentStep < steps.Length; currentStep++)
            {
                AdkNodeTest nt = steps[currentStep].NodeTest;
                if (nt is AdkNodeNameTest)
                {
                    current = parent.CreateChild(this, ((AdkNodeNameTest)nt).NodeName, 0);
                    if (current == null)
                    {
                        throw new ArgumentException("Cannot evaluate expression step: " + steps[currentStep]);
                    }
                    foreach (AdkExpression predicate in steps[currentStep].Predicates)
                    {
                        CreatePredicateValues(current, predicate, context);
                    }
                }
                else
                {
                    throw new ArgumentException("Cannot evaluate expression step: " + steps[currentStep]);
                }

                parent = current;
            }
            // At the end, the 'parent' variable will contain the last element created by this function
            return(parent);
        }
예제 #15
0
        private void ParserTests()
        {
            Debug.Log("starting parser tests");

            var parser = new XPathParser();

            float startTime = Time.realtimeSinceStartup;

            var results = parser.Parse("books");

            Debug.Assert(results.Count == 1);
            Debug.Assert(results [0].TagName == "books");
            Debug.Assert(results [0].IsChild == false);
            Debug.Assert(results [0].predicates.Count == 0);

            results = parser.Parse("//books");

            Debug.Assert(results.Count == 1);
            Debug.Assert(results [0].TagName == "books");
            Debug.Assert(results [0].IsChild == false);
            Debug.Assert(results [0].predicates.Count == 0);

            results = parser.Parse("/books/book");

            Debug.Assert(results.Count == 2);
            Debug.Assert(results [0].TagName == "books");
            Debug.Assert(results [0].IsChild == true);
            Debug.Assert(results [0].predicates.Count == 0);
            Debug.Assert(results [1].TagName == "book");
            Debug.Assert(results [1].IsChild == true);
            Debug.Assert(results [1].predicates.Count == 0);

            results = parser.Parse("books//letter");

            Debug.Assert(results.Count == 2);
            Debug.Assert(results [0].TagName == "books");
            Debug.Assert(results [0].IsChild == false);
            Debug.Assert(results [0].predicates.Count == 0);
            Debug.Assert(results [1].TagName == "letter");
            Debug.Assert(results [1].IsChild == false);
            Debug.Assert(results [1].predicates.Count == 0);


            results = parser.Parse("somescript/uilabel[3]");

            Debug.Assert(results.Count == 2);
            Debug.Assert(results [0].TagName == "somescript");
            Debug.Assert(results [0].IsChild == false);
            Debug.Assert(results [0].predicates.Count == 0);
            Debug.Assert(results [1].TagName == "uilabel");
            Debug.Assert(results [1].IsChild == true);
            Debug.Assert(results [1].predicates.Count == 1);
            Debug.Assert(results [1].predicates[0] is XPathNumberPredicate);
            Debug.Assert((results [1].predicates[0] as XPathNumberPredicate).Number == 3);

            results = parser.Parse("otherscript//uilabel[@text=\"something\"]");

            Debug.Assert(results.Count == 2);
            Debug.Assert(results [0].TagName == "otherscript");
            Debug.Assert(results [0].IsChild == false);
            Debug.Assert(results [0].predicates.Count == 0);
            Debug.Assert(results [1].TagName == "uilabel");
            Debug.Assert(results [1].IsChild == false);
            Debug.Assert(results [1].predicates.Count == 1);
            Debug.Assert(results [1].predicates[0] is XPathAttribute);
            Debug.Assert((results [1].predicates[0] as XPathAttribute).Name == "text");
            Debug.Assert((results [1].predicates[0] as XPathAttribute).ValueToMatch == "something");

            results = parser.Parse("/otherscript/uilabel[@text=\"something\" and @lang=\"en\"]");

            Debug.Assert(results.Count == 2);
            Debug.Assert(results [0].TagName == "otherscript");
            Debug.Assert(results [0].IsChild == true);
            Debug.Assert(results [0].predicates.Count == 0);
            Debug.Assert(results [1].TagName == "uilabel");
            Debug.Assert(results [1].IsChild == true);
            Debug.Assert(results [1].predicates.Count == 2);
            Debug.Assert(results [1].predicates[0] is XPathAttribute);
            Debug.Assert((results [1].predicates[0] as XPathAttribute).Name == "text");
            Debug.Assert((results [1].predicates[0] as XPathAttribute).ValueToMatch == "something");
            Debug.Assert(results [1].predicates[1] is XPathAttribute);
            Debug.Assert((results [1].predicates[1] as XPathAttribute).Name == "lang");
            Debug.Assert((results [1].predicates[1] as XPathAttribute).ValueToMatch == "en");

            Debug.Log("time " + (Time.realtimeSinceStartup - startTime));

            Debug.Log("end parser test");
        }
예제 #16
0
        STb <FuncDecl, Expr, Sort> Generate()
        {
            var name = DeclarationType.ContainingNamespace.Name + "." +
                       (DeclarationType.ContainingType == null ? "" : DeclarationType.ContainingType.Name + ".") + DeclarationType.Name;

            Console.WriteLine("XPath " + name);

            var        parser = new XPathParser <IXPathNode>();
            IXPathNode root;

            try
            {
                root = parser.Parse(_xpath, new XPathNodeBuilder());
                Console.WriteLine(root);
            }
            catch (XPathParserException e)
            {
                throw new TransducerCompilationException("XPath parsing failed", e);
            }

            var resultSort       = _ctx.MkBitVecSort(32);
            var levelCounterSort = _ctx.MkBitVecSort(32);
            var regSort          = _ctx.MkTupleSort(resultSort, levelCounterSort);
            var initReg          = _ctx.MkTuple(_ctx.MkNumeral(0, resultSort), _ctx.MkNumeral(0, levelCounterSort));

            var        stb       = new STb <FuncDecl, Expr, Sort>(_ctx, "stb", _ctx.CharSort, _ctx.MkBitVecSort(32), regSort, initReg, 0);
            int        freeState = 1;
            Func <int> nextState = () => freeState++;

            var resultProj       = _ctx.MkProj(0, stb.RegVar);
            var levelCounterProj = _ctx.MkProj(1, stb.RegVar);

            Func <int, IgnorerInfo> CreateIgnorer = (exitState) =>
            {
                IgnorerInfo info = new IgnorerInfo();

                int outsideTagState    = nextState();
                int freshTagState      = nextState();
                int openingTagState    = nextState();
                int standaloneTagState = nextState();
                int closingTagState    = nextState();

                stb.AssignRule(outsideTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, freshTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, outsideTagState)));

                stb.AssignRule(freshTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState)));

                var counterOne      = _ctx.MkNumeral(1, levelCounterSort);
                var levelCounterInc = _ctx.MkTuple(resultProj, _ctx.MkBvAdd(levelCounterProj, counterOne));
                stb.AssignRule(openingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterInc, outsideTagState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState))));

                var counterZero        = _ctx.MkNumeral(0, levelCounterSort);
                var levelCounterZeroed = _ctx.MkTuple(resultProj, counterZero);
                stb.AssignRule(standaloneTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new IteRule <Expr>(_ctx.MkEq(levelCounterProj, counterZero),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, exitState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, outsideTagState)),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState))));

                var levelCounterDec = _ctx.MkTuple(resultProj, _ctx.MkBvSub(levelCounterProj, counterOne));
                stb.AssignRule(closingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new IteRule <Expr>(_ctx.MkEq(levelCounterProj, counterOne),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, exitState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterDec, outsideTagState)),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState)));

                info.MoveToTagOpening             = new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, openingTagState);
                info.MoveToTagOpeningOrStandalone = new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, standaloneTagState),
                                                                       info.MoveToTagOpening);
                var levelCounterSet = _ctx.MkTuple(resultProj, counterOne);
                info.MoveToOutsideTag = new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterSet, outsideTagState);

                return(info);
            };

            var next        = root;
            int?parentState = null;
            int startState  = stb.InitialState;
            int childState  = nextState();
            var zeroResult  = _ctx.MkTuple(_ctx.MkNumeral(0, resultSort), levelCounterProj);

            while (next != null)
            {
                XPathAxisNode current;
                var           step = next as XPathStepNode;
                if (step != null)
                {
                    current = step.Left as XPathAxisNode;
                    next    = step.Right;
                }
                else
                {
                    current = next as XPathAxisNode;
                    next    = null;
                }

                if (current.Axis == XPathAxis.Root)
                {
                    continue;
                }

                if (current == null)
                {
                    throw new TransducerCompilationException("Unsupported XPath node type: " + next.GetType());
                }
                if (current.Axis != XPathAxis.Child)
                {
                    throw new TransducerCompilationException("Unsupported axis: " + current.Axis);
                }
                if (current.Type != System.Xml.XPath.XPathNodeType.Element)
                {
                    throw new TransducerCompilationException("Unsupported node type: " + current.Type);
                }

                int freshTagState             = nextState();
                int closingTagState           = nextState();
                int standaloneMatchState      = nextState();
                int matchedOpeningTagState    = nextState();
                int matchedStandaloneTagState = nextState();
                var ignorer = CreateIgnorer(startState);

                stb.AssignRule(startState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, freshTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState)));

                int  matchState     = freshTagState;
                int  nextMatchState = nextState();
                bool first          = true;
                foreach (char c in current.Label)
                {
                    STbRule <Expr> matchRule;

                    if (first)
                    {
                        matchRule = new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState),
                                                       new IteRule <Expr>(EqualsChar(stb.InputVar, c),
                                                                          new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, nextMatchState),
                                                                          new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                                                             ignorer.MoveToOutsideTag,
                                                                                             ignorer.MoveToTagOpening)));
                        first = false;
                    }
                    else
                    {
                        matchRule = new IteRule <Expr>(EqualsChar(stb.InputVar, c),
                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, nextMatchState),
                                                       new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                                          ignorer.MoveToOutsideTag,
                                                                          ignorer.MoveToTagOpeningOrStandalone));
                    }

                    stb.AssignRule(matchState, matchRule);
                    matchState     = nextMatchState;
                    nextMatchState = nextState();
                }

                stb.AssignRule(closingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  parentState != null ? (STbRule <Expr>) new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, parentState.Value) : new UndefRule <Expr>(),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState)));

                stb.AssignRule(matchState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, zeroResult, childState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, ' '),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState),
                                                                     new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                                        new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneMatchState),
                                                                                        ignorer.MoveToTagOpening))));

                stb.AssignRule(standaloneMatchState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState),
                                                  new UndefRule <Expr>()));

                stb.AssignRule(matchedOpeningTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, zeroResult, childState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedStandaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState))));

                stb.AssignRule(matchedStandaloneTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedStandaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState))));

                parentState = startState;
                startState  = childState;
                childState  = nextState();
            }

            Func <Expr, Expr> AddZeros = (c) =>
            {
                uint k = (uint)(32 - (int)_ctx.CharSetProvider.Encoding);
                if (k == 0)
                {
                    return(c);
                }
                else
                {
                    return(_ctx.MkZeroExt(k, c));
                }
            };
            var toIntUpdate = _ctx.MkTuple(
                _ctx.MkBvAdd(_ctx.MkBvMul(_ctx.MkNumeral(10, resultSort), resultProj), _ctx.MkBvSub(AddZeros(stb.InputVar), _ctx.MkNumeral((int)'0', resultSort))),
                levelCounterProj);

            var expectSlashState = nextState();
            var scanTagState     = nextState();

            stb.AssignRule(startState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                              new BaseRule <Expr>(new Sequence <Expr>(resultProj), zeroResult, expectSlashState),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, toIntUpdate, startState)));

            stb.AssignRule(expectSlashState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, scanTagState),
                                              new UndefRule <Expr>()));

            stb.AssignRule(scanTagState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                              parentState != null ? (STbRule <Expr>) new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, parentState.Value) : new UndefRule <Expr>(),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, scanTagState)));

            Console.WriteLine(stb.StateCount);

            foreach (var state in stb.States)
            {
                stb.AssignFinalRule(state, new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, state));
            }

            if (ShowGraphStages.Count > 0)
            {
                stb.ToST().ShowGraph();
            }
            return(stb);
        }