Exemplo n.º 1
0
        private Ast.SqlStmt ParseSqlStmt(TokenQueue q, string rootProdName = "sql-stmt")
        {
            var start = q.GetLocation();
            var tok   = q.SourceToken;

            Ast.SqliteSyntaxProduction syntaxNode;
            var result = SqliteParser.ReadStmt(q, out syntaxNode, rootProdName);

            if (result.IsValid)
            {
                var stmt = new Ast.SqlStmt {
                    Sql          = q.Substring(start, result.NumValidTokens),
                    SourceToken  = tok,
                    SqliteSyntax = syntaxNode
                };
                _preprocessor.PreprocessStmt(stmt);
                return(stmt);
            }
            else if (result.InvalidMessage != null)
            {
                throw new SyntaxException(result.InvalidMessage);
            }
            else
            {
                throw new SyntaxException(q);
            }
        }
Exemplo n.º 2
0
        private Ast.Expr ParseExpr(TokenQueue q)
        {
            var start = q.GetLocation();
            var tok   = q.SourceToken;

            Ast.SqliteSyntaxProduction syntaxNode;
            var result = SqliteParser.ReadExpr(q, out syntaxNode);

            if (result.IsValid)
            {
                return(new Ast.Expr {
                    Sql = q.Substring(start, result.NumValidTokens),
                    SourceToken = tok,
                    SqliteSyntax = syntaxNode
                });
            }
            else if (result.InvalidMessage != null)
            {
                throw new SyntaxException(result.InvalidMessage);
            }
            else
            {
                throw new SyntaxException(q);
            }
        }
Exemplo n.º 3
0
        public static MatchResult Match(string rootProdName, TokenQueue q, out Ast.SqliteSyntaxProduction ast)
        {
            // we use an explicit stack rather than function call recursion because our BNF grammar is deeply nested,
            // particularly the productions for 'expr'.
            var stack = new MatchStack {
                Queue = q
            };

            stack.Push(SqliteGrammar.Prods[rootProdName]);
            MatchResult?rootResult = null;

            Ast.SqliteSyntaxProduction rootAst = null;

            Action <MatchResult, Ast.SqliteSyntaxProduction> finishFrame = (frameResult, frameAstProd) => {
                stack.Pop();
                var parentFrame = stack.Peek();
                if (parentFrame == null)
                {
                    rootResult = frameResult;
                    rootAst    = frameAstProd;
                }
                else
                {
                    parentFrame.SubResult = frameResult;
                    if (frameResult.IsMatch)
                    {
                        parentFrame.AstProd.Items.Add(frameAstProd);
                    }
                }
            };

#if MATCHER_LOG
            var matcherLogWriter        = File.CreateText(@"C:\temp\matcher.log");
            int matcherLogPreviousDepth = 0;
#endif

            // trampoline loop
            while (!rootResult.HasValue && stack.Any())
            {
#if MATCHER_LOG
                stack.DebugDump(matcherLogWriter, q.GetLocation(), q.Substring(q.GetLocation(), 1),
                                matcherLogPreviousDepth > stack.Count);
                matcherLogPreviousDepth = stack.Count;
#endif

                var frame  = stack.Peek();
                var result = frame.Prod.Terms[frame.TermIndex].MatchStep(stack, frame, q);
                if (result.HasValue)
                {
                    // we are done matching this term
                    if (result.Value.IsMatch)
                    {
                        // move to the next term in the production.
                        frame.Clear(all: false);
                        frame.TermIndex++;
                        if (frame.TermIndex >= frame.Prod.Terms.Length)
                        {
                            // we have matched this full production
                            var prodEndLoc = q.GetLocation();
                            frame.AstProd.StartToken = frame.ProdStartLoc;
                            frame.AstProd.NumTokens  = prodEndLoc - frame.ProdStartLoc;
                            frame.AstProd.Text       = q.Substring(frame.ProdStartLoc, prodEndLoc - frame.ProdStartLoc);
                            finishFrame(MatchResult.Matched, frame.AstProd);
                        }
                    }
                    else
                    {
                        // we needed a match and didn't find one.  we have to abandon this production.
                        finishFrame(result.Value, null);
                    }
                }
            }

#if MATCHER_LOG
            matcherLogWriter.Close();
#endif

            if (!rootResult.HasValue && !stack.Any())   // detect bugs
            {
                throw new Exception("Expected a MatchResult but one was not set.");
            }

            ast = rootAst;
            return(rootResult.Value);
        }