Пример #1
0
        /// Function := Name '(' ArgList ')'
        void ParseFunction(TokenQueue tokens)
        {
            var funcStartPosition       = tokens.PeekToken().Position;
            RegisteredFunction function = ParseFunctionName(tokens);
            Token current = tokens.PeekToken();

            if (current.TokenType != TokenType.OpenParenthesis)
            {
                throw new ParserExceptionWithPosistion(string.Format("Expected open bracket at {0}.", current.Position), current.Position);
            }
            tokens.NextToken();
            int args = 0;

            ParseArgList(tokens, ref args);
            current = tokens.PeekToken();
            if (args != function.ArgCount)
            {
                throw new ParserExceptionWithPosistion(string.Format("Invalid number of function parameters in function {0}.  Expected {1} at {2}.", function.Name, function.ArgCount, current.Position), current.Position);
            }
            if (current.TokenType != TokenType.CloseParenthesis)
            {
                throw new ParserExceptionWithPosistion(string.Format("Expected close bracket at {0}.", current.Position), current.Position);
            }

            // Append function names after all their arguments.
            EmitFunction(function, funcStartPosition);

            tokens.NextToken();
        }
Пример #2
0
        /// <summary>
        /// FactorTail := Number | '(' Expr ')' | Function
        /// </summary>
        void ParseFactorTail(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.OpenParenthesis)
            {
                current = tokens.NextToken();
                ParseExpressionR(tokens);

                // Skip the closing bracket
                if (tokens.PeekToken().TokenType != TokenType.CloseParenthesis)
                {
                    throw new ParserExceptionWithPosistion(string.Format("Expected close bracket at {0}.", current.Position), current.Position);
                }
                tokens.NextToken();
            }
            else if (current.TokenType == TokenType.Text && IsRegisteredFunction(current.Value))
            {
                ParseFunction(tokens);
            }
            else if (current.TokenType == TokenType.Numeric)
            {
                ParseNumber(tokens);
            }
            else
            {
                throw new ParserExceptionWithPosistion(string.Format("Unrecognised factor at {0}.", current.Position), current.Position);
            }
        }
Пример #3
0
    private Ast.Stmt ParseExecuteStmt(TokenQueue q)
    {
        var stmt = new Ast.ExecuteStmt {
            SourceToken = q.SourceToken
        };

        q.Take("exec", "execute");

        if (q.Peek(1) == "=")
        {
            stmt.ReturnVariableName = ParseVariableName(q);
            q.Take("=");
        }

        if (q.PeekToken().Type == TokenType.String || q.PeekToken().Type == TokenType.Id)
        {
            stmt.ScriptName = q.Take().GetUnescapedText();
        }
        else
        {
            throw new SyntaxException(new[] { "string", "identifier" }, q);
        }

        if (IsVariableName(q.PeekToken()?.GetUnescapedText() ?? "") && q.Peek(1) == "=")
        {
            while (true)
            {
                var arg = new Ast.ArgumentPair();
                arg.Name = ParseVariableName(q);
                q.Take("=");
                if (q.Peek() == "default")
                {
                    q.Take();
                }
                else
                {
                    arg.Value = ParseExpr(q);
                }
                stmt.Arguments.Add(arg);
                if (!q.TakeMaybe(","))
                {
                    break;
                }
            }
        }

        ConsumeSemicolon(q);
        return(stmt);
    }
Пример #4
0
        /// <summary>
        /// ExprTail := nil | '+' Term ExprTail | '-' Term ExprTail
        /// </summary>
        void ParseExprTail(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.Plus)
            {
                current = tokens.NextToken();

                ParseTerm(tokens);

                // Append operators postfix
                EmitBinaryOperator("+", current.Position);

                ParseExprTail(tokens);
            }
            else if (current.TokenType == TokenType.Minus)
            {
                current = tokens.NextToken();

                ParseTerm(tokens);

                // Append operators postfix
                EmitBinaryOperator("-", current.Position);

                ParseExprTail(tokens);
            }
            else
            {
                // nil - but this is ok.
            }
        }
Пример #5
0
        /// <summary>
        /// TermTail := nil | '*' Factor | '/' Factor
        /// </summary>
        void ParseTermTail(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.Divide)
            {
                current = tokens.NextToken();

                ParseFactor(tokens);

                // Append operators postfix
                EmitBinaryOperator("/", current.Position);

                ParseTermTail(tokens);
            }
            else if (current.TokenType == TokenType.Multiply)
            {
                current = tokens.NextToken();

                ParseFactor(tokens);

                // Append operators postfix
                EmitBinaryOperator("*", current.Position);

                ParseTermTail(tokens);
            }
            else
            {
                // nil - but this is ok
            }
        }
Пример #6
0
 /// <summary>
 /// Parse the supplied expression.
 /// If the expression is not valid, then a ParserException will be thrown.
 /// Finally we test to see that all tokens have been parsed.
 /// If not, this is likely to be an error in the expression, for example something like
 /// 4535+54345+5345345POWER(2, 3)
 /// </summary>
 public void ParseExpression(TokenQueue tokens)
 {
     ParseExpressionR(tokens);
     if (tokens.PeekToken().TokenType != TokenType.EOF)
     {
         throw new ParserException(string.Format("Tokens remain after parsing: {0}.", tokens.ToString()));
     }
     return;
 }
Пример #7
0
        /// ArgList :=nil  |  NonEmptyArgList
        void ParseArgList(TokenQueue tokens, ref int argc)
        {
            Token current = tokens.PeekToken();

            // If it is a close parenthesis then its the end of the arglist.
            if (current.TokenType != TokenType.CloseParenthesis)
            {
                ParseNonEmptyArgList(tokens, ref argc);
            }
        }
Пример #8
0
        /// Name := (One of a recognised/registered list of function Names)
        RegisteredFunction ParseFunctionName(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.Text &&
                IsRegisteredFunction(current.Value))
            {
                tokens.NextToken();
                return(_functions[current.Value.ToUpperInvariant()]);
            }
            else
            {
                throw new ParserExceptionWithPosistion(string.Format("Expected known function at {0}.", current.Position), current.Position);
            }
        }
Пример #9
0
        /// ArgListTail : = nil | ',' NonEmptyArgList
        void ParseArgListTail(TokenQueue tokens, ref int argc)
        {
            Token current = tokens.PeekToken();

            // Otherwise it's the end of the arg list
            if (current.TokenType != TokenType.CloseParenthesis)
            {
                if (current.TokenType == TokenType.Separator)
                {
                    tokens.NextToken();
                    ParseNonEmptyArgList(tokens, ref argc);
                }
                else
                {
                    throw new ParserExceptionWithPosistion(string.Format("Expected comma at {0}.", current.Position), current.Position);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// </summary>
        void ParseNumber(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.Numeric)
            {
                // Append numbers as encountered.
                Double result = (Double.Parse(current.Value, NumberFormatInfo.InvariantInfo));

                EmitNumeric(result, current.Position);

                current = tokens.NextToken();
            }
            else
            {
                throw new ParserExceptionWithPosistion(string.Format("Expected number at {0}.", current.Position), current.Position);
            }
        }
Пример #11
0
        /// <summary>
        /// Factor := UnaryPrefixOp FactorTail | FactorTail
        /// </summary>
        void ParseFactor(TokenQueue tokens)
        {
            Token current = tokens.PeekToken();

            if (current.TokenType == TokenType.Minus)
            {
                current = tokens.NextToken();
                ParseFactorTail(tokens);

                // We negate by multiplying by -1.
                EmitNumeric(-1d, current.Position);
                EmitBinaryOperator("*", current.Position);
            }
            else
            {
                ParseFactorTail(tokens);
            }
        }