/// <summary> /// Инициализация анализатора /// </summary> private void Initialize() { InitKeyWords(); InitKeySymbols(); InitComments(); InitFileMap(); InitMetaTags(); DfmRegex = new Regex("^\\$R (?<dfm>.*)\\.dfm$", RegexOptions.IgnoreCase); List <string> keys = new List <string>(metatags.Keys); string regex = string.Empty; foreach (string metatag in keys) { regex = string.Format("{0}|(\\#{1}\\s+(?<{1}Data>[^\\n]*)\\s*$)", regex, metatag); metatags[metatag] = string.Empty; } if (regex.Length > 0) { regex = string.Format("^{0}", regex.Substring(1)); } MetaRegex = new Regex(regex, RegexOptions.IgnoreCase); index = 0; token = DelphiTokens.Undefined; currentId = string.Empty; }
public TokenInfo(DelphiTokens token, string text, int line, Dictionary <string, string> metatags) { this.token = token; this.text = text; this.line = line; this.metatags = metatags; }
/// <summary> /// Считывание токена с заглядыванием назад /// </summary> /// <param name="token">токен, который должен был быть</param> /// <returns>результат считывания</returns> public bool Match(DelphiTokens token) { if (Current.Token == token) { return(Next()); } else { return(false); } }
/// <summary> /// Считывание токена с игнорирование комментариев /// </summary> private void SkipScan() { Scan(); while (comments.Contains(token)) { if (token == DelphiTokens.OComment) { Match match = DfmRegex.Match(currentId); if (match.Success) { string filename = (match.Groups["dfm"].Captures[0].Value == "*") ? file.Name.Substring(0, file.Name.LastIndexOf(".")) : match.Groups["dfm"].Captures[0].Value; filename = string.Format("{0}\\{1}.dfm", file.DirectoryName, filename); if (DfmInclusionEvent != null) { AnalyserParameters p = new AnalyserParameters(new FileInfo(filename)); p.AddToken(new TokenInfo(DelphiTokens.OComment, currentId, Line, metatags)); DfmInclusionEvent(this, p); } } else { MatchCollection matches = MetaRegex.Matches(currentId); foreach (Match m in matches) { List <string> keys = new List <string>(metatags.Keys); foreach (string metatag in keys) { if (m.Groups[string.Format("{0}Data", metatag)].Captures.Count > 0) { metatags[metatag] = m.Groups[string.Format("{0}Data", metatag)].Value; } } } } } Scan(); } if ((token == DelphiTokens.Id) && keywords.ContainsKey(currentId.ToLower())) { token = keywords[currentId.ToLower()]; } }
/// <summary> /// Чтение одного токена /// </summary> private void Scan() { token = DelphiTokens.Undefined; currentId = string.Empty; if (index >= source.Length) { token = DelphiTokens.FileEnd; return; } char c; int state = 1; while (index < source.Length) { c = source[index]; switch (state) { case 1: if (DelphiAnalyser.Addition.DChar.IsLetter(c) || (c == '_')) { currentId += c; token = DelphiTokens.Id; state = 2; } else if (DelphiAnalyser.Addition.DChar.IsDigit(c)) { currentId += c; token = DelphiTokens.Digits; state = 3; } else { switch (c) { case '/': token = DelphiTokens.Division; state = 4; break; case '>': token = DelphiTokens.Greater; state = 8; break; case '<': token = DelphiTokens.Less; state = 9; break; case '.': token = DelphiTokens.Dot; state = 10; break; case ':': token = DelphiTokens.Colon; state = 11; break; case '$': state = 12; break; case '#': state = 14; break; case '\'': state = 16; break; case '(': token = DelphiTokens.LBr; state = 17; break; case '{': token = DelphiTokens.OComment; state = 20; break; case '\n': filemap.AddLine(index + 1); break; case '*': case '+': case '-': case '=': case ',': case ';': case ')': case '[': case ']': case '}': case '@': case '^': index++; token = keysymbols[c.ToString()]; return; } } break; case 2: if (DelphiAnalyser.Addition.DChar.IsLetterOrDigit(c) || (c == '_')) { currentId += c; } else { return; } break; case 3: if (DelphiAnalyser.Addition.DChar.IsDigit(c)) { currentId += c; } else { return; } break; case 4: switch (c) { case '/': token = DelphiTokens.LComment; state = 5; break; case '*': token = DelphiTokens.MLComment; state = 6; break; default: return; } break; case 5: if (c == '\n') { return; } else { currentId += c; } break; case 6: if (c == '*') { state = 7; } else { if (c == '\n') { filemap.AddLine(index + 1); } currentId += c; } break; case 7: if (c == '/') { index++; return; } else { currentId += '*'; if (c != '*') { if (c == '\n') { filemap.AddLine(index + 1); } currentId += c; state = 6; } } break; case 8: if (c == '=') { token = DelphiTokens.GreaterOrEqual; index++; } return; case 9: switch (c) { case '=': token = DelphiTokens.LessOrEqual; index++; break; case '>': token = DelphiTokens.NotEqual; index++; return; } return; case 10: if (c == '.') { token = DelphiTokens.Interval; index++; } return; case 11: if (c == '=') { token = DelphiTokens.Assigment; index++; } return; case 12: if (DelphiAnalyser.Addition.DChar.IsHexSymbol(c)) { currentId += c; token = DelphiTokens.HexConstant; state = 13; } break; case 13: if (DelphiAnalyser.Addition.DChar.IsHexSymbol(c)) { currentId += c; } else { return; } break; case 14: if (DelphiAnalyser.Addition.DChar.IsDigit(c)) { currentId += c; token = DelphiTokens.Char; state = 15; } else if (c == '$') { currentId += c; state = 21; } else { return; } break; case 15: if (DelphiAnalyser.Addition.DChar.IsDigit(c)) { currentId += c; } else { return; } break; case 16: if (c == '\'') { token = (currentId.Length == 1) ? DelphiTokens.Char : DelphiTokens.String; index++; return; } else if (c == '\n') { return; } else { currentId += c; } break; case 17: if (c == '*') { token = DelphiTokens.BComment; state = 18; } else { return; } break; case 18: if (c == '*') { state = 19; } else { if (c == '\n') { filemap.AddLine(index + 1); } currentId += c; } break; case 19: if (c == ')') { index++; return; } else { currentId += '*'; if (c != '*') { if (c == '\n') { filemap.AddLine(index + 1); } currentId += c; state = 18; } } break; case 20: if (c == '}') { index++; return; } else { if (c == '\n') { filemap.AddLine(index + 1); } currentId += c; } break; case 21: if (DelphiAnalyser.Addition.DChar.IsHexSymbol(c)) { currentId += c; token = DelphiTokens.Char; state = 22; } else { return; } break; case 22: if (DelphiAnalyser.Addition.DChar.IsHexSymbol(c)) { currentId += c; } else { return; } break; } index++; } }
/// <summary> /// Сравнение токена с текущим /// </summary> /// <returns>результат сравнения</returns> public bool MatchTokens(DelphiTokens t) { return(MatchTokens(Current.Token, t)); }
/// <summary> /// Сравнивнение токенов /// </summary> /// <returns>результат сравнения</returns> public bool MatchTokens(DelphiTokens t1, DelphiTokens t2) { return(t1 == t2); }