예제 #1
0
        public static IParsingResultExtended Parse(ParsingContext context)
        {
            RewindState            rewind = context.RewindState;
            IParsingResultExtended result = null;
            bool isResultTemplatePrefix   = false;

            while (!context.Parser.IsEnd)
            {
                bool isResultTemplatePrefixNext = false;

                switch (context.Parser.Peek)
                {
                case 'S':
                {
                    IParsingResultExtended substitution = Substitution.Parse(context);

                    if (substitution == null)
                    {
                        context.Rewind(rewind);
                        return(null);
                    }

                    result = substitution;
                }
                break;

                case 'T':
                {
                    IParsingResultExtended param = TemplateParam.Parse(context);

                    if (param == null)
                    {
                        context.Rewind(rewind);
                        return(null);
                    }

                    result = AddToSubstitutionTable(context, param);
                    isResultTemplatePrefixNext = true;
                }
                break;

                case 'D':
                {
                    IParsingResultExtended decltype = Decltype.Parse(context);

                    if (decltype != null)
                    {
                        result = AddToSubstitutionTable(context, decltype);
                    }
                    else
                    {
                        IParsingResultExtended name = UnqualifiedName.Parse(context);

                        if (name == null)
                        {
                            context.Rewind(rewind);
                            return(null);
                        }

                        if (result != null)
                        {
                            result = AddToSubstitutionTable(context, new NestedName(result, name));
                        }
                        else
                        {
                            result = AddToSubstitutionTable(context, name);
                        }
                        isResultTemplatePrefixNext = true;
                    }
                }
                break;

                default:
                    if (context.Parser.Peek == 'I' && result != null && isResultTemplatePrefix)
                    {
                        TemplateArgs arguments = TemplateArgs.Parse(context);

                        if (arguments == null)
                        {
                            context.Rewind(rewind);
                            return(null);
                        }

                        result = AddToSubstitutionTable(context, new Template(result, arguments));
                    }
                    else if (result != null && SourceName.StartsWith(context))
                    {
                        Debug.Assert(UnqualifiedName.StartsWith(context));
                        Debug.Assert(DataMemberPrefix.StartsWith(context));

                        IParsingResultExtended name = SourceName.Parse(context);

                        if (name == null)
                        {
                            context.Rewind(rewind);
                            return(null);
                        }

                        if (context.Parser.VerifyString("M"))
                        {
                            result = AddToSubstitutionTable(context, new DataMember(result, name));
                        }
                        else
                        {
                            if (result != null)
                            {
                                result = AddToSubstitutionTable(context, new NestedName(result, name));
                            }
                            else
                            {
                                result = AddToSubstitutionTable(context, name);
                            }
                            isResultTemplatePrefixNext = true;
                        }
                    }
                    else if (UnqualifiedName.StartsWith(context))
                    {
                        IParsingResultExtended name = UnqualifiedName.Parse(context);

                        if (name == null)
                        {
                            context.Rewind(rewind);
                            return(null);
                        }

                        if (result != null)
                        {
                            result = AddToSubstitutionTable(context, new NestedName(result, name));
                        }
                        else
                        {
                            result = AddToSubstitutionTable(context, name);
                        }
                        isResultTemplatePrefixNext = true;
                    }
                    else
                    {
                        if (result != null)
                        {
                            return(result);
                        }

                        context.Rewind(rewind);
                        return(null);
                    }
                    break;
                }
                isResultTemplatePrefix = isResultTemplatePrefixNext;
            }

            return(result);
        }
예제 #2
0
        public static IParsingResult Parse(ParsingContext context)
        {
            RewindState rewind = context.RewindState;

            if (context.Parser.VerifyString("pp_"))
            {
                return(Parse <PrefixInc>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("mm_"))
            {
                return(Parse <PrefixDec>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("cl"))
            {
                return(Parse <Call>(rewind, context, Expression.Parse, ZeroOrMore(Expression.Parse)));
            }
            if (context.Parser.VerifyString("cv"))
            {
                IParsingResult type = Type.Parse(context);

                if (type != null)
                {
                    if (context.Parser.VerifyString("_"))
                    {
                        List <IParsingResult> expressions = CxxDemangler.ParseList(Expression.Parse, context);

                        if (context.Parser.VerifyString("E"))
                        {
                            return(new ConversionMany(type, expressions));
                        }
                    }
                    else
                    {
                        IParsingResult expression = Expression.Parse(context);

                        if (expression != null)
                        {
                            return(new ConversionOne(type, expression));
                        }
                    }
                }
                context.Rewind(rewind);
                return(null);
            }
            if (context.Parser.VerifyString("tl"))
            {
                return(ParseWithEnd <ConversionBraced>(rewind, context, Type.Parse, ZeroOrMore(Expression.Parse)));
            }
            if (context.Parser.VerifyString("il"))
            {
                return(ParseWithEnd <BracedInitList>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("dc"))
            {
                return(Parse <DynamicCast>(rewind, context, Type.Parse, Expression.Parse));
            }
            if (context.Parser.VerifyString("sc"))
            {
                return(Parse <StaticCast>(rewind, context, Type.Parse, Expression.Parse));
            }
            if (context.Parser.VerifyString("cc"))
            {
                return(Parse <ConstCast>(rewind, context, Type.Parse, Expression.Parse));
            }
            if (context.Parser.VerifyString("rc"))
            {
                return(Parse <ReinterpretCast>(rewind, context, Type.Parse, Expression.Parse));
            }
            if (context.Parser.VerifyString("ti"))
            {
                return(Parse <TypeIdType>(rewind, context, Type.Parse));
            }
            if (context.Parser.VerifyString("te"))
            {
                return(Parse <TypeIdExpression>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("st"))
            {
                return(Parse <SizeOfType>(rewind, context, Type.Parse));
            }
            if (context.Parser.VerifyString("sz"))
            {
                return(Parse <SizeOfExpression>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("at"))
            {
                return(Parse <AlignOfType>(rewind, context, Type.Parse));
            }
            if (context.Parser.VerifyString("az"))
            {
                return(Parse <AlignOfExpression>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("nx"))
            {
                return(Parse <Noexcept>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("dt"))
            {
                return(Parse <Member>(rewind, context, Expression.Parse, UnresolvedName.Parse));
            }
            if (context.Parser.VerifyString("pt"))
            {
                return(Parse <DeferMember>(rewind, context, Expression.Parse, UnresolvedName.Parse));
            }
            if (context.Parser.VerifyString("ds"))
            {
                return(Parse <PointerToMember>(rewind, context, Expression.Parse, Expression.Parse));
            }
            if (context.Parser.VerifyString("sZ"))
            {
                IParsingResult param = TemplateParam.Parse(context);

                if (param != null)
                {
                    return(new SizeOfTemplatepack(param));
                }
                param = FunctionParam.Parse(context);
                if (param != null)
                {
                    return(new SizeOfFunctionPack(param));
                }
                context.Rewind(rewind);
                return(null);
            }
            if (context.Parser.VerifyString("sP"))
            {
                return(ParseWithEnd <SizeofCapturedTemplatePack>(rewind, context, ZeroOrMore(TemplateArg.Parse)));
            }
            if (context.Parser.VerifyString("sp"))
            {
                return(Parse <PackExpansion>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("tw"))
            {
                return(Parse <Throw>(rewind, context, Expression.Parse));
            }
            if (context.Parser.VerifyString("tr"))
            {
                return(new Retrow());
            }
            if (context.Parser.VerifyString("gs"))
            {
                return(CanBeGlobal(rewind, context, true));
            }

            IParsingResult result = CanBeGlobal(rewind, context, false) ?? TemplateParam.Parse(context) ?? FunctionParam.Parse(context)
                                    ?? UnresolvedName.Parse(context) ?? ExprPrimary.Parse(context);

            if (result != null)
            {
                return(result);
            }

            IParsingResult operatorName = OperatorName.Parse(context);

            if (operatorName != null)
            {
                IParsingResult first = Expression.Parse(context);

                if (first != null)
                {
                    IParsingResult second = Expression.Parse(context);

                    if (second != null)
                    {
                        IParsingResult third = Expression.Parse(context);

                        if (third != null)
                        {
                            return(new Ternary(operatorName, first, second, third));
                        }
                        else
                        {
                            return(new Binary(operatorName, first, second));
                        }
                    }
                    else
                    {
                        return(new Unary(operatorName, first));
                    }
                }
                context.Rewind(rewind);
                return(null);
            }
            return(null);
        }