Ejemplo n.º 1
0
        //
        // Helper function to extract an expression term from a token stream.
        //
        // Returns true if a term was found, and passes out the index of the
        // next token to examine. No tokens should be popped if this helper
        // returns false.
        //
        // Note that in cases where a terminating token is present, such as
        // a closing parenthesis or a comma, this will return false; however
        // this does not indicate a syntax error.
        //
        private static bool ParseExpressionTerm(ParseSession parser, bool atstart, int starttoken, out int consumedtokens, out bool matchedstatement)
        {
            matchedstatement = false;
            int totaltokens = starttoken;

            consumedtokens = totaltokens;

            if (parser.PeekToken(totaltokens) == null)
            {
                return(false);
            }

            if (parser.CheckToken(totaltokens, ")"))
            {
                return(false);
            }

            if (parser.CheckToken(totaltokens, ","))
            {
                return(false);
            }

            if (parser.CheckToken(totaltokens, "("))
            {
                ++totaltokens;
                if (Parse(parser, totaltokens, out totaltokens) != null)
                {
                    ++totaltokens;
                    consumedtokens = totaltokens;
                    return(true);
                }

                return(false);
            }

            if (parser.CheckToken(totaltokens, "!"))
            {
                ++totaltokens;
                var ret = ParseExpressionTerm(parser, atstart, totaltokens, out totaltokens, out matchedstatement);

                if (matchedstatement && parser.CheckToken(totaltokens, ")"))
                {
                    ++totaltokens;
                }

                consumedtokens = totaltokens;

                return(ret);
            }

            // The following check is a tiny optimization. Instead of trying to parse
            // a statement first and then eventually giving up, we first try checking
            // for common literals. This makes code with literals parse a fractional,
            // almost insignificant amount faster. It's actually a relic from the way
            // the compiler implements this logic. Maybe it makes sense to remove it,
            // and aim for simplicity over ideal efficiency. Profiling data is so far
            // insufficient to decide for sure, so this stays in the interim.
            if (parser.CheckToken(totaltokens, "false") || parser.CheckToken(totaltokens, "true") || parser.CheckToken(totaltokens, "0") || parser.CheckToken(totaltokens, "0.0"))
            {
                ++totaltokens;
            }
            else if (parser.ParsePreopStatement(totaltokens, out totaltokens))
            {
                consumedtokens = totaltokens;
                return(true);
            }
            else if (parser.ParseStatement(totaltokens, out totaltokens))
            {
                matchedstatement = true;
                consumedtokens   = totaltokens;
                return(true);
            }
            else
            {
                ++totaltokens;
            }

            consumedtokens = totaltokens;
            return(true);
        }