示例#1
0
        /// <summary>
        ///     Parses the specified pattern into expression.
        /// </summary>
        /// <param name="pattern">The pattern to parse.</param>
        /// <returns>The parsed expression.</returns>
        /// <exception cref="InvalidPatternException">
        ///     The pattern is invalid.
        /// </exception>
        public PatternExpression Parse(string pattern)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }

            try
            {
                tokenizer.Initialize(pattern);
                lookAhead = tokenizer.NextToken();
                PatternExpression ret = ParseExpression(true);
                if (PeekToken() != null)
                {
                    throw new InvalidPatternException("Extra tokens beyond the end of pattern.");
                }
                return(ret);
            }
            catch (Exception ex)
            {
                if (ex is InvalidPatternException)
                {
                    throw;
                }
                throw new InvalidPatternException("Invalid pattern.", ex);
            }
        }
示例#2
0
        private PatternToken ReadToken()
        {
            if (lookAhead == null)
            {
                throw UnexpectedEnd();
            }
            PatternToken ret = lookAhead.Value;

            lookAhead = tokenizer.NextToken();
            return(ret);
        }
示例#3
0
 /// <summary>
 ///     Parses the specified pattern into expression.
 /// </summary>
 /// <param name="pattern">The pattern to parse.</param>
 /// <returns>The parsed expression.</returns>
 /// <exception cref="InvalidPatternException">
 ///     The pattern is invalid.
 /// </exception>
 public PatternExpression Parse(string pattern)
 {
     try {
         tokenizer.Initialize(pattern);
         lookAhead = tokenizer.NextToken();
         PatternExpression ret = ParseExpression(true);
         if (PeekToken() != null)
             throw new InvalidPatternException("Extra tokens beyond the end of pattern.");
         return ret;
     }
     catch (Exception ex) {
         if (ex is InvalidPatternException)
             throw;
         throw new InvalidPatternException("Invalid pattern.", ex);
     }
 }
示例#4
0
 PatternToken ReadToken()
 {
     if (lookAhead == null)
         throw UnexpectedEnd();
     PatternToken ret = lookAhead.Value;
     lookAhead = tokenizer.NextToken();
     return ret;
 }
示例#5
0
        private PatternExpression ParseExpression(bool readBinOp = false)
        {
            PatternExpression ret;
            PatternToken      token = ReadToken();

            switch (token.Type)
            {
            case TokenType.Literal:
                ret = new LiteralExpression(token.Value);
                break;

            case TokenType.LParens:
            {
                ret = ParseExpression(true);
                PatternToken parens = ReadToken();
                if (parens.Type != TokenType.RParens)
                {
                    throw MismatchParens(token.Position.Value);
                }
            }
            break;

            case TokenType.Identifier:
                if (IsOperator(token))
                {
                    // unary operator
                    PatternOperator op = ops[token.Value]();
                    if (!op.IsUnary)
                    {
                        throw UnexpectedToken(token);
                    }
                    op.OperandA = ParseExpression();
                    ret         = op;
                }
                else if (IsFunction(token))
                {
                    // function
                    PatternFunction fn = fns[token.Value]();

                    PatternToken parens = ReadToken();
                    if (parens.Type != TokenType.LParens)
                    {
                        throw UnexpectedToken(parens, '(');
                    }

                    fn.Arguments = new List <PatternExpression>(fn.ArgumentCount);
                    for (int i = 0; i < fn.ArgumentCount; i++)
                    {
                        if (PeekToken() == null)
                        {
                            throw UnexpectedEnd();
                        }
                        if (PeekToken().Value.Type == TokenType.RParens)
                        {
                            throw BadArgCount(token, fn.ArgumentCount);
                        }
                        if (i != 0)
                        {
                            PatternToken comma = ReadToken();
                            if (comma.Type != TokenType.Comma)
                            {
                                throw UnexpectedToken(comma, ',');
                            }
                        }
                        fn.Arguments.Add(ParseExpression());
                    }

                    parens = ReadToken();
                    if (parens.Type == TokenType.Comma)
                    {
                        throw BadArgCount(token, fn.ArgumentCount);
                    }
                    if (parens.Type != TokenType.RParens)
                    {
                        throw MismatchParens(parens.Position.Value);
                    }

                    ret = fn;
                }
                else
                {
                    bool boolValue;
                    if (bool.TryParse(token.Value, out boolValue))
                    {
                        ret = new LiteralExpression(boolValue);
                    }
                    else
                    {
                        throw UnknownToken(token);
                    }
                }

                break;

            default:
                throw UnexpectedToken(token);
            }

            if (!readBinOp)
            {
                return(ret);
            }

            // binary operator
            PatternToken?peek = PeekToken();

            while (peek != null)
            {
                if (peek.Value.Type != TokenType.Identifier)
                {
                    break;
                }
                if (!IsOperator(peek.Value))
                {
                    break;
                }

                PatternToken    binOpToken = ReadToken();
                PatternOperator binOp      = ops[binOpToken.Value]();
                if (binOp.IsUnary)
                {
                    throw UnexpectedToken(binOpToken);
                }
                binOp.OperandA = ret;
                binOp.OperandB = ParseExpression();
                ret            = binOp;

                peek = PeekToken();
            }

            return(ret);
        }