public static ParseError ResolveDefines(List <Define> defines, ref StringGroup group, int index, string fileName) { string plainText = group.ToString(); foreach (Define define in defines) { var matches = define.FindRegex.Matches(plainText); var commentIndex = plainText.IndexOf(';'); if (matches.Count != 0) { for (int matchIndex = matches.Count - 1; matchIndex >= 0; matchIndex--) { Match match = matches[matchIndex]; if (commentIndex != -1 && match.Index > commentIndex) { continue; } if (define.IsEmpty) { return(new ParseError(ParseErrorType.Preprocessor_ReferenceToEmptyDefine, index, match.Index, fileName)); } if (define.IsParametric) { Match parametricMatch = ParametricDefine.ParametricUsageRegex.Match(plainText); if (parametricMatch.Success) { var subStr = plainText.Substring(parametricMatch.Index, parametricMatch.Length); plainText = plainText.Remove(parametricMatch.Index, parametricMatch.Length); ParseError parseError; var value = (define as ParametricDefine).Expand(subStr, out parseError); if (parseError != null) { return(new ParseError(parseError.Type, index, parametricMatch.Index, fileName)); } plainText = plainText.Insert(parametricMatch.Index, value.ToString()); } else { return(new ParseError(ParseErrorType.Preprocessor_WrongParametricDefineFormat, index, fileName)); } } else { plainText = plainText.Remove(match.Index, match.Length); plainText = plainText.Insert(match.Index, define.Value.ToString()); } } } } group = new StringGroup(plainText.Split('\n')); return(null); }
public ParametricDefine(string name, StringGroup value) : base(name.Split('(')[0], value) { var parts = name.Split('('); var part = parts[1].Trim(')'); part = part.Replace(" ", ""); part = part.Replace("\t", ""); part = part.Replace("\r", ""); ParameterNames = part.Split(',').ToList(); ParameterRegexes = new List <Regex>(); foreach (var item in ParameterNames) { ParameterRegexes.Add(new Regex(string.Format(FindBaseRegex, item))); } IsParametric = true; }
public StringGroup Expand(string input, out ParseError error) { var parts = input.Split('('); var part = parts[1].Trim(')'); part = part.Replace(" ", ""); part = part.Replace("\t", ""); part = part.Replace("\r", ""); var parameters = part.Split(',').ToList(); if (parameters.Count != ParameterNames.Count) { error = new ParseError(ParseErrorType.Preprocessor_WrongParameterCount); return(null); } StringGroup expanded = (StringGroup)Value.Clone(); for (int grCouter = 0; grCouter < expanded.Strings.Count; grCouter++) { for (int i = 0; i < parameters.Count; i++) { var matches = ParameterRegexes[i].Matches(expanded.Strings[grCouter]); for (int j = matches.Count - 1; j >= 0; j--) { expanded.Strings[grCouter] = expanded.Strings[grCouter] .Remove(matches[j].Index, matches[j].Length); expanded.Strings[grCouter] = expanded.Strings[grCouter] .Insert(matches[j].Index, parameters[i]); } } } error = null; return(expanded); }
internal abstract List <SourceLine> Apply(StringGroup input, Stack <bool> enableList, List <Define> defines, out ParseError error, Func <string, PreprocessorParseResult> recursiveFunc);
internal abstract void Apply(StringGroup input, Stack <bool> enableList, List <Define> defines, out ParseError error);
private static PreprocessorParseResult RecursiveParse(string fileName) { var result = new List <SourceLine>(); if (!File.Exists(fileName)) { fileName = new FileInfo(Path.Combine(workingDirectory, fileName)).FullName; } if (!File.Exists(fileName)) { return(new PreprocessorParseResult( null, new ParseError(ParseErrorType.IO_UnabletoFindSpecifiedFile, -1, fileName))); } if (Cache.FileCache.ContainsKey(fileName)) { FileCache cache = Cache.FileCache[fileName]; if (cache.CompiledDefines != null) { defines.AddRange(cache.CompiledDefines); } return(new PreprocessorParseResult(new List <SourceLine>(), null)); } List <StringGroup> stringGroups = getLinesFunc(fileName); int index = -1; for (int i = 0; i < stringGroups.Count; i++) { StringGroup group = stringGroups[i]; if (!group.IsSingleLine && !group.IsMultilineDefine) { return(new PreprocessorParseResult(null, new ParseError(ParseErrorType.Preprcessor_MultilineNonDefinesAreNotAllowed, index, fileName))); } if (group.IsMultilineDefine) { ParseError error; PreprocessorDirective directive = GetDirective(group.Strings.First(), index, fileName, out error); if (error != null) { return(new PreprocessorParseResult(null, error)); } ParseError parseError; //Preprocessor.Directives.PreprocessorDefine. directive.Apply(group, enableStack, defines, out parseError); if (parseError != null) { return(new PreprocessorParseResult(null, new ParseError(parseError.Type, index, fileName))); } index += group.Strings.Count; } if (group.IsSingleLine) { index++; string line = group.AsSingleLine(); if (IsPreprocessorLine(line)) { ParseError error; PreprocessorDirective directive = GetDirective(line, index, fileName, out error); if (error != null) { return(new PreprocessorParseResult(null, error)); } if (directive.CanAddNewLines) { ParseError parseError; var newLines = directive.Apply(new StringGroup(line), enableStack, defines, out parseError, RecursiveParse); if (parseError != null) { return(new PreprocessorParseResult(null, parseError)); } result.AddRange(newLines); } else { ParseError parseError; directive.Apply(new StringGroup(line), enableStack, defines, out parseError); if (parseError != null) { return(new PreprocessorParseResult(null, new ParseError(parseError.Type, index, fileName))); } } } else { if (!enableStack.Contains(false)) { if (string.IsNullOrWhiteSpace(line)) { continue; } ParseError parseError = Define.ResolveDefines(defines, ref group, index, fileName); if (parseError != null) { return(new PreprocessorParseResult(null, parseError)); } group.Strings.ForEach(p => { result.Add(new SourceLine(p, index, fileName)); }); } } } else { //STUB } } return(new PreprocessorParseResult(result, null)); }
public Define(string name, StringGroup value) { Name = name; Value = value; InitRegex(); }