private static Tuple <string, string, GrammarSection> ProcessSection(Identifier grammar, Dictionary <string, object> dict) { if (dict == null) { return(null); } string tmp; var ignoreCase = dict.Bool("ignoreCase"); var sect = new GrammarSection { GrammarKey = grammar, ExternalGrammarKey = (Identifier)dict.String("grammar"), IgnoreCase = ignoreCase, ContextChars = dict.String("context"), ContinuationChar = dict.Char("contination"), EscapeChar = dict.Char("escape"), TerminatorChar = dict.Char("terminator"), Multiline = dict.Bool("multiline"), DontStyleCompletely = dict.Bool("dontStyleCompletely"), StyleBrackets = dict.Bool("styleBrackets"), StyleNumbers = dict.Bool("styleNumbers"), Style = dict.Style("style"), IdentifierStyle = dict.Style("identifierStyle"), ContextIdentifierStyle = dict.Style("contextIdentifierStyle"), TerminatorEndChar = dict.Char("terminatorEnd"), OnLineStartOnly = dict.Bool("lineStartOnly"), Start = (tmp = dict.String("start")) != null ? new SectionSequence(tmp, !ignoreCase) : null, End = (tmp = dict.String("end")) != null ? new SectionSequence(tmp, !ignoreCase) : null, Keywords = ProcessKeywords(ignoreCase, dict.Object("keywords") as List <object>) }; return(Tuple.Create(dict.String("key"), dict.String("parent"), sect)); }
public static GrammarSection TryMatch(this IEnumerable <GrammarSection> sections, Line ln, int col, GrammarSection except) { foreach (var sect in sections) { if (sect == except || sect.Start == null || sect.Start.Length <= except.Start.Length || sect.Start.Offset == 0) { continue; } var res = sect.Start.TryMatch(ln.CharAt(col + 0), 0); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 1), 1); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 2), 2); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 3), 3); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 4), 4); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 5), 5); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 6), 6); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 7), 7); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 8), 8); if (res == MatchResult.Hit) { return(sect); } else if (res == MatchResult.Fail) { continue; } res = sect.Start.TryMatch(ln.CharAt(col + 9), 9); if (res == MatchResult.Hit || sect.Start.MatchAnyState) { return(sect); } else if (res == MatchResult.Fail) { continue; } } return(null); }
private bool Overlap(IEnumerable <GrammarSection> seq, Line ln, int col, GrammarSection sect) { return(seq.TryMatch(ln, col + 1, sect) != null); }
private State ParseLine(GrammarSection mys, ref int i, int line) { var start = i; var identStart = i; var ln = Lines[line]; var grammar = App.Ext.Grammars().GetGrammar(mys.GrammarKey); Editor.AffinityManager.Associate(line, i, grammar.GlobalId); var wordSep = grammar.NonWordSymbols ?? settings.NonWordSymbols; var backm = mys.Id == 0 && mys.BackDelegate != null ? mys.BackDelegate : mys; var last = '\0'; var term = '\0'; var lastNonIdent = true; var lineStart = i == 0; for (; i < ln.Length + 1; i++) { var c = ln.CharAt(i); var nonIdent = IsNonIdent(c, wordSep); var ws = IsWhiteSpace(c); var kres = lastNonIdent || mys.Keywords.Offset != -1 ? mys.Keywords.Match(c) : -1; if (mys.StyleBrackets && IsBracket(grammar, c)) { Styles.StyleRange(StandardStyle.Bracket, line, i, i); } if (kres > 0 && IsNonIdent(ln.CharAt(i + 1), wordSep)) { var style = mys.IdentifierStyle; if (mys.ContextChars == null || mys.ContextChars.IndexOf(contextChar) != -1) { style = (StandardStyle)kres; contextChar = '\0'; if (mys.ContextChars != null) { Editor.CallTips.BindCallTip( "<b>ToolTip header</b><br><i>Subheader for this unique tip</i><br><br><<keyword>script</keyword><keywordspecial> type</keywordspecial>=<string>\"text/csharp\"</string>><br>This is a context keyword which is only recognized in a particular context such as (>) or any other different context symbol.", new Pos(line, i - mys.Keywords.Offset), new Pos(line, i)); } } Styles.StyleRange(style, line, i - mys.Keywords.Offset, i); identStart = i + 1; mys.Keywords.Reset(); } else if (kres < 0) { mys.Keywords.Reset(); } var num = false; if (kres < 0 && mys.StyleNumbers && grammar.NumberLiteral != null) { var mc = grammar.NumberLiteral.MatchCount; num = grammar.NumberLiteral.Match(c, last); if (!num && mc > 0 && nonIdent) { Styles.StyleRange(StandardStyle.Number, line, i - mc, i - 1); } } if (nonIdent) { if (!lastNonIdent && i - identStart - 1 >= 0) { if (mys.IdentifierStyle != 0) { Styles.StyleRange( mys.ContextIdentifierStyle != StandardStyle.Default && mys.ContextChars != null && mys.ContextChars.IndexOf(contextChar) != -1 ? mys.ContextIdentifierStyle : mys.IdentifierStyle, line, identStart, i - 1); contextChar = '\0'; } } identStart = i + 1; } if (!ws && nonIdent && c != '\0') { contextChar = c; } var sect = kres >= 0 || num ? null : mys.Sections.Match(c); if (sect != null && (sect.Start == null || (!Overlap(mys.Sections, ln, i, sect) && (!sect.OnLineStartOnly || lineStart) && (sect.Start.Length > 1 || IsNonIdent(sect.Start.First(), wordSep) || IsNonIdent(last, wordSep))))) { if (i < ln.Length - 1 && sect.TerminatorChar == ln.CharAt(i + 1)) { i++; sect.Start.Reset(); continue; } if (mys.Style != 0) { var off1 = backm.DontStyleCompletely || mys.Fallback ? 0 : backm.Start != null ? backm.Start.Length : 0; Styles.StyleRange(mys.Style, line, start - off1, i - (sect.Start == null ? 0 : sect.Start.Length)); mys.Fallback = false; } if (sect.DontStyleCompletely) { var oldi = i; var lineIndex = line; var newCol = i; if (sect.Start.MatchCount > ln.Length) { var shift = sect.Start.MatchCount; var nln = ln; do { shift -= nln.Length; if (nln.Length == 0) { shift--; } if (shift >= 0) { lineIndex--; nln = Editor.Buffer.Document.Lines[lineIndex]; } } while (shift >= 0); newCol = Math.Abs(shift) + 1; } else { newCol = i - sect.Start.MatchCount + 1; } newCol = newCol < 0 ? 0 : newCol; sect.Start.Disabled = true; var tys = mys; for (var ni = lineIndex; ni < line + 1; ni++) { var tst = ParseLine(tys, ref newCol, ni); tys = grammar.Sections[tst.SectionId]; if (newCol >= Lines[ni].Length) { newCol = 0; } else { ni--; } } sect.Start.Disabled = false; sect.Start.Reset(); i = oldi; } i++; if (sect.ExternalGrammarKey != null) { var bd = sect; sect = App.Ext.Grammars().GetGrammar(sect.ExternalGrammarKey).Sections[0]; sect.BackDelegate = bd; } return(Fetch(sect.Id, sect)); } else if (!num && backm.End != null && backm.End.Match(c) == MatchResult.Hit && (backm.EscapeChar == '\0' || backm.EscapeChar != last || (i >= 1 && backm.EscapeChar == ln.CharAt(i - 2)))) { if (i < ln.Length - 1 && backm.TerminatorEndChar == ln.CharAt(i + 1)) { i++; backm.End.Reset(); continue; } if (backm.Style != 0) { var off1 = backm.DontStyleCompletely || backm.Fallback ? 0 : backm.Start != null ? backm.Start.Length : 0; Styles.StyleRange(backm.Style, line, start - off1, i - (backm.DontStyleCompletely ? backm.End.Offset : 0)); backm.Fallback = false; } i++; var parId = mys.ParentId; if (backm == mys.BackDelegate) { mys.BackDelegate = null; parId = backm.ParentId; if (parId != 0) { App.Ext.Grammars().GetGrammar(backm.GrammarKey).Sections[parId].Fallback = true; } } else if (parId != 0) { grammar.Sections[parId].Fallback = true; } if (backm.DontStyleCompletely) { i -= backm.End.MatchCount; i = i < 0 ? 0 : i; } return(Fetch(parId, backm)); } if (!ws) { term = c; lineStart = false; } last = c; lastNonIdent = nonIdent; } var singleLineContinue = !mys.Multiline && mys.ContinuationChar != '\0' && mys.ContinuationChar == term; if (mys.Style != 0 && (mys.Multiline || mys.End == null)) { var off = !mys.DontStyleCompletely ? mys.Start.Length : 0; Styles.StyleRange(mys.Style, line, start - off, ln.Length); } if (mys.End != null && mys.Multiline || mys.End == null && singleLineContinue) { return(Fetch(mys.Id, mys)); } else { return(Fetch(0, mys, mys.Sections.MatchAnyState())); } }
private State Fetch(int sectionId, GrammarSection sect, bool matchAnyState = false) { return(new State(sectionId, sect.GrammarKey, matchAnyState)); }