public override ParseNode_Base Parse(SyntaxTreeBuilder pSyntaxTreeBuilder)
    {
        var ifNode = node as ParseNode_ManyOpt_If;

        if (ifNode != null)
        {
            if (!ifNode.Matches(pSyntaxTreeBuilder))
            {
                return(parent.NextAfterChild(this, pSyntaxTreeBuilder));
            }

            var tokenIndex = pSyntaxTreeBuilder.TokenScanner.CurrentTokenIndex;
            var line       = pSyntaxTreeBuilder.TokenScanner.CurrentLine;
            var nextNode   = node.Parse(pSyntaxTreeBuilder);
            if (nextNode != this || pSyntaxTreeBuilder.TokenScanner.CurrentTokenIndex != tokenIndex || pSyntaxTreeBuilder.TokenScanner.CurrentLine != line)
            {
                return(nextNode);
            }
            //Debug.Log("Exiting Many " + this + " in goal: " + pSyntaxTreeBuilder.CurrentParseTreeNode);
        }
        else
        {
            if (!FirstSet.Contains(pSyntaxTreeBuilder.TokenScanner.Current.tokenId))
            {
                return(parent.NextAfterChild(this, pSyntaxTreeBuilder));
            }

            var tokenIndex = pSyntaxTreeBuilder.TokenScanner.CurrentTokenIndex;
            var line       = pSyntaxTreeBuilder.TokenScanner.CurrentLine;
            var nextNode   = node.Parse(pSyntaxTreeBuilder);
            if (!(nextNode == this && pSyntaxTreeBuilder.TokenScanner.CurrentTokenIndex == tokenIndex && pSyntaxTreeBuilder.TokenScanner.CurrentLine == line))
            {
                // throw new Exception("Infinite loop!!! while parsing " + pSyntaxTreeBuilder.Current + " on line " + pSyntaxTreeBuilder.CurrentLine());
                return(nextNode);
            }
        }
        return(parent.NextAfterChild(this, pSyntaxTreeBuilder));
    }
    public override ParseNode_Base Parse(SyntaxTreeBuilder pSyntaxTreeBuilder)
    {
        bool           wasError = pSyntaxTreeBuilder.ErrorMessage != null;
        ParseNode_Base ret      = null;

        if (FirstSet.Contains(pSyntaxTreeBuilder.TokenScanner.Current))
        {
            ret = rhs.Parse(pSyntaxTreeBuilder);
        }
        if ((ret == null || !wasError && pSyntaxTreeBuilder.ErrorMessage != null) && !FirstSet.ContainsEmpty())
        {
            pSyntaxTreeBuilder.SyntaxErrorExpected(FirstSet);
            return(ret ?? this);
        }
        if (ret != null)
        {
            return(ret);
        }
        return(NextAfterChild(rhs, pSyntaxTreeBuilder)); // ready to be reduced
    }