Esempio n. 1
0
        public Expression ParseExpression(int precedence = 0)
        {
            var             token = Take();
            IPrefixParselet prefix;
            IInfixParselet  infix;

            if (!PrefixParselets.TryGetValue(token.ID, out prefix))
            {
                throw new RantException(_src, token, "Invalid expression '\{token.Value}'.");
            }

            var left = prefix.Parse(this, token);

            // Break when the next token's precedence is less than or equal to the current precedence
            // This will assure that higher precedence operations like multiplication are parsed before lower operations.
            while (GetPrecedence() > precedence)
            {
                token = Take();
                if (!InfixParselets.TryGetValue(token.ID, out infix))
                {
                    throw new RantException(_src, token, "Invalid operator '\{token.Value}'.");
                }

                // Replace the left expression with the next parsed expression.
                left = infix.Parse(this, left, token);
            }

            return(left);
        }
Esempio n. 2
0
 /// <summary>
 /// Registers a token type to a new BinaryOperatorParselet
 /// </summary>
 /// <param name="opToken">Token type to register</param>
 /// <param name="precedence">Precedence of operator</param>
 /// <param name="rightAssociative">If the operator is right-associative or not</param>
 public static void RegisterBinaryOperator(TokenType opToken, Precedence precedence,
                                           bool rightAssociative = false)
 {
     Logger.Log(LogLevel.Debug, Logger.REGISTRY,
                "Registering binary operator parselet for token " + opToken.ToString());
     InfixParselets.Add(opToken, new BinaryOperatorParselet(precedence, rightAssociative));
 }
Esempio n. 3
0
        /// <summary>
        /// Gets the infix parselet registered to the token type
        /// </summary>
        /// <param name="tokenClass">Token type to check</param>
        /// <returns>Parselet the token type is registered to</returns>
        public static IInfixParselet GetInfix(TokenType tokenClass)
        {
            if (InfixParselets.ContainsKey(tokenClass))
            {
                return(InfixParselets[tokenClass]);
            }

            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Returns the precedence of the next infix operator, or 0 if there is none.
        /// </summary>
        /// <returns></returns>
        private int GetPrecedence()
        {
            if (_pos == _tokens.Length)
            {
                return(0);
            }
            IInfixParselet infix;

            InfixParselets.TryGetValue(Peek().ID, out infix);
            return(infix?.Precedence ?? 0);
        }
Esempio n. 5
0
 /// <summary>
 /// Registers a token type to a new PostfixOperatorParselet
 /// </summary>
 /// <param name="opToken">Token type to register</param>
 public static void RegisterPostfixOperator(TokenType opToken)
 {
     Logger.Log(LogLevel.Debug, Logger.REGISTRY,
                "Registering postfix operator parselet for token " + opToken.ToString());
     InfixParselets.Add(opToken, new PostfixOperatorParselet(Precedence.POSTFIX));
 }
Esempio n. 6
0
 /// <summary>
 /// Registers a token type to an infix parselet
 /// </summary>
 /// <param name="token">Token type to register</param>
 /// <param name="parselet">Parselet to register to</param>
 public static void RegisterInfix(TokenType token, IInfixParselet parselet)
 {
     Logger.Log(LogLevel.Debug, Logger.REGISTRY,
                "Registering infix/postfix operator parselet for token " + token.ToString());
     InfixParselets.Add(token, parselet);
 }