Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parser.cc

Issue 7039037: Create stand-alone json parser (including scanner). (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3996 matching lines...) Expand 10 before | Expand all | Expand 10 after
4007 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements, 4007 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements,
4008 TENURED); 4008 TENURED);
4009 4009
4010 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); 4010 ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
4011 args->Add(new(zone()) Literal(type)); 4011 args->Add(new(zone()) Literal(type));
4012 args->Add(new(zone()) Literal(array)); 4012 args->Add(new(zone()) Literal(array));
4013 return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args), 4013 return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args),
4014 scanner().location().beg_pos); 4014 scanner().location().beg_pos);
4015 } 4015 }
4016 4016
4017 // ----------------------------------------------------------------------------
4018 // JSON
4019
4020 Handle<Object> JsonParser::ParseJson(Handle<String> script,
4021 UC16CharacterStream* source) {
4022 scanner_.Initialize(source);
4023 stack_overflow_ = false;
4024 Handle<Object> result = ParseJsonValue();
4025 if (result.is_null() || scanner_.Next() != Token::EOS) {
4026 if (stack_overflow_) {
4027 // Scanner failed.
4028 isolate()->StackOverflow();
4029 } else {
4030 // Parse failed. Scanner's current token is the unexpected token.
4031 Token::Value token = scanner_.current_token();
4032
4033 const char* message;
4034 const char* name_opt = NULL;
4035
4036 switch (token) {
4037 case Token::EOS:
4038 message = "unexpected_eos";
4039 break;
4040 case Token::NUMBER:
4041 message = "unexpected_token_number";
4042 break;
4043 case Token::STRING:
4044 message = "unexpected_token_string";
4045 break;
4046 case Token::IDENTIFIER:
4047 case Token::FUTURE_RESERVED_WORD:
4048 message = "unexpected_token_identifier";
4049 break;
4050 default:
4051 message = "unexpected_token";
4052 name_opt = Token::String(token);
4053 ASSERT(name_opt != NULL);
4054 break;
4055 }
4056
4057 Scanner::Location source_location = scanner_.location();
4058 Factory* factory = isolate()->factory();
4059 MessageLocation location(factory->NewScript(script),
4060 source_location.beg_pos,
4061 source_location.end_pos);
4062 Handle<JSArray> array;
4063 if (name_opt == NULL) {
4064 array = factory->NewJSArray(0);
4065 } else {
4066 Handle<String> name = factory->NewStringFromUtf8(CStrVector(name_opt));
4067 Handle<FixedArray> element = factory->NewFixedArray(1);
4068 element->set(0, *name);
4069 array = factory->NewJSArrayWithElements(element);
4070 }
4071 Handle<Object> result = factory->NewSyntaxError(message, array);
4072 isolate()->Throw(*result, &location);
4073 return Handle<Object>::null();
4074 }
4075 }
4076 return result;
4077 }
4078
4079
4080 Handle<String> JsonParser::GetString() {
4081 int literal_length = scanner_.literal_length();
4082 if (literal_length == 0) {
4083 return isolate()->factory()->empty_string();
4084 }
4085 if (scanner_.is_literal_ascii()) {
4086 return isolate()->factory()->NewStringFromAscii(
4087 scanner_.literal_ascii_string());
4088 } else {
4089 return isolate()->factory()->NewStringFromTwoByte(
4090 scanner_.literal_uc16_string());
4091 }
4092 }
4093
4094
4095 Handle<String> JsonParser::GetSymbol() {
4096 int literal_length = scanner_.literal_length();
4097 if (literal_length == 0) {
4098 return isolate()->factory()->empty_string();
4099 }
4100 if (scanner_.is_literal_ascii()) {
4101 return isolate()->factory()->LookupAsciiSymbol(
4102 scanner_.literal_ascii_string());
4103 } else {
4104 return isolate()->factory()->LookupTwoByteSymbol(
4105 scanner_.literal_uc16_string());
4106 }
4107 }
4108
4109
4110 // Parse any JSON value.
4111 Handle<Object> JsonParser::ParseJsonValue() {
4112 Token::Value token = scanner_.Next();
4113 switch (token) {
4114 case Token::STRING:
4115 return GetString();
4116 case Token::NUMBER:
4117 return isolate()->factory()->NewNumber(scanner_.number());
4118 case Token::FALSE_LITERAL:
4119 return isolate()->factory()->false_value();
4120 case Token::TRUE_LITERAL:
4121 return isolate()->factory()->true_value();
4122 case Token::NULL_LITERAL:
4123 return isolate()->factory()->null_value();
4124 case Token::LBRACE:
4125 return ParseJsonObject();
4126 case Token::LBRACK:
4127 return ParseJsonArray();
4128 default:
4129 return ReportUnexpectedToken();
4130 }
4131 }
4132
4133
4134 // Parse a JSON object. Scanner must be right after '{' token.
4135 Handle<Object> JsonParser::ParseJsonObject() {
4136 Handle<JSFunction> object_constructor(
4137 isolate()->global_context()->object_function());
4138 Handle<JSObject> json_object =
4139 isolate()->factory()->NewJSObject(object_constructor);
4140 if (scanner_.peek() == Token::RBRACE) {
4141 scanner_.Next();
4142 } else {
4143 if (StackLimitCheck(isolate()).HasOverflowed()) {
4144 stack_overflow_ = true;
4145 return Handle<Object>::null();
4146 }
4147 do {
4148 if (scanner_.Next() != Token::STRING) {
4149 return ReportUnexpectedToken();
4150 }
4151 Handle<String> key = GetSymbol();
4152 if (scanner_.Next() != Token::COLON) {
4153 return ReportUnexpectedToken();
4154 }
4155 Handle<Object> value = ParseJsonValue();
4156 if (value.is_null()) return Handle<Object>::null();
4157 uint32_t index;
4158 if (key->AsArrayIndex(&index)) {
4159 SetOwnElement(json_object, index, value, kNonStrictMode);
4160 } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
4161 // We can't remove the __proto__ accessor since it's hardcoded
4162 // in several places. Instead go along and add the value as
4163 // the prototype of the created object if possible.
4164 SetPrototype(json_object, value);
4165 } else {
4166 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
4167 }
4168 } while (scanner_.Next() == Token::COMMA);
4169 if (scanner_.current_token() != Token::RBRACE) {
4170 return ReportUnexpectedToken();
4171 }
4172 }
4173 return json_object;
4174 }
4175
4176
4177 // Parse a JSON array. Scanner must be right after '[' token.
4178 Handle<Object> JsonParser::ParseJsonArray() {
4179 ZoneScope zone_scope(DELETE_ON_EXIT);
4180 ZoneList<Handle<Object> > elements(4);
4181
4182 Token::Value token = scanner_.peek();
4183 if (token == Token::RBRACK) {
4184 scanner_.Next();
4185 } else {
4186 if (StackLimitCheck(isolate()).HasOverflowed()) {
4187 stack_overflow_ = true;
4188 return Handle<Object>::null();
4189 }
4190 do {
4191 Handle<Object> element = ParseJsonValue();
4192 if (element.is_null()) return Handle<Object>::null();
4193 elements.Add(element);
4194 token = scanner_.Next();
4195 } while (token == Token::COMMA);
4196 if (token != Token::RBRACK) {
4197 return ReportUnexpectedToken();
4198 }
4199 }
4200
4201 // Allocate a fixed array with all the elements.
4202 Handle<FixedArray> fast_elements =
4203 isolate()->factory()->NewFixedArray(elements.length());
4204
4205 for (int i = 0, n = elements.length(); i < n; i++) {
4206 fast_elements->set(i, *elements[i]);
4207 }
4208
4209 return isolate()->factory()->NewJSArrayWithElements(fast_elements);
4210 }
4211 4017
4212 // ---------------------------------------------------------------------------- 4018 // ----------------------------------------------------------------------------
4213 // Regular expressions 4019 // Regular expressions
4214 4020
4215 4021
4216 RegExpParser::RegExpParser(FlatStringReader* in, 4022 RegExpParser::RegExpParser(FlatStringReader* in,
4217 Handle<String>* error, 4023 Handle<String>* error,
4218 bool multiline) 4024 bool multiline)
4219 : isolate_(Isolate::Current()), 4025 : isolate_(Isolate::Current()),
4220 error_(error), 4026 error_(error),
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
5178 info->is_global(), 4984 info->is_global(),
5179 info->StrictMode()); 4985 info->StrictMode());
5180 } 4986 }
5181 } 4987 }
5182 4988
5183 info->SetFunction(result); 4989 info->SetFunction(result);
5184 return (result != NULL); 4990 return (result != NULL);
5185 } 4991 }
5186 4992
5187 } } // namespace v8::internal 4993 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698