public bool ParseStep(SyntaxTreeBuilder pSyntaxTreeBuilder)
    {
        if (pSyntaxTreeBuilder.ParseNode_Cur == null)
        {
            return(false);
        }

        var token = pSyntaxTreeBuilder.TokenScanner.Current;

        if (pSyntaxTreeBuilder.ErrorMessage == null)
        {
            while (pSyntaxTreeBuilder.ParseNode_Cur != null)
            {
                pSyntaxTreeBuilder.ParseNode_Cur = pSyntaxTreeBuilder.ParseNode_Cur.Parse(pSyntaxTreeBuilder);
                if (pSyntaxTreeBuilder.ErrorMessage != null || token != pSyntaxTreeBuilder.TokenScanner.Current)
                {
                    break;
                }
            }

            if (pSyntaxTreeBuilder.ErrorMessage == null && token != pSyntaxTreeBuilder.TokenScanner.Current)
            {
                pSyntaxTreeBuilder.SyntaxRule_Err = pSyntaxTreeBuilder.SyntaxRule_Cur;
                pSyntaxTreeBuilder.ParseNode_Err  = pSyntaxTreeBuilder.ParseNode_Cur;
            }
        }
        if (pSyntaxTreeBuilder.ErrorMessage != null)
        {
            if (token.tokenKind == LexerToken.Kind.EOF)
            {
                return(false);
            }

            var missingParseTreeNode = pSyntaxTreeBuilder.SyntaxRule_Cur;
            var missingParseNode     = pSyntaxTreeBuilder.ParseNode_Cur;

            pSyntaxTreeBuilder.SyntaxRule_Cur = pSyntaxTreeBuilder.SyntaxRule_Err;
            pSyntaxTreeBuilder.ParseNode_Cur  = pSyntaxTreeBuilder.ParseNode_Err;
            if (pSyntaxTreeBuilder.SyntaxRule_Cur != null)
            {
                var cpt = pSyntaxTreeBuilder.SyntaxRule_Cur;
                for (var i = cpt.NumValidNodes; i > 0 && !cpt.ChildAt(--i).HasLeafs();)
                {
                    cpt.InvalidateFrom(i);
                }
            }

            if (pSyntaxTreeBuilder.ParseNode_Cur != null)
            {
                int numSkipped;
                pSyntaxTreeBuilder.ParseNode_Cur = pSyntaxTreeBuilder.ParseNode_Cur.Recover(pSyntaxTreeBuilder, out numSkipped);
            }
            if (pSyntaxTreeBuilder.ParseNode_Cur == null)
            {
                if (token.m_kLinkedLeaf != null)
                {
                    token.m_kLinkedLeaf.ReparseToken();
                }
                new SyntaxTreeNode_Leaf(pSyntaxTreeBuilder.TokenScanner);

                if (cachedErrorParseNode == pSyntaxTreeBuilder.ParseNode_Err)
                {
                    token.m_kLinkedLeaf.m_sSyntaxError = cachedErrorMessage;
                }
                else
                {
                    token.m_kLinkedLeaf.m_sSyntaxError = "Unexpected token! Expected " + pSyntaxTreeBuilder.ParseNode_Err.FirstSet.ToString(this);
                    cachedErrorMessage   = token.m_kLinkedLeaf.m_sSyntaxError;
                    cachedErrorParseNode = pSyntaxTreeBuilder.ParseNode_Err;
                }

                pSyntaxTreeBuilder.ParseNode_Cur  = pSyntaxTreeBuilder.ParseNode_Err;
                pSyntaxTreeBuilder.SyntaxRule_Cur = pSyntaxTreeBuilder.SyntaxRule_Err;

                if (!pSyntaxTreeBuilder.TokenScanner.MoveNext())
                {
                    return(false);
                }
                pSyntaxTreeBuilder.ErrorMessage = null;
            }
            else
            {
                if (missingParseNode != null && missingParseTreeNode != null)
                {
                    pSyntaxTreeBuilder.SyntaxRule_Cur = missingParseTreeNode;
                    pSyntaxTreeBuilder.ParseNode_Cur  = missingParseNode;
                }

                pSyntaxTreeBuilder.InsertMissingToken(pSyntaxTreeBuilder.ErrorMessage
                                                      ?? ("Expected " + missingParseNode.FirstSet.ToString(this)));

                if (missingParseNode != null && missingParseTreeNode != null)
                {
                    pSyntaxTreeBuilder.ErrorMessage   = null;
                    pSyntaxTreeBuilder.ErrorToken     = null;
                    pSyntaxTreeBuilder.SyntaxRule_Cur = missingParseTreeNode;
                    pSyntaxTreeBuilder.ParseNode_Cur  = missingParseNode;
                    pSyntaxTreeBuilder.ParseNode_Cur  = missingParseNode.parent.NextAfterChild(missingParseNode, pSyntaxTreeBuilder);
                }
                pSyntaxTreeBuilder.ErrorMessage = null;
                pSyntaxTreeBuilder.ErrorToken   = null;
            }
        }

        return(true);
    }