예제 #1
0
        private bool ProcessChar(int i, char lineChar, out string errorText)
        {
            result    = true;
            errorText = null;

            switch (parseState)
            {
            case ParseState.NotInParam:
                if (lineChar == quoteChar)
                {
                    parseState = ParseState.TextParam;
                    textParamIdx++;
                    startIdx = i;
                    textBldr.Clear();
                    quoted = true;
                }
                else
                {
                    if (Array.IndexOf <char>(optionParamAnnouncerChars, lineChar) >= 0)
                    {
                        parseState       = ParseState.OptionParam;
                        parseOptionState = ParseOptionState.Announced;
                        startIdx         = i + 1;
                    }
                    else
                    {
                        if (Array.IndexOf <char>(parseTerminateChars, lineChar) >= 0)
                        {
                            ignoreRestOfLine = true;
                        }
                        else
                        {
                            if (!char.IsWhiteSpace(lineChar))
                            {
                                parseState = ParseState.TextParam;
                                textParamIdx++;
                                startIdx = i;
                                textBldr.Clear();
                                textBldr.Append(lineChar);
                                quoted = false;
                            }
                        }
                    }
                }
                break;

            case ParseState.TextParam:
                if (!quoted)
                {
                    if (!char.IsWhiteSpace(lineChar))
                    {
                        textBldr.Append(lineChar);
                    }
                    else
                    {
                        result     = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText);
                        parseState = ParseState.NotInParam;
                    }
                }
                else
                {
                    if (lineChar != QuoteChar)
                    {
                        textBldr.Append(lineChar);
                    }
                    else
                    {
                        parseState = ParseState.TextParamPossibleEndQuote;
                    }
                }
                break;

            case ParseState.TextParamPossibleEndQuote:
                if (lineChar == QuoteChar)
                {
                    textBldr.Append(lineChar);
                    parseState = ParseState.TextParam;
                }
                else
                {
                    if (char.IsWhiteSpace(lineChar))
                    {
                        result     = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText);
                        parseState = ParseState.NotInParam;
                    }
                    else
                    {
                        result = PrepareErrorText(CLParserError.Id.InvalidQuoteCharacterInTextParameter, textBldr.ToString(), out errorText);
                    }
                }
                break;

            case ParseState.OptionParam:
                switch (parseOptionState)
                {
                case ParseOptionState.Announced:
                    if (char.IsWhiteSpace(lineChar) || Array.IndexOf <char>(optionTerminationChars, lineChar) >= 0)
                    {
                        result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, i.ToString(), out errorText);
                    }
                    else
                    {
                        parseOptionState = ParseOptionState.Name;
                    }
                    break;

                case ParseOptionState.Name:
                    bool optionValueAnnounced = lineChar == optionParamValueAnnouncerChar;
                    if (optionValueAnnounced || char.IsWhiteSpace(lineChar) || Array.IndexOf <char>(optionTerminationChars, lineChar) >= 0)
                    {
                        optionName = parseLine.Substring(startIdx, i - startIdx);
                        if (optionName == "")
                        {
                            result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, i.ToString(), out errorText);
                        }
                        else
                        {
                            if (optionValueAnnounced)
                            {
                                if (optionParamValueAnnouncerIsWhiteSpace)
                                {
                                    parseOptionState = ParseOptionState.ValuePossible;
                                }
                                else
                                {
                                    parseOptionState = ParseOptionState.ValueAnnounced;
                                }
                            }
                            else
                            {
                                result = ProcessOption(optionName, null, out errorText);
                                if (result)
                                {
                                    parseState = ParseState.NotInParam;
                                }
                            }
                        }
                    }
                    break;

                case ParseOptionState.ValuePossible:
                    if (!char.IsWhiteSpace(lineChar))
                    {
                        if (
                            Array.IndexOf <char>(optionParamAnnouncerChars, lineChar) < 0 // not a new option
                            &&
                            CanOptionHaveValue(optionName)                                // option can have values
                            )
                        {
                            parseOptionState = ParseOptionState.ValueAnnounced;
                            result           = ProcessChar(i, lineChar, out errorText); // process first char of value
                        }
                        else
                        {
                            result = ProcessOption(optionName, null, out errorText);         // process current option
                            if (result)
                            {
                                parseState = ParseState.NotInParam;
                                result     = ProcessChar(i, lineChar, out errorText);     // will handle new option/text param
                            }
                        }
                    }
                    break;

                case ParseOptionState.ValueAnnounced:
                    startIdx = i;
                    textBldr.Clear();
                    if (char.IsWhiteSpace(lineChar))
                    {
                        result     = ProcessOption(optionName, "", out errorText);
                        parseState = ParseState.NotInParam;
                    }
                    else
                    {
                        if (lineChar == QuoteChar)
                        {
                            quoted = true;
                        }
                        else
                        {
                            quoted = false;
                            textBldr.Append(lineChar);
                        }
                        parseOptionState = ParseOptionState.Value;
                    }
                    break;

                case ParseOptionState.Value:
                    if (!quoted)
                    {
                        if (!char.IsWhiteSpace(lineChar))
                        {
                            textBldr.Append(lineChar);
                        }
                        else
                        {
                            result     = ProcessOption(optionName, textBldr.ToString(), out errorText);
                            parseState = ParseState.NotInParam;
                        }
                    }
                    else
                    {
                        if (lineChar != QuoteChar)
                        {
                            textBldr.Append(lineChar);
                        }
                        else
                        {
                            parseOptionState = ParseOptionState.ValuePossibleEndQuote;
                        }
                    }
                    break;

                case ParseOptionState.ValuePossibleEndQuote:
                    if (lineChar == QuoteChar)
                    {
                        textBldr.Append(lineChar);
                        parseOptionState = ParseOptionState.Value;
                    }
                    else
                    {
                        if (char.IsWhiteSpace(lineChar))
                        {
                            result     = ProcessOption(optionName, textBldr.ToString(), out errorText);
                            parseState = ParseState.NotInParam;
                        }
                        else
                        {
                            result = PrepareErrorText(CLParserError.Id.InvalidQuoteCharacterInOptionValue, optionName, out errorText);
                        }
                    }
                    break;
                }
                break;
            }

            return(result);
        }
예제 #2
0
        public virtual bool Parse(string line, out string errorText)
        {
            parseLine              = line;
            textParamIdx           = -1;
            parseState             = ParseState.NotInParam;
            parseOptionState       = ParseOptionState.Announced;
            startIdx               = -1;
            optionName             = null;
            quoted                 = false;
            ignoreRestOfLine       = false;
            textBldr               = new StringBuilder(30);
            optionTerminationChars = CreateOptionTerminationCharArray();
            errorText              = null;

            for (int i = 0; i < line.Length; i++)
            {
                result = ProcessChar(i, line[i], out errorText);
                if (!result || ignoreRestOfLine)
                {
                    break;
                }
            }

            if (result && !ignoreRestOfLine)
            {
                switch (parseState)
                {
                case ParseState.NotInParam:
                    break;

                case ParseState.TextParam:
                    if (quoted)
                    {
                        result = PrepareErrorText(CLParserError.Id.TextMissingClosingQuoteCharacter, null, out errorText);
                    }
                    else
                    {
                        result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText);
                    }
                    break;

                case ParseState.TextParamPossibleEndQuote:
                    result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText);
                    break;

                case ParseState.OptionParam:
                    switch (parseOptionState)
                    {
                    case ParseOptionState.Announced:
                        result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, line.Length.ToString(), out errorText);
                        break;

                    case ParseOptionState.Name:
                        optionName = line.Substring(startIdx, line.Length - startIdx);
                        result     = ProcessOption(optionName, null, out errorText);
                        break;

                    case ParseOptionState.ValuePossible:
                        result = ProcessOption(optionName, null, out errorText);
                        break;

                    case ParseOptionState.ValueAnnounced:
                        result = ProcessOption(optionName, "", out errorText);
                        break;

                    case ParseOptionState.Value:
                        if (quoted)
                        {
                            result = PrepareErrorText(CLParserError.Id.OptionMissingClosingQuoteCharacter, optionName, out errorText);
                        }
                        else
                        {
                            result = ProcessOption(optionName, textBldr.ToString(), out errorText);
                        }
                        break;

                    case ParseOptionState.ValuePossibleEndQuote:
                        result = ProcessOption(optionName, textBldr.ToString(), out errorText);
                        break;
                    }
                    break;

                default:
                    Debug.Assert(false, "False");
                    break;
                }
            }

            return(result);
        }