Javascript 有人能解释一下JSON解析器在不使用eval的情况下是如何工作的吗?
如果不使用eval,我无法理解它是如何工作的-这背后的秘密是什么Javascript 有人能解释一下JSON解析器在不使用eval的情况下是如何工作的吗?,javascript,json,parsing,Javascript,Json,Parsing,如果不使用eval,我无法理解它是如何工作的-这背后的秘密是什么 编辑:有人能举一个简单的例子说明如何将树结构转换为对象吗?JSON有一个用于构建树,然后将树转换为对象。我不知道具体细节,但这并不难。这只是一个聪明的组合,读取字符和子字符串,解释它们的意思,并在执行时构建一个数据数组。与任何其他解析器一样。没有秘密。您认为eval()是如何实现的?它使用的技术与解析JSON数据时必须使用的技术相同,即有效地重新实现eval()的一部分。JSON是数据的一种本机表示。它只是JavaScript内置
编辑:有人能举一个简单的例子说明如何将树结构转换为对象吗?JSON有一个用于构建树,然后将树转换为对象。我不知道具体细节,但这并不难。这只是一个聪明的组合,读取字符和子字符串,解释它们的意思,并在执行时构建一个数据数组。与任何其他解析器一样。没有秘密。您认为eval()是如何实现的?它使用的技术与解析JSON数据时必须使用的技术相同,即有效地重新实现eval()的一部分。JSON是数据的一种本机表示。它只是JavaScript内置对象格式的创造性实现。作为本地语言,它根本不需要被“解析”(程序员需要担心这样做)。获取道格拉斯·克罗克福德的书《Javascript:好的部分》。附录E包括实现JSON解析器的代码。它不使用eval。如何将带有json的字符串转换为不带eval的对象的简单示例:
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请查看我的解析器以获得一个好主意。它并不完美,但代码很容易理解
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;
}
publicstaticjsonstructure解析(字符串jsonText)
{
var结果=默认值(JsonStructure);
var structureStack=新堆栈();
var keyStack=新堆栈();
var电流=默认值(JsonStructure);
var currentState=ParserState.Begin;
var key=默认值(字符串);
var值=默认值(对象);
foreach(Lexer.Tokenize(jsonText)中的var标记)
{
开关(当前状态)
{
案例解析器状态。开始:
开关(token.Type)
{
案例TokenType.BeginObject:
currentState=ParserState.Name;
当前=结果=新JsonObject();
打破
case TokenType.BeginArray:
currentState=ParserState.Value;
当前=结果=新JsonArray();
打破
违约:
抛出新的JsonException(令牌、当前状态);
}
打破
case ParserState。名称:
开关(token.Type)
{
大小写标记类型。字符串:
currentState=ParserState.NameSeparator;
key=(字符串)token.Value;
打破
违约:
抛出新的JsonException(令牌、当前状态);
}
打破
case ParserState.NameSeparator:
开关(token.Type)
{
案例TokenType.NameSeparator:
currentState=ParserState.Value;
打破
违约:
抛出新的JsonException(令牌、当前状态);
}
打破
case ParserState.Value:
开关(token.Type)
{
案例类型。编号:
大小写标记类型。字符串:
大小写标记类型。True:
大小写标记类型。错误:
大小写标记类型。空:
currentState=ParserState.ValueSeparator;
value=token.value;
打破
案例TokenType.BeginObject:
structureStack.Push(当前);
击键(键);
currentState=ParserState.Name;
当前=新的JsonObject();
打破
case TokenType.BeginArray:
structureStack.Push(当前);
currentState=ParserState.Value;
当前=新的JsonArray();
打破
违约:
抛出新的JsonException(令牌、当前状态);
}
打破
case ParserState.ValueSeparator:
var jsonObject=(当前为jsonObject);
var jsonArray=(当前为jsonArray);
if(jsonObject!=null)
{
jsonObject.Add(键,值);
currentState=ParserState.Name;
}
if(jsonArray!=null)
{
jsonArray.Add(value);
currentState=ParserState.Value;
}
开关(token.Type)
{
大小写标记类型.EndObject:
大小写TokenType.EndArray:
currentState=ParserState.End;
打破
大小写TokenType.ValueSeparator:
打破
违约:
抛出新的JsonException(令牌、当前状态);
}
打破
case ParserState.End:
开关(token.Type)
{
大小写标记类型.EndObject:
大小写TokenType.EndArray:
大小写TokenType.ValueSeparator:
var previous=structureStack.Pop();
var previousJsonObject=(之前作为JsonObject);
var previousJsonArray=(先前为JsonArray);
if(previousJsonObject!=null)
{
添加(keyStack.Pop(),当前);