2010-03-08 7 views
3

eval을 사용하지 않고 어떻게 작동하는지 이해할 수 없습니다 -이 문제의 비밀은 무엇입니까?JSON 파서가 eval을 전혀 사용하지 않고 어떻게 작동하는지 설명 할 수 있습니까?

편집 : 누군가 트리 구조가 개체로 변환되는 방법에 대한 간단한 예를 제시 할 수 있습니까?

+0

은의 중복 가능성 [JSON 데이터 - Eval'ed '파싱 또는 (http://stackoverflow.com/questions/1143417/json-data-parsed-or-evaled) – outis

답변

1

평가하지 않고 객체로 JSON 문자열을 변환하는 방법의 사소한 예 :

var txt='[\'one\',\'two\']'; 

    var re1='(\\[)'; // Any Single Character 1 
    var re2='(\\\'.*?\\\')'; // Single Quote String 1 
    var re3='(,)'; // Any Single Character 2 
    var re4='(\\\'.*?\\\')'; // Single Quote String 2 
    var re5='(\\])'; // Any Single Character 3 

    var p = new RegExp(re1+re2+re3+re4+re5,["i"]); 
    var m = p.exec(txt); 
    if (m != null) 
    { 
     var c1=m[1]; 
     var s1=m[2]; 
     var c2=m[3]; 
     var s2=m[4]; 
     var c3=m[5]; 

     return [s1, s2]; 
    } 
    return null; 

예 그것을 할 수있는이 끔찍한 방법으로, 그러나 그것은 그 문자열을 주장하는 것을 수행 : P

+0

알다시피 ... 기술적으로 JSON 문자열 예제가 유효한 JSON이 아닙니다. :-p –

+0

나는 그에게 올바른 방향으로 밀기 만하면된다. 또한 배열이 아닌 해시를 반환했습니다. – mkoryak

9

JSON에는 well defined grammar이 있으며 트리를 구성하여 개체로 변환됩니다.

+0

하지만 어떻게 나무가 변환된다 물건에? –

+1

@Fedor - 당신이 묻는 것은 "JSON 파서가 어떻게 구현 되는가"와 같습니다 ... –

+0

@Fedor -'eval'은 어떻게 구현되고 있습니까? – orip

2

세부 사항을 모르지만 실제로 어렵지는 않습니다. 문자와 하위 문자열을 읽고, 의미를 해석하고, 데이터 배열을 구성하는 스마트 조합입니다. 다른 파서와 같습니다.

2

비밀이 없습니다. eval()이 어떻게 구현되었다고 생각하십니까? JSON 데이터를 구문 분석해야하는 경우와 동일한 기술을 사용합니다. 즉, eval()의 일부를 효과적으로 다시 구현합니다.

0

JSON은 네이티브 데이터 표현입니다. 이것은 JavaScript의 내장 객체 형식을 단순히 창의적으로 구현 한 것입니다. 네이티브 (native)이기 때문에, 프로그래머가 그것을 염려 할 필요가 있다는 의미에서 "파싱"할 필요가 전혀 없습니다.

+0

eval()은 JSON에 적합한 파서입니다. 그건 사실이지만, 그건 OP에 관한 것이 아닙니다. –

+0

나는 결코 그렇게 말하지 않았다. –

3

더글러스 크록 포드 (Douglas Crockford)의 저서 자바 스크립트 : 좋은 부품. 부록 E에는 JSON 구문 분석기를 구현하는 코드가 포함되어 있습니다. 그것은 eval을 사용하지 않습니다.

2

제 파서를 잘 살펴보십시오. 완벽하지는 않지만 코드는 따라하기 쉽습니다.

public static JsonStructure Parse(string jsonText) 
{ 
    var result = default(JsonStructure); 
    var structureStack = new Stack<JsonStructure>(); 
    var keyStack = new Stack<string>(); 
    var current = default(JsonStructure); 
    var currentState = ParserState.Begin; 
    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.BeginObject: 
         currentState = ParserState.Name; 
         current = result = new JsonObject(); 
         break; 
        case TokenType.BeginArray: 
         currentState = ParserState.Value; 
         current = result = new JsonArray(); 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.Name: 
       switch (token.Type) 
       { 
        case TokenType.String: 
         currentState = ParserState.NameSeparator; 
         key = (string)token.Value; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.NameSeparator: 
       switch (token.Type) 
       { 
        case TokenType.NameSeparator: 
         currentState = ParserState.Value; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.Value: 
       switch (token.Type) 
       { 
        case TokenType.Number: 
        case TokenType.String: 
        case TokenType.True: 
        case TokenType.False: 
        case TokenType.Null: 
         currentState = ParserState.ValueSeparator; 
         value = token.Value; 
         break; 
        case TokenType.BeginObject: 
         structureStack.Push(current); 
         keyStack.Push(key); 
         currentState = ParserState.Name; 
         current = new JsonObject(); 
         break; 
        case TokenType.BeginArray: 
         structureStack.Push(current); 
         currentState = ParserState.Value; 
         current = new JsonArray(); 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.ValueSeparator: 
       var jsonObject = (current as JsonObject); 
       var jsonArray = (current as JsonArray); 
       if (jsonObject != null) 
       { 
        jsonObject.Add(key, value); 
        currentState = ParserState.Name; 
       } 
       if (jsonArray != null) 
       { 
        jsonArray.Add(value); 
        currentState = ParserState.Value; 
       } 
       switch (token.Type) 
       { 
        case TokenType.EndObject: 
        case TokenType.EndArray: 
         currentState = ParserState.End; 
         break; 
        case TokenType.ValueSeparator: 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.End: 
       switch (token.Type) 
       { 
        case TokenType.EndObject: 
        case TokenType.EndArray: 
        case TokenType.ValueSeparator: 
         var previous = structureStack.Pop(); 
         var previousJsonObject = (previous as JsonObject); 
         var previousJsonArray = (previous as JsonArray); 
         if (previousJsonObject != null) 
         { 
          previousJsonObject.Add(keyStack.Pop(), current); 
          currentState = ParserState.Name; 
         } 
         if (previousJsonArray != null) 
         { 
          previousJsonArray.Add(current); 
          currentState = ParserState.Value; 
         } 
         if (token.Type != TokenType.ValueSeparator) 
         { 
          currentState = ParserState.End; 
         } 
         current = previous; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      default: 
       break; 
     } 
    } 
    return result; 
} 
관련 문제