Fixed with regex improvements. Also enabled ELUP detection for autocompletion

This commit is contained in:
Olivier Guinart 2017-01-14 18:56:21 -08:00
parent a7a3708a53
commit 22df541220
4 changed files with 71 additions and 37 deletions

View File

@ -8,29 +8,34 @@ namespace VSMerlin32.Coloring
{
internal class Merlin32CodeHelper
{
const string COMMENT_REG = @"((\u003B)|(\u002A))(.*)"; // ;
const string TEXT_REG = @"(""|')[^']*(""|')";
// OPCODE_REG is initialized dynamically below.
static string OPCODE_REG = "";
static string DIRECTIVE_REG = "";
static string DATADEFINE_REG = "";
const string CommentRegex = @"((\u003B)|(\u002A))(.*)"; // ;
const string TextRegex = @"(""|')[^']*(""|')";
// OPCODE_REG and below are initialized dynamically below.
const string RegexBoilerplate = @"(\b|\s)(?<{0}>{1})(\b|\s)";
const string Opcode = "OPCODE";
const string Data = "DATA";
const string Directive = "DIRECTIVE";
const string Elup = "ELUP";
static string OpcodeRegex = "";
static string DirectiveRegex = "";
static string DataRegex = "";
public static IEnumerable<SnapshotHelper> GetTokens(SnapshotSpan span)
{
string strTempRegex; // temp var string
string TempRegex; // temp var string
ITextSnapshotLine containingLine = span.Start.GetContainingLine();
int curLoc = containingLine.Start.Position;
string formattedLine = containingLine.GetText();
int commentMatch = int.MaxValue;
Regex reg = new Regex(COMMENT_REG);
Regex reg = new Regex(CommentRegex);
foreach (Match match in reg.Matches(formattedLine))
{
commentMatch = match.Index < commentMatch ? match.Index : commentMatch;
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Comment);
}
reg = new Regex(TEXT_REG);
reg = new Regex(TextRegex);
foreach (Match match in reg.Matches(formattedLine))
{
if (match.Index < commentMatch)
@ -39,55 +44,83 @@ namespace VSMerlin32.Coloring
// OG NEW
// OPCODES
strTempRegex = "";
TempRegex = "";
foreach (Merlin32Opcodes token in Enum.GetValues(typeof(Merlin32Opcodes)))
{
strTempRegex += (token.ToString() + ("|"));
TempRegex += (token.ToString() + ("|"));
}
// we remove the last "|" added
strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|"));
OPCODE_REG = string.Format(@"\b({0})\b", strTempRegex);
TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
OpcodeRegex = string.Format(RegexBoilerplate, Opcode, TempRegex);
reg = new Regex(OPCODE_REG,RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(formattedLine))
reg = new Regex(OpcodeRegex,RegexOptions.IgnoreCase);
Match opcodeMatch = reg.Match(formattedLine);
if (opcodeMatch.Success)
{
if (match.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Opcode);
foreach (Capture opcode in opcodeMatch.Groups[Opcode].Captures)
{
// An opcode after within a comment doesn't get a SnapShotSpan...
if (opcode.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, opcode.Index + curLoc), opcode.Length), Merlin32TokenTypes.Merlin32Opcode);
}
}
// OG NEW
// DIRECTIVES
strTempRegex = "";
TempRegex = "";
string ElupDirective = Resources.directives.ELUP;
foreach (Merlin32Directives token in Enum.GetValues(typeof(Merlin32Directives)))
{
if (token.ToString() != Resources.directives.ELUP)
strTempRegex += (token.ToString() + ("|"));
if (token.ToString() != ElupDirective)
TempRegex += (token.ToString() + ("|"));
}
DIRECTIVE_REG = string.Format(@"\b({0})\b|{1}", strTempRegex, Resources.directives.ELUPRegex);
reg = new Regex(DIRECTIVE_REG, RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(formattedLine))
// we remove the last "|" added
TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
DirectiveRegex = string.Format(RegexBoilerplate, Directive, TempRegex);
reg = new Regex(DirectiveRegex, RegexOptions.IgnoreCase);
Match DirectiveMatch = reg.Match(formattedLine);
if (DirectiveMatch.Success)
{
if (match.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32Directive);
foreach (Capture directive in DirectiveMatch.Groups[Directive].Captures)
{
if (directive.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, directive.Index + curLoc), directive.Length), Merlin32TokenTypes.Merlin32Directive);
}
}
// We also need to check for special ELUP directive...
reg = new Regex(Resources.directives.ELUPRegex);
Match ElupMatch = reg.Match(formattedLine);
if (ElupMatch.Success)
{
foreach (Capture elup in ElupMatch.Groups[Elup].Captures)
{
if (elup.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, elup.Index + curLoc), elup.Length), Merlin32TokenTypes.Merlin32Directive);
}
}
// OG NEW
// DATADEFINES
strTempRegex = "";
TempRegex = "";
foreach (Merlin32DataDefines token in Enum.GetValues(typeof(Merlin32DataDefines)))
{
strTempRegex += (token.ToString() + ("|"));
TempRegex += (token.ToString() + ("|"));
}
// we remove the last "|" added
strTempRegex = strTempRegex.Remove(strTempRegex.LastIndexOf("|"));
DATADEFINE_REG = string.Format(@"\b({0})\b", strTempRegex);
TempRegex = TempRegex.Remove(TempRegex.LastIndexOf("|"));
DataRegex = string.Format(RegexBoilerplate, Data, TempRegex);
reg = new Regex(DATADEFINE_REG, RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(formattedLine))
reg = new Regex(DataRegex, RegexOptions.IgnoreCase);
Match dataMatch = reg.Match(formattedLine);
if (dataMatch.Success)
{
if (match.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, match.Index + curLoc), match.Length), Merlin32TokenTypes.Merlin32DataDefine);
foreach (Capture data in dataMatch.Groups[Data].Captures)
{
if (data.Index < commentMatch)
yield return new SnapshotHelper(new SnapshotSpan(new SnapshotPoint(span.Snapshot, data.Index + curLoc), data.Length), Merlin32TokenTypes.Merlin32DataDefine);
}
}
}
}

View File

@ -107,7 +107,8 @@ namespace VSMerlin32
//pass along the command so the char is added to the buffer
int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
bool handled = false;
if (!typedChar.Equals(char.MinValue) && ((char.IsLetterOrDigit(typedChar)) || ((typedChar == '\'') || (typedChar == '"'))))
// Test for '-' is to catch ELUP (--^)
if (!typedChar.Equals(char.MinValue) && ((char.IsLetterOrDigit(typedChar)) || ((typedChar == '\'') || (typedChar == '"') || (typedChar == '-'))))
{
if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
{

View File

@ -151,7 +151,7 @@ namespace VSMerlin32.Resources {
}
/// <summary>
/// Looks up a localized string similar to (--\^).
/// Looks up a localized string similar to (^|\s)(?&lt;ELUP&gt;--\^)(\s|$).
/// </summary>
internal static string ELUPRegex {
get {

View File

@ -148,7 +148,7 @@
<value>End of LUP</value>
</data>
<data name="ELUPRegex" xml:space="preserve">
<value>(--\^)</value>
<value>(^|\s)(?&lt;ELUP&gt;--\^)(\s|$)</value>
</data>
<data name="ELUPValue" xml:space="preserve">
<value>--^</value>