18 using System.Collections.Generic;
27 namespace Deveel.Data.Sql.Parser {
33 languageData =
new LanguageData(grammar);
34 parser =
new Irony.Parsing.Parser(languageData);
36 if (!languageData.CanParse())
37 throw new InvalidOperationException();
47 GC.SuppressFinalize(
this);
50 public string Dialect {
57 var timer =
new Timer();
61 var node = ParseNode(input, result.Errors, out time);
62 result.RootNode = node;
63 }
catch (Exception ex) {
68 result.ParseTime = timer.Elapsed;
74 private ISqlNode ParseNode(
string sqlSource, ICollection<SqlParseError> errors, out
long parseTime) {
75 var tree = parser.Parse(sqlSource);
76 parseTime = tree.ParseTimeMilliseconds;
78 if (tree.Status == ParseTreeStatus.Error) {
79 BuildErrors(tree, errors, tree.ParserMessages);
83 var astContext =
new AstContext(languageData) {
84 DefaultNodeType = typeof (
SqlNode),
88 var astCompiler =
new AstBuilder(astContext);
89 astCompiler.BuildAst(tree);
92 BuildErrors(tree, errors, tree.ParserMessages);
94 var node = (
ISqlNode) tree.Root.AstNode;
95 if (node.NodeName ==
"root")
96 node = node.ChildNodes.FirstOrDefault();
101 private static void BuildErrors(ParseTree tree, ICollection<SqlParseError> errors, LogMessageList logMessages) {
102 foreach (var logMessage
in logMessages) {
104 var line = logMessage.Location.Line;
105 var column = logMessage.Location.Column;
106 var locationMessage = FormInfoMessage(tree, line, column);
107 var expected = logMessage.ParserState.ReportedExpectedSet.ToArray();
108 var infoMessage = String.Format(
"A parse error occurred near '{0}' in the source", locationMessage);
109 if (expected.Length > 0)
110 infoMessage = String.Format(
"{0}. Expected {1}", infoMessage, String.Join(
", ", expected));
118 const int tokensBeforeCount = 10;
119 const int tokensAfterCount = 10;
121 var tokensBefore = FindTokensTo(tree, line, column).Reverse().ToList();
122 var tokensAfter = FindTokensFrom(tree, line, column);
124 var countTokensBefore =
System.Math.Min(tokensBefore.Count, tokensBeforeCount);
125 var countTokensAfter =
System.Math.Min(tokensAfterCount, tokensAfter.Count);
127 var takeTokensBefore = tokensBefore.Take(countTokensBefore).Reverse();
128 var takeTokensAfter = tokensAfter.Take(countTokensAfter);
130 var sb =
new StringBuilder();
131 foreach (var token
in takeTokensBefore) {
132 sb.Append(token.Text);
136 foreach (var token
in takeTokensAfter) {
137 sb.Append(token.Text);
141 return sb.ToString();
145 var tokens = tree.Tokens;
146 bool startCollect =
false;
148 var result =
new List<
Irony.Parsing.Token>();
149 foreach (var token
in tokens) {
150 if (token.Location.Line == line &&
151 token.Location.Column == column) {
159 return result.ToList();
163 var tokens = tree.Tokens;
165 var result =
new List<
Irony.Parsing.Token>();
166 foreach (var token
in tokens) {
167 if (token.Location.Line == line &&
168 token.Location.Column == column)
174 return result.ToList();
181 private readonly DateTimeOffset startTime;
188 startTime = DateTimeOffset.UtcNow;
190 stopwatch =
new Stopwatch();
195 public TimeSpan Elapsed {
198 return DateTimeOffset.UtcNow.Subtract(startTime);
200 return stopwatch.Elapsed;
207 if (stopwatch != null)
The result of a parse of an SQL input
void Dispose(bool disposing)
This is a simple identifier within a SQL grammar.
Defines the contract for nodes in an AST model for a SQL grammar analysis and parsing.
static IList< Irony.Parsing.Token > FindTokensFrom(ParseTree tree, int line, int column)
static void BuildErrors(ParseTree tree, ICollection< SqlParseError > errors, LogMessageList logMessages)
SqlDefaultParser(SqlGrammarBase grammar)
LanguageData languageData
static string FormInfoMessage(ParseTree tree, int line, int column)
Implementations of this interface will parse input strings into ISqlNode that can be used to construc...
ISqlNode ParseNode(string sqlSource, ICollection< SqlParseError > errors, out long parseTime)
ErrorLevel
In case of error messages, this enumerates the level of severity of the error.
SqlParseResult Parse(string input)
Analyzes and parses the input and results an object that describes the parsed nodes in a tree that ca...
static IList< Irony.Parsing.Token > FindTokensTo(ParseTree tree, int line, int column)
Irony.Parsing.Parser parser
The default implementation of ISqlNode, that is a node in the text analysis parsing of SQL commands...