How could I refactor this into more manageable code?

Posted by ChaosPandion on Stack Overflow See other posts from Stack Overflow or by ChaosPandion
Published on 2010-04-16T09:02:28Z Indexed on 2010/04/16 13:43 UTC
Read the original article Hit count: 276

Filed under:
|
|
|
private static JsonStructure Parse(string jsonText, bool throwException)
{
    var result = default(JsonStructure);
    var structureStack = new Stack<JsonStructure>();
    var keyStack = new Stack<string>();
    var current = default(JsonStructure);
    var currentState = ParserState.Begin;
    var invalidToken = false;
    var key = default(string);
    var value = default(object);

    foreach (var token in Lexer.Tokenize(jsonText))
    {
        switch (currentState)
        {
            case ParserState.Begin:
                switch (token.Type)
                {
                    case TokenType.OpenBrace:
                        currentState = ParserState.ObjectKey;
                        current = result = new JsonObject();
                        break;
                    case TokenType.OpenBracket:
                        currentState = ParserState.ArrayValue;
                        current = result = new JsonArray();
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            case ParserState.ObjectKey:
                switch (token.Type)
                {
                    case TokenType.StringLiteral:
                        currentState = ParserState.ColonSeperator;
                        key = (string)token.Value;
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            case ParserState.ColonSeperator:
                switch (token.Type)
                {
                    case TokenType.Colon:
                        currentState = ParserState.ObjectValue;
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            case ParserState.ObjectValue:
            case ParserState.ArrayValue:
                switch (token.Type)
                {
                    case TokenType.NumberLiteral:
                    case TokenType.StringLiteral:
                    case TokenType.BooleanLiteral:
                    case TokenType.NullLiteral:
                        currentState = ParserState.ItemEnd;
                        value = token.Value;
                        break;
                    case TokenType.OpenBrace:
                        structureStack.Push(current);
                        keyStack.Push(key);
                        currentState = ParserState.ObjectKey;
                        current = new JsonObject();
                        break;
                    case TokenType.OpenBracket:
                        structureStack.Push(current);
                        currentState = ParserState.ArrayValue;
                        current = new JsonArray();
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            case ParserState.ItemEnd:
                var jsonObject = (current as JsonObject);
                if (jsonObject != null)
                {
                    jsonObject.Add(key, value);
                    currentState = ParserState.ObjectKey;
                }
                var jsonArray = (current as JsonArray);
                if (jsonArray != null)
                {
                    jsonArray.Add(value);
                    currentState = ParserState.ArrayValue;
                }
                switch (token.Type)
                {
                    case TokenType.CloseBrace:
                    case TokenType.CloseBracket:
                        currentState = ParserState.End;
                        break;
                    case TokenType.Comma:
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            case ParserState.End:
                switch (token.Type)
                {
                    case TokenType.CloseBrace:
                    case TokenType.CloseBracket:
                    case TokenType.Comma:
                        var previous = structureStack.Pop();
                        var previousJsonObject = (previous as JsonObject);
                        if (previousJsonObject != null)
                        {
                            currentState = ParserState.ObjectKey;
                            previousJsonObject.Add(keyStack.Pop(), current);
                        }
                        var previousJsonArray = (previous as JsonArray);
                        if (previousJsonArray != null)
                        {
                            currentState = ParserState.ArrayValue;
                            previousJsonArray.Add(current);
                        }
                        current = previous;
                        if (token.Type != TokenType.Comma)
                        {
                            currentState = ParserState.End;
                        }
                        break;
                    default:
                        invalidToken = true;
                        break;
                }
                break;
            default:
                break;
        }

        if (invalidToken)
        {
            if (throwException)
            {
                throw new JsonException(token);
            }
            return null;
        }
    }
    return result;
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about refactoring