public object VisitKeywords(XshdKeywords keywords)
            {
                if (keywords.Words.Count == 0)
                {
                    return(Error(keywords, "Keyword group must not be empty."));
                }
                foreach (string keyword in keywords.Words)
                {
                    if (string.IsNullOrEmpty(keyword))
                    {
                        throw Error(keywords, "Cannot use empty string as keyword");
                    }
                }
                StringBuilder keyWordRegex = new StringBuilder();

                // We can use "\b" only where the keyword starts/ends with a letter or digit, otherwise we don't
                // highlight correctly. (example: ILAsm-Mode.xshd with ".maxstack" keyword)
                if (keywords.Words.All(IsSimpleWord))
                {
                    keyWordRegex.Append(@"\b(?>");
                    // (?> = atomic group
                    // atomic groups increase matching performance, but we
                    // must ensure that the keywords are sorted correctly.
                    // "\b(?>in|int)\b" does not match "int" because the atomic group captures "in".
                    // To solve this, we are sorting the keywords by descending length.
                    int i = 0;
                    foreach (string keyword in keywords.Words.OrderByDescending(w => w.Length))
                    {
                        if (i++ > 0)
                        {
                            keyWordRegex.Append('|');
                        }
                        keyWordRegex.Append(Regex.Escape(keyword));
                    }
                    keyWordRegex.Append(@")\b");
                }
                else
                {
                    keyWordRegex.Append('(');
                    int i = 0;
                    foreach (string keyword in keywords.Words)
                    {
                        if (i++ > 0)
                        {
                            keyWordRegex.Append('|');
                        }
                        if (char.IsLetterOrDigit(keyword[0]))
                        {
                            keyWordRegex.Append(@"\b");
                        }
                        keyWordRegex.Append(Regex.Escape(keyword));
                        if (char.IsLetterOrDigit(keyword[keyword.Length - 1]))
                        {
                            keyWordRegex.Append(@"\b");
                        }
                    }
                    keyWordRegex.Append(')');
                }
                return(new HighlightingRule
                {
                    Color = GetColor(keywords, keywords.ColorReference),
                    Regex = CreateRegex(keywords, keyWordRegex.ToString(), XshdRegexType.Default)
                });
            }
 public object VisitKeywords(XshdKeywords keywords)
 {
     return(keywords.ColorReference.AcceptVisitor(this));
 }