Ejemplo n.º 1
0
        /// <summary>
        /// Parse expression using the rule the ParseRuleSelector instance supplies.
        /// </summary>
        /// <param name="expression">text to parse</param>
        /// <param name="eplStatementErrorMsg">text for error</param>
        /// <param name="addPleaseCheck">true to include depth paraphrase</param>
        /// <param name="parseRuleSelector">parse rule to select</param>
        /// <param name="rewriteScript">if set to <c>true</c> [rewrite script].</param>
        /// <returns>
        /// AST - syntax tree
        /// </returns>
        /// <exception cref="EPException">IOException parsing expression ' + expression + '\''</exception>
        /// <throws>EPException when the AST could not be parsed</throws>
        public static ParseResult Parse(String expression, String eplStatementErrorMsg, bool addPleaseCheck, ParseRuleSelector parseRuleSelector, bool rewriteScript)
        {
            if (Log.IsDebugEnabled)
            {
                Log.Debug(".parse Parsing expr=" + expression);
            }

            ICharStream input;

            try
            {
                input = new NoCaseSensitiveStream(expression);
            }
            catch (IOException ex)
            {
                throw new EPException("IOException parsing expression '" + expression + '\'', ex);
            }

            var lex = NewLexer(input);

            var tokens = new CommonTokenStream(lex);
            var parser = ParseHelper.NewParser(tokens);

            ITree tree;

            try
            {
                tree = parseRuleSelector.Invoke(parser);
            }
            catch (RecognitionException ex)
            {
                tokens.Fill();
                if (rewriteScript && IsContainsScriptExpression(tokens))
                {
                    return(HandleScriptRewrite(tokens, eplStatementErrorMsg, addPleaseCheck, parseRuleSelector));
                }
                Log.Debug("Error parsing statement [" + expression + "]", ex);
                throw ExceptionConvertor.ConvertStatement(ex, eplStatementErrorMsg, addPleaseCheck, parser);
            }
            catch (Exception e)
            {
                try
                {
                    tokens.Fill();
                }
                catch (Exception ex)
                {
                    Log.Debug("Token-fill produced exception: " + ex.Message, ex);
                }

                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Error parsing statement [" + eplStatementErrorMsg + "]", e);
                }
                if (e.InnerException is RecognitionException)
                {
                    if (rewriteScript && IsContainsScriptExpression(tokens))
                    {
                        return(HandleScriptRewrite(tokens, eplStatementErrorMsg, addPleaseCheck, parseRuleSelector));
                    }
                    throw ExceptionConvertor.ConvertStatement((RecognitionException)e.InnerException, eplStatementErrorMsg, addPleaseCheck, parser);
                }
                else
                {
                    throw;
                }
            }

            // if we are re-writing scripts and contain a script, then rewrite
            if (rewriteScript && IsContainsScriptExpression(tokens))
            {
                return(HandleScriptRewrite(tokens, eplStatementErrorMsg, addPleaseCheck, parseRuleSelector));
            }

            if (Log.IsDebugEnabled)
            {
                Log.Debug(".parse Dumping AST...");
                ASTUtil.DumpAST(tree);
            }

            var expressionWithoutAnnotation = expression;

            if (tree is EsperEPL2GrammarParser.StartEPLExpressionRuleContext)
            {
                var epl = (EsperEPL2GrammarParser.StartEPLExpressionRuleContext)tree;
                expressionWithoutAnnotation = GetNoAnnotation(expression, epl.annotationEnum(), tokens);
            }
            else if (tree is EsperEPL2GrammarParser.StartPatternExpressionRuleContext)
            {
                var pattern = (EsperEPL2GrammarParser.StartPatternExpressionRuleContext)tree;
                expressionWithoutAnnotation = GetNoAnnotation(expression, pattern.annotationEnum(), tokens);
            }

            return(new ParseResult(tree, expressionWithoutAnnotation, tokens, Collections.GetEmptyList <String>()));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Converts from a syntax error to a nice exception.
        /// </summary>
        /// <param name="e">is the syntax error</param>
        /// <param name="expression">is the expression text</param>
        /// <param name="parser">the parser that parsed the expression</param>
        /// <param name="addPleaseCheck">indicates to add "please check" paraphrases</param>
        /// <returns>syntax exception</returns>
        public static UniformPair <string> Convert(RecognitionException e, string expression, bool addPleaseCheck, EsperEPL2GrammarParser parser)
        {
            string message;

            if (expression.Trim().Length == 0)
            {
                message = "Unexpected " + END_OF_INPUT_TEXT;
                return(new UniformPair <string>(message, expression));
            }

            IToken t;
            IToken tBeforeBefore = null;
            IToken tBefore       = null;
            IToken tAfter        = null;

            ITokenStream tokenStream = parser.InputStream as ITokenStream;

            var tIndex = e.OffendingToken != null ? e.OffendingToken.TokenIndex : int.MaxValue;

            if (tIndex < tokenStream.Size)
            {
                t = tokenStream.Get(tIndex);
                if ((tIndex + 1) < tokenStream.Size)
                {
                    tAfter = tokenStream.Get(tIndex + 1);
                }
                if (tIndex - 1 >= 0)
                {
                    tBefore = tokenStream.Get(tIndex - 1);
                }
                if (tIndex - 2 >= 0)
                {
                    tBeforeBefore = tokenStream.Get(tIndex - 2);
                }
            }
            else
            {
                if (tokenStream.Size >= 1)
                {
                    tBeforeBefore = tokenStream.Get(tokenStream.Size - 1);
                }
                if (tokenStream.Size >= 2)
                {
                    tBefore = tokenStream.Get(tokenStream.Size - 2);
                }
                t = tokenStream.Get(tokenStream.Size - 1);
            }

            IToken tEnd = null;

            if (tokenStream.Size > 0)
            {
                tEnd = tokenStream.Get(tokenStream.Size - 1);
            }

            var positionInfo = GetPositionInfo(t);
            var token        = t.Type == EsperEPL2GrammarParser.Eof ? "end-of-input" : "'" + t.Text + "'";

            var stack    = parser.GetParaphrases();
            var check    = "";
            var isSelect = stack.Count == 1 && stack.Peek().Equals("select clause");

            if ((stack.Count > 0) && addPleaseCheck)
            {
                var delimiter = "";
                var checkList = new StringBuilder();
                checkList.Append(", please check the ");
                while (stack.Count != 0)
                {
                    checkList.Append(delimiter);
                    checkList.Append(stack.Pop());
                    delimiter = " within the ";
                }
                check = checkList.ToString();
            }

            // check if token is a reserved keyword
            var keywords        = parser.GetKeywords();
            var reservedKeyword = false;

            if (keywords.Contains(token.ToLower()))
            {
                token          += " (a reserved keyword)";
                reservedKeyword = true;
            }
            else if (tAfter != null && keywords.Contains("'" + tAfter.Text.ToLower() + "'"))
            {
                token          += " ('" + tAfter.Text + "' is a reserved keyword)";
                reservedKeyword = true;
            }
            else
            {
                if ((tBefore != null) &&
                    (tAfter != null) &&
                    (keywords.Contains("'" + tBefore.Text.ToLower() + "'")) &&
                    (keywords.Contains("'" + tAfter.Text.ToLower() + "'")))
                {
                    token          += " ('" + tBefore.Text + "' and '" + tAfter.Text + "' are a reserved keyword)";
                    reservedKeyword = true;
                }
                else if ((tBefore != null) &&
                         (keywords.Contains("'" + tBefore.Text.ToLower() + "'")))
                {
                    token          += " ('" + tBefore.Text + "' is a reserved keyword)";
                    reservedKeyword = true;
                }
                else if (tEnd != null && keywords.Contains("'" + tEnd.Text.ToLower() + "'"))
                {
                    token          += " ('" + tEnd.Text + "' is a reserved keyword)";
                    reservedKeyword = true;
                }
            }

            // special handling for the select-clause "as" keyword, which is required
            if (isSelect && !reservedKeyword)
            {
                check += GetSelectClauseAsText(tBeforeBefore, t);
            }

            message = "Incorrect syntax near " + token + positionInfo + check;
            if (e is NoViableAltException || e is LexerNoViableAltException || CheckForInputMismatchWithNoExpected(e))
            {
                var nvaeToken     = e.OffendingToken;
                var nvaeTokenType = nvaeToken != null ? nvaeToken.Type : EsperEPL2GrammarLexer.Eof;

                if (nvaeTokenType == EsperEPL2GrammarLexer.Eof)
                {
                    if (token.Equals(END_OF_INPUT_TEXT))
                    {
                        message = "Unexpected " + END_OF_INPUT_TEXT + positionInfo + check;
                    }
                    else
                    {
                        if (ParseHelper.HasControlCharacters(expression))
                        {
                            message = "Unrecognized control characters found in text" + positionInfo;
                        }
                        else
                        {
                            message = "Unexpected " + END_OF_INPUT_TEXT + " near " + token + positionInfo + check;
                        }
                    }
                }
                else
                {
                    var parserTokenParaphrases = EsperEPL2GrammarParser.GetParserTokenParaphrases();
                    if (parserTokenParaphrases.Get(nvaeTokenType) != null)
                    {
                        message = "Incorrect syntax near " + token + positionInfo + check;
                    }
                    else
                    {
                        // find next keyword in the next 3 tokens
                        var currentIndex = tIndex + 1;
                        while ((currentIndex > 0) &&
                               (currentIndex < tokenStream.Size - 1) &&
                               (currentIndex < tIndex + 3))
                        {
                            IToken next = tokenStream.Get(currentIndex);
                            currentIndex++;

                            var quotedToken = "'" + next.Text + "'";
                            if (parser.GetKeywords().Contains(quotedToken))
                            {
                                check += " near reserved keyword '" + next.Text + "'";
                                break;
                            }
                        }
                        message = "Incorrect syntax near " + token + positionInfo + check;
                    }
                }
            }
            else if (e is InputMismatchException)
            {
                var mismatched = (InputMismatchException)e;

                string expected;
                var    expectedTokens = mismatched.GetExpectedTokens().ToList();
                if (expectedTokens.Count > 1)
                {
                    var writer = new StringWriter();
                    writer.Write("any of the following tokens {");
                    var delimiter = "";
                    for (var i = 0; i < expectedTokens.Count; i++)
                    {
                        writer.Write(delimiter);
                        if (i > 5)
                        {
                            writer.Write("...");
                            writer.Write(expectedTokens.Count - 5);
                            writer.Write(" more");
                            break;
                        }
                        delimiter = ", ";
                        writer.Write(GetTokenText(parser, expectedTokens[i]));
                    }
                    writer.Write("}");
                    expected = writer.ToString();
                }
                else
                {
                    expected = GetTokenText(parser, expectedTokens[0]);
                }

                var offendingTokenType = mismatched.OffendingToken.Type;
                var unexpected         = GetTokenText(parser, offendingTokenType);

                var expecting = " expecting " + expected.Trim() + " but found " + unexpected.Trim();
                message = "Incorrect syntax near " + token + expecting + positionInfo + check;
            }

            return(new UniformPair <string>(message, expression));
        }