class JSON::Ext::Parser
这是作为 C 扩展实现的 JSON
解析器。可以通过在 JSON
中使用方法 parser= 来配置使用它。
JSON.parser = JSON::Ext::Parser
用方法 parser= 在 JSON
中配置。
公共类方法
为字符串 source 创建一个新的 JSON::Ext::Parser
实例。
它将由 opts 哈希配置。opts 可以有以下键
opts 可以有以下键
-
max_nesting:解析的数据结构中允许的最大嵌套深度。使用 :max_nesting => false|nil|0 禁用深度检查,默认为 100。
-
allow_nan:如果设置为 true,则允许
Parser
解析 NaN、Infinity 和 -Infinity,这与 RFC 4627 相悖。此选项默认为 false。 -
symbolize_names:如果设置为 true,则返回
JSON
对象中名称(键)的符号。否则返回字符串,这也是默认值。此选项不能与 create_additions 选项一起使用。 -
create_additions:如果设置为 false,即使找到匹配的类和 create_id,
Parser
也不会创建添加项。此选项默认为 false。 -
object_class:默认为 Hash。如果提供了另一种类型,它将代替 Hash 用于表示
JSON
对象。该类型必须响应不带参数的new
,并返回一个响应[]=
的对象。 -
array_class:默认为 Array。如果提供了另一种类型,它将代替 Hash 用于表示
JSON
数组。该类型必须响应不带参数的new
,并返回一个响应 +<<+ 的对象。 -
decimal_class:指定使用哪个类代替默认的
(Float) when parsing decimal numbers. This class must accept a single string argument in its constructor.
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) { GET_PARSER_INIT; rb_check_arity(argc, 1, 2); parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil); return self; }
static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts) { char *p, *pe; int cs = EVIL; VALUE result = Qnil; JSON_Parser _parser = {0}; JSON_Parser *json = &_parser; parser_init(json, source, opts); char stack_buffer[FBUFFER_STACK_SIZE]; fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA]; rvalue_stack stack = { .type = RVALUE_STACK_STACK_ALLOCATED, .ptr = rvalue_stack_buffer, .capa = RVALUE_STACK_INITIAL_CAPA, }; json->stack = &stack; #line 2957 "parser.c" { cs = JSON_start; } #line 1323 "parser.rl" p = json->source; pe = p + json->len; #line 2966 "parser.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 13: goto st1; case 32: goto st1; case 34: goto tr2; case 45: goto tr2; case 47: goto st6; case 73: goto tr2; case 78: goto tr2; case 91: goto tr2; case 102: goto tr2; case 110: goto tr2; case 116: goto tr2; case 123: goto tr2; } if ( (*p) > 10 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr2; } else if ( (*p) >= 9 ) goto st1; goto st0; st0: cs = 0; goto _out; tr2: #line 1249 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 3010 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; case 47: goto st2; } if ( 9 <= (*p) && (*p) <= 10 ) goto st10; goto st0; st2: if ( ++p == pe ) goto _test_eof2; case 2: switch( (*p) ) { case 42: goto st3; case 47: goto st5; } goto st0; st3: if ( ++p == pe ) goto _test_eof3; case 3: if ( (*p) == 42 ) goto st4; goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: switch( (*p) ) { case 42: goto st4; case 47: goto st10; } goto st3; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 10 ) goto st10; goto st5; st6: if ( ++p == pe ) goto _test_eof6; case 6: switch( (*p) ) { case 42: goto st7; case 47: goto st9; } goto st0; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( (*p) == 42 ) goto st8; goto st7; st8: if ( ++p == pe ) goto _test_eof8; case 8: switch( (*p) ) { case 42: goto st8; case 47: goto st1; } goto st7; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) == 10 ) goto st1; goto st9; } _test_eof1: cs = 1; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof: {} _out: {} } #line 1326 "parser.rl" if (json->stack_handle) { rvalue_stack_eagerly_release(json->stack_handle); } if (cs >= JSON_first_final && p == pe) { return result; } else { raise_parse_error("unexpected token at '%s'", p); return Qnil; } }
公共实例方法
解析当前的 JSON
文本 source 并返回完整的数据结构作为结果。如果解析失败,则引发 JSON::ParserError
。
static VALUE cParser_parse(VALUE self) { char *p, *pe; int cs = EVIL; VALUE result = Qnil; GET_PARSER; char stack_buffer[FBUFFER_STACK_SIZE]; fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA]; rvalue_stack stack = { .type = RVALUE_STACK_STACK_ALLOCATED, .ptr = rvalue_stack_buffer, .capa = RVALUE_STACK_INITIAL_CAPA, }; json->stack = &stack; #line 2779 "parser.c" { cs = JSON_start; } #line 1285 "parser.rl" p = json->source; pe = p + json->len; #line 2788 "parser.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 13: goto st1; case 32: goto st1; case 34: goto tr2; case 45: goto tr2; case 47: goto st6; case 73: goto tr2; case 78: goto tr2; case 91: goto tr2; case 102: goto tr2; case 110: goto tr2; case 116: goto tr2; case 123: goto tr2; } if ( (*p) > 10 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr2; } else if ( (*p) >= 9 ) goto st1; goto st0; st0: cs = 0; goto _out; tr2: #line 1249 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 2832 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; case 47: goto st2; } if ( 9 <= (*p) && (*p) <= 10 ) goto st10; goto st0; st2: if ( ++p == pe ) goto _test_eof2; case 2: switch( (*p) ) { case 42: goto st3; case 47: goto st5; } goto st0; st3: if ( ++p == pe ) goto _test_eof3; case 3: if ( (*p) == 42 ) goto st4; goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: switch( (*p) ) { case 42: goto st4; case 47: goto st10; } goto st3; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 10 ) goto st10; goto st5; st6: if ( ++p == pe ) goto _test_eof6; case 6: switch( (*p) ) { case 42: goto st7; case 47: goto st9; } goto st0; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( (*p) == 42 ) goto st8; goto st7; st8: if ( ++p == pe ) goto _test_eof8; case 8: switch( (*p) ) { case 42: goto st8; case 47: goto st1; } goto st7; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) == 10 ) goto st1; goto st9; } _test_eof1: cs = 1; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof: {} _out: {} } #line 1288 "parser.rl" if (json->stack_handle) { rvalue_stack_eagerly_release(json->stack_handle); } if (cs >= JSON_first_final && p == pe) { return result; } else { raise_parse_error("unexpected token at '%s'", p); return Qnil; } }
返回用于构造此 Parser
的当前 source 字符串的副本。
static VALUE cParser_source(VALUE self) { GET_PARSER; return rb_str_dup(json->Vsource); }