/// <summary>
        /// Tries to parse the dataFields using the delimiter and fields. If true,
        /// result will hold an IStringConverter that can convert all valid input
        /// in the form of dataFields, only extracting fields.
        /// </summary>
        /// <param name="dataFields">Input string</param>
        /// <param name="delimiter">Seperator</param>
        /// <param name="fields">Required (conversion) fields</param>
        /// <param name="result">Converter</param>
        /// <param name="options">Parseoptions</param>
        /// <returns>Parse is possible</returns>
        public static Boolean TryParse(String dataFields, Char delimiter, String[] fields, out IStringConverter result, 
            ParseOptions options = ParseOptions.CleanupQuotes)
        {
            result = new DelimiterConverter(delimiter);

            var splittedDataFields = new Queue<String>(dataFields.Split(delimiter));
            var fieldsQueue = new Queue<String>(fields);

            while (fieldsQueue.Count > 0 && splittedDataFields.Count > 0)
            {
                var field = fieldsQueue.Peek();
                var data = splittedDataFields.Dequeue().Trim();

                if (options.HasFlag(ParseOptions.GlueStrings))
                    while (data.StartsWith("\"") && !data.EndsWith("\"") && splittedDataFields.Count > 0)
                        data = data + "," + splittedDataFields.Dequeue().Trim();

                if (options.HasFlag(ParseOptions.CleanupQuotes))
                    data = data.Replace("\"", "").Trim();

                (result as DelimiterConverter).PushMask(field == data);

                if (field == data)
                    fieldsQueue.Dequeue();
            }

            return fieldsQueue.Count == 0;
        }
        public static Expression Parse(string expression, ParseOptions options = ParseOptions.None)
        {
            if (options.HasFlag(ParseOptions.IgnoreWhitespace))
            {
                expression = Regex.Replace(expression, @"\s", "");
            }

            var nestMap = new Dictionary <char, string>();

            expression = MapTopLevelStatements(expression, nestMap);

            var instance = CreatePipeline(expression, nestMap);

            return(instance);
        }
Beispiel #3
0
        /// <summary>
        /// Parses a given text into IncludeLineInfo objects.
        /// </summary>
        /// <returns>A list of parsed lines.</returns>
        public static List <IncludeLineInfo> ParseIncludes(string text, ParseOptions options)
        {
            StringReader reader = new StringReader(text);

            var outInfo = new List <IncludeLineInfo>();

            // Simplistic parsing.
            int    openMultiLineComments = 0;
            int    openIfdefs            = 0;
            string lineText;

            for (int lineNumber = 0; true; ++lineNumber)
            {
                lineText = reader.ReadLine();
                if (lineText == null)
                {
                    break;
                }

                if (options.HasFlag(ParseOptions.RemoveEmptyLines) && string.IsNullOrWhiteSpace(lineText))
                {
                    continue;
                }

                int commentedSectionStart = int.MaxValue;
                int commentedSectionEnd   = int.MaxValue;

                // Check for single line comment.
                {
                    int singleLineCommentStart = lineText.IndexOf("//");
                    if (singleLineCommentStart != -1)
                    {
                        commentedSectionStart = singleLineCommentStart;
                    }
                }

                // Check for multi line comments.
                {
                    int multiLineCommentStart = lineText.IndexOf("/*");
                    if (multiLineCommentStart > -1 && multiLineCommentStart < commentedSectionStart)
                    {
                        ++openMultiLineComments;
                        commentedSectionStart = multiLineCommentStart;
                    }

                    int multiLineCommentEnd = lineText.IndexOf("*/");
                    if (multiLineCommentEnd > -1)
                    {
                        --openMultiLineComments;
                        commentedSectionEnd = multiLineCommentEnd;
                    }
                }

                bool isCommented(int pos) => (commentedSectionStart == int.MaxValue && openMultiLineComments > 0) || (pos > commentedSectionStart && pos < commentedSectionEnd);

                // Check for #if / #ifdefs.
                if (options.HasFlag(ParseOptions.IgnoreIncludesInPreprocessorConditionals))
                {
                    // There can be only a single preprocessor directive per line, so no need to parse more than this.
                    int ifdefStart = lineText.IndexOf("#if");
                    int ifdefEnd   = lineText.IndexOf("#endif");
                    if (ifdefStart > -1 && !isCommented(ifdefStart))
                    {
                        ++openIfdefs;
                    }
                    else if (ifdefEnd > -1 && !isCommented(ifdefEnd))
                    {
                        --openIfdefs;
                    }
                }

                int includeOccurence = lineText.IndexOf("#include");

                // Not a valid include.
                if (includeOccurence == -1 ||        // Include not found
                    isCommented(includeOccurence) || // Include commented out
                    openIfdefs > 0)                  // Inside an #ifdef block
                {
                    if (!options.HasFlag(ParseOptions.KeepOnlyValidIncludes))
                    {
                        outInfo.Add(new IncludeLineInfo()
                        {
                            lineText = lineText, LineNumber = lineNumber
                        });
                    }
                }
                // A valid include
                else
                {
                    // Parse include delimiters.
                    int delimiter1 = -1;
                    int delimiter0 = lineText.IndexOf('\"', includeOccurence + "#include".Length);
                    if (delimiter0 == -1)
                    {
                        delimiter0 = lineText.IndexOf('<', includeOccurence + "#include".Length);
                        if (delimiter0 != -1)
                        {
                            delimiter1 = lineText.IndexOf('>', delimiter0 + 1);
                        }
                    }
                    else
                    {
                        delimiter1 = lineText.IndexOf('\"', delimiter0 + 1);
                    }

                    // Might not be valid after all!
                    if (delimiter0 != -1 && delimiter1 != -1)
                    {
                        outInfo.Add(new IncludeLineInfo()
                        {
                            lineText = lineText, LineNumber = lineNumber, delimiter0 = delimiter0, delimiter1 = delimiter1
                        });
                    }
                    else if (!options.HasFlag(ParseOptions.KeepOnlyValidIncludes))
                    {
                        outInfo.Add(new IncludeLineInfo()
                        {
                            lineText = lineText, LineNumber = lineNumber
                        });
                    }
                }
            }

            return(outInfo);
        }