예제 #1
0
        public static List <IStatement> Execute(ITokenizer tokenizer, bool ensureParserIsFound)
        {
            var result = new List <IStatement>();

            if (tokenizer.Current == (Token)null)
            {
                tokenizer.ReadNextToken();
            }

            while (tokenizer.HasMoreTokens)
            {
                IParser parser = GetParser(tokenizer);

                if (parser != null)
                {
                    result.Add(parser.Execute());
                }
                else
                if (ensureParserIsFound)
                {
                    throw new ParserNotImplementedException(
                              "No parser exists for statement type: " + tokenizer.Current.Value
                              );
                }
                else
                {
                    break;
                }
            }

            return(result);
        }
예제 #2
0
        private string ProcessParameter(ITokenizer tokenizer, string parameterName)
        {
            // the following code produces a parameter that supports Guids. For unknown reasons, NH
            // is supplying the parameter value as an unquoted set of alpha numerics, so, here they are processed
            // until the next token is NOT a dash
            int    tokenCount = 0;
            string token      = "";

            //string regexDateFormat = GetDateFormatRegex();
            tokenizer.SkipWhiteSpace = false;
            do
            {
                if (tokenizer.Current.Type != TokenType.BlockedText)
                {
                    token +=
                        // TODO: the code below will not work until the parser can retain embedded comments
                        //String.Format("/* {0} */ ", parameterName) +
                        tokenizer.Current.Value;

                    if (tokenizer.Current.Type != TokenType.WhiteSpace)
                    {
                        tokenCount++;
                    }
                }
                tokenizer.ReadNextToken();
            }while (tokenizer.HasMoreTokens && !tokenizer.IsNextToken(Constants.Comma));

            tokenizer.SkipWhiteSpace = true;

            return(tokenCount > 1 && !token.StartsWith("'") ? String.Format("'{0}'", token.Trim().ToUpper()) : token);
        }
예제 #3
0
        private string ProcessParameter(ITokenizer tokenizer, string parameterName)
        {
            // the following code produces a parameter that supports Guids. For unknown reasons, NH
            // is supplying the parameter value as an unquoted set of alpha numerics, so, here they are processed
            // until the next token is NOT a dash
            int tokenCount = 0;
            string token = "";
            //string regexDateFormat = GetDateFormatRegex();
            tokenizer.SkipWhiteSpace = false;
            do
            {
                if (tokenizer.Current.Type != TokenType.BlockedText)
                {
                    token +=
                        // TODO: the code below will not work until the parser can retain embedded comments
                        //String.Format("/* {0} */ ", parameterName) +
                        tokenizer.Current.Value;

                    if (tokenizer.Current.Type != TokenType.WhiteSpace)
                        tokenCount++;
                }
                tokenizer.ReadNextToken();
            }
            while (tokenizer.HasMoreTokens && !tokenizer.IsNextToken(Constants.Comma));

            tokenizer.SkipWhiteSpace = true;

            return tokenCount > 1 && !token.StartsWith("'") ? String.Format("'{0}'", token.Trim().ToUpper()) : token;
        }
예제 #4
0
        internal static IParser GetParser(ITokenizer _tokenizer)
        {
            // this is a quick and dirty service locator that maps tokens to parsers
            Type parserType;

            if (_parsers.TryGetValue(_tokenizer.Current.Value.ToUpper(), out parserType))
            {
                _tokenizer.ReadNextToken();

                object instance = Activator.CreateInstance(parserType, _tokenizer);
                return((IParser)instance);
            }
            return(null);
        }
        protected string DoShuntingYardAlgorithm(ITokenizer tokenizer)
        {
            // see https://en.wikipedia.org/wiki/Shunting-yard_algorithm for details.

            // - Read a token.
            Token token = tokenizer.ReadNextToken();
            Token lastToken = null;
            bool first = true;
            bool afterOpenParenthesis = false;
            while (token.Type != TokenType.None)
            {
                // - If the token is a number, then add it to the output queue.
                if (IsDigit(token))
                    AddToOutput(token.GetValueAsString());

                // - If the token is a left parenthesis (i.e. "("), then push it onto the stack.
                else if (token.GetValueAsString() == "(")
                    operatorStack.Push(token.GetValueAsString());

                // - If the token is a right parenthesis (i.e. ")"):
                else if (token.GetValueAsString() == ")")
                {
                    //   - Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
                    string lastOperation = operatorStack.Peek();
                    while (lastOperation != "(")
                    {
                        AddToOutput(operatorStack.Pop());
                        lastOperation = operatorStack.Peek();
                    }

                    //   - If the stack runs out without finding a left parenthesis, then there are mismatched parenthesis.
                    if (operatorStack.Count == 0)
                        throw new Exception("Invalid Syntax! - Parenthesis mismatch, missing open parenthesis");

                    //   - Pop the left parenthesis from the stack, but not onto the output queue.
                    operatorStack.Pop();

                    // Mark parenthesis flag to avoid false unary operation detection.
                    afterOpenParenthesis = true;
                }

                // - If the token is an operator, o1, then:
                else if (IsOperator(token))
                {
                    string currentOperation = token.GetValueAsString();

                    // check for negation at the beginning of the input formal.
                    if (first && currentOperation == "-")
                    {
                        currentOperation = "m";
                    }
                    // check for plus sign at the beginning of the input formal.
                    else if (first && currentOperation == "+")
                    {
                        currentOperation = "p";
                    }
                    else if (operatorStack.Count > 0)
                    {
                        string lastOperation = operatorStack.Peek();

                        // If parenthesis flag is set avoid false unary operation detection
                        if (!afterOpenParenthesis)
                        {
                            // check for negation direct after a '(' or after another operator.
                            if ((IsOperator(lastOperation) || lastOperation == "(") && currentOperation == "-" && lastOperation != "p" && lastOperation != "m" && !IsDigit(lastToken))
                            {
                                currentOperation = "m";
                            }

                            // check for plus sign direct after a '(' or after another operator.
                            if ((IsOperator(lastOperation) || lastOperation == "(") && currentOperation == "+" && lastOperation != "p" && lastOperation != "m" && !IsDigit(lastToken))
                            {
                                currentOperation = "p";
                            }
                        }

                        //   - while there is an operator token, lastOperation, at the top of the operator stack, and either
                        while (IsOperator(lastOperation))
                        {
                            //     o1 is left-associative and its precedence is less than or equal to that of lastOperation, or
                            //     o1 is right associative, and has precedence less than that of lastOperation,
                            if (IsLeftAssociative(currentOperation) && LessOrEqualPrecedence(currentOperation, lastOperation) ||
                                IsRightAssociative(currentOperation) && LessPrecedence(currentOperation, lastOperation))
                            {
                                //     then pop o2 off the operator stack, onto the output queue;
                                AddToOutput(operatorStack.Pop());

                                if (operatorStack.Count == 0)
                                    break;
                                else
                                    lastOperation = operatorStack.Peek();
                            }
                            else
                                break;
                        }
                    }
                        
                    //   - push o1 onto the operator stack.
                    operatorStack.Push(currentOperation);

                    // Reset parenthesis flag.
                    afterOpenParenthesis = false;
                }
                else
                {
                    throw new Exception(string.Format("Invalid Syntax! Unknown symbol \"{0}\"", token.GetValueAsString()));
                }
                
                lastToken = token;
                token = tokenizer.ReadNextToken();
                first = false;
            }

            // - When there are no more tokens to read:
            // - While there are still operator tokens in the stack:
            while (operatorStack.Count > 0)
            {
                string lastOperation = operatorStack.Peek();
                //   - If the operator token on the top of the stack is a parenthesis, then there are mismatched parenthesis.
                if (lastOperation == "(" || lastOperation == ")")
                    throw new Exception("Parenthesis mismatch! - Missing closing parenthesis");
                else
                    //   - Pop the operator onto the output queue.
                    AddToOutput(operatorStack.Pop());
            }

            return CreateOutput(output);
        }
예제 #6
0
        private IExpression ParseAddSubtract()
        {
            var lhs = ParseMultiplyDivide();

            while (true)
            {
                if (tokenizer.Token == Token.Add || tokenizer.Token == Token.Subtract)
                {
                    var token = tokenizer.Token;

                    tokenizer.ReadNextToken();

                    var rhs = ParseMultiplyDivide();

                    if (token == Token.Add)
                    {
                        lhs = new AddExpression(lhs, rhs);
                    }
                    else
                    {
                        lhs = new SubtractExpression(lhs, rhs);
                    }
                }
                else
                {
                    return(lhs);
                }
            }
        }