public static List <IToken> SyntaxHighlight(FastColoredTextBox textbox) { List <IToken> tokens; // TODO: This is slow on a large DAX expression and may cause flickering... //textbox.SuspendDrawing(); // Doesn't work as we might be on a different thread try { var lexer = new DAXLexer(new DAXCharStream(textbox.Text, Preferences.Current.UseSemicolonsAsSeparators)); lexer.RemoveErrorListeners(); tokens = lexer.GetAllTokens().ToList(); } catch { textbox.ClearStyle(StyleIndex.All); return(new List <IToken>()); } textbox.BeginInvoke((MethodInvoker)(() => { textbox.SuspendDrawing(); textbox.ClearStyle(StyleIndex.All); foreach (var tok in tokens) { if (tok.Type == DAXLexer.Eof) { break; } var range = textbox.GetRange(tok.StartIndex, tok.StopIndex + 1); if (tok.Channel == DAXLexer.KEYWORD_CHANNEL) { range.SetStyle(KeywordStyle); } else if (tok.Channel == DAXLexer.COMMENTS_CHANNEL) { range.SetStyle(CommentStyle); } else { switch (tok.Type) { case DAXLexer.INTEGER_LITERAL: case DAXLexer.REAL_LITERAL: case DAXLexer.STRING_LITERAL: range.SetStyle(LiteralStyle); break; case DAXLexer.OPEN_PARENS: case DAXLexer.CLOSE_PARENS: range.SetStyle(ParensStyle); break; default: range.SetStyle(PlainStyle); break; } } } textbox.ResumeDrawing(); })); return(tokens); }
public static string CommasToSemicolons(string input) { var sb = new StringBuilder(input); var lexer = new DAXLexer(new DAXCharStream(input, false)); foreach (var token in lexer.GetAllTokens().ToList()) { if (token.Type == DAXLexer.COMMA) { sb[token.StartIndex] = ';'; } else if (token.Type == DAXLexer.REAL_LITERAL) { for (var i = token.StartIndex; i <= token.StopIndex; i++) { if (sb[i] == '.') { sb[i] = ','; break; } } } } return(sb.ToString()); }
public static IList <DaxToken> Tokenize(this IDaxDependantObject obj, DAXProperty property) { var result = new List <DaxToken>(); var dax = obj.GetDAX(property); if (string.IsNullOrEmpty(dax)) { return(result); } var lexer = new DAXLexer(new DAXCharStream(obj.GetDAX(property), false)); lexer.RemoveErrorListeners(); var lexerTokens = lexer.GetAllTokens(); for (int i = 0; i < lexerTokens.Count; i++) { result.Add(new DaxToken(lexerTokens[i], result, i)); } return(result); }
private static void ParseExpression(string dax, IDaxDependantObject expressionObj, DAXProperty prop, DependsOnList dependsOn = null) { var lexer = new DAXLexer(new DAXCharStream(dax, false)); lexer.RemoveErrorListeners(); var tokens = lexer.GetAllTokens(); IToken lastTableRef = null; int startTableIndex = 0; for (var i = 0; i < tokens.Count; i++) { var tok = tokens[i]; switch (tok.Type) { case DAXLexer.TABLE: case DAXLexer.TABLE_OR_VARIABLE: if (i < tokens.Count - 1 && tokens[i + 1].Type == DAXLexer.COLUMN_OR_MEASURE) { // Keep the token reference, as the next token should be column (fully qualified). lastTableRef = tok; startTableIndex = tok.StartIndex; } else { // Table referenced directly, don't save the reference for the next token. lastTableRef = null; } if (Model.Tables.Contains(tok.Text)) { if (dependsOn != null) { dependsOn.Add(Model.Tables[tok.Text], prop, tok.StartIndex, tok.StopIndex, true); } else { expressionObj.AddDep(Model.Tables[tok.Text], prop, tok.StartIndex, tok.StopIndex, true); } } else { // Invalid reference (no table with that name) or possibly a variable or function ref } break; case DAXLexer.COLUMN_OR_MEASURE: // Referencing a table just before the object reference if (lastTableRef != null) { var tableName = lastTableRef.Text; lastTableRef = null; if (!Model.Tables.Contains(tableName)) { return; // Invalid reference (no table with that name) } var table = Model.Tables[tableName]; // Referencing a column on a specific table if (table.Columns.Contains(tok.Text)) { if (dependsOn != null) { dependsOn.Add(table.Columns[tok.Text], prop, startTableIndex, tok.StopIndex, true); } else { expressionObj.AddDep(table.Columns[tok.Text], prop, startTableIndex, tok.StopIndex, true); } } // Referencing a measure on a specific table else if (table.Measures.Contains(tok.Text)) { if (dependsOn != null) { dependsOn.Add(table.Measures[tok.Text], prop, startTableIndex, tok.StopIndex, true); } else { expressionObj.AddDep(table.Measures[tok.Text], prop, startTableIndex, tok.StopIndex, true); } } } // No table reference before the object reference else { var table = (expressionObj as ITabularTableObject)?.Table ?? (expressionObj as TablePermission)?.Table; // Referencing a column without specifying a table (assume column in same table): if (table != null && table.Columns.Contains(tok.Text)) { if (dependsOn != null) { dependsOn.Add(table.Columns[tok.Text], prop, tok.StartIndex, tok.StopIndex, false); } else { expressionObj.AddDep(table.Columns[tok.Text], prop, tok.StartIndex, tok.StopIndex, false); } } // Referencing a measure or column without specifying a table else { Measure m = null; if (table != null && table.Measures.Contains(tok.Text)) { m = table.Measures[tok.Text]; } else { m = Model.Tables.FirstOrDefault(t => t.Measures.Contains(tok.Text))?.Measures[tok.Text]; } if (m != null) { if (dependsOn != null) { dependsOn.Add(m, prop, tok.StartIndex, tok.StopIndex, false); } else { expressionObj.AddDep(m, prop, tok.StartIndex, tok.StopIndex, false); } } } } break; default: lastTableRef = null; break; } } }