123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifndef LiteralParser_h
- #define LiteralParser_h
- #include "Identifier.h"
- #include "JSCJSValue.h"
- #include "JSGlobalObjectFunctions.h"
- #include <wtf/text/WTFString.h>
- namespace JSC {
- typedef enum { StrictJSON, NonStrictJSON, JSONP } ParserMode;
- enum JSONPPathEntryType {
- JSONPPathEntryTypeDeclare, // var pathEntryName = JSON
- JSONPPathEntryTypeDot, // <prior entries>.pathEntryName = JSON
- JSONPPathEntryTypeLookup, // <prior entries>[pathIndex] = JSON
- JSONPPathEntryTypeCall // <prior entries>(JSON)
- };
- enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
- StartParseStatement, StartParseStatementEndStatement,
- DoParseObjectStartExpression, DoParseObjectEndExpression,
- DoParseArrayStartExpression, DoParseArrayEndExpression };
- enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
- TokString, TokIdentifier, TokNumber, TokColon,
- TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
- TokNull, TokEnd, TokDot, TokAssign, TokSemi, TokError };
-
- struct JSONPPathEntry {
- JSONPPathEntryType m_type;
- Identifier m_pathEntryName;
- int m_pathIndex;
- };
- struct JSONPData {
- Vector<JSONPPathEntry> m_path;
- Strong<Unknown> m_value;
- };
- template <typename CharType>
- struct LiteralParserToken {
- TokenType type;
- const CharType* start;
- const CharType* end;
- String stringBuffer;
- union {
- double numberToken;
- struct {
- union {
- const LChar* stringToken8;
- const UChar* stringToken16;
- };
- unsigned stringIs8Bit : 1;
- unsigned stringLength : 31;
- };
- };
- };
- template <typename CharType>
- ALWAYS_INLINE void setParserTokenString(LiteralParserToken<CharType>&, const CharType* string);
- template <typename CharType>
- class LiteralParser {
- public:
- LiteralParser(ExecState* exec, const CharType* characters, unsigned length, ParserMode mode)
- : m_exec(exec)
- , m_lexer(characters, length, mode)
- , m_mode(mode)
- {
- }
-
- String getErrorMessage()
- {
- if (!m_lexer.getErrorMessage().isEmpty())
- return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl();
- if (!m_parseErrorMessage.isEmpty())
- return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl();
- return ASCIILiteral("JSON Parse error: Unable to parse JSON string");
- }
-
- JSValue tryLiteralParse()
- {
- m_lexer.next();
- JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
- if (m_lexer.currentToken().type == TokSemi)
- m_lexer.next();
- if (m_lexer.currentToken().type != TokEnd)
- return JSValue();
- return result;
- }
-
- bool tryJSONPParse(Vector<JSONPData>&, bool needsFullSourceInfo);
- private:
- class Lexer {
- public:
- Lexer(const CharType* characters, unsigned length, ParserMode mode)
- : m_mode(mode)
- , m_ptr(characters)
- , m_end(characters + length)
- {
- }
-
- TokenType next();
-
- const LiteralParserToken<CharType>& currentToken()
- {
- return m_currentToken;
- }
-
- String getErrorMessage() { return m_lexErrorMessage; }
-
- private:
- String m_lexErrorMessage;
- template <ParserMode mode> TokenType lex(LiteralParserToken<CharType>&);
- ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken<CharType>&);
- template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken<CharType>&);
- ALWAYS_INLINE TokenType lexNumber(LiteralParserToken<CharType>&);
- LiteralParserToken<CharType> m_currentToken;
- ParserMode m_mode;
- const CharType* m_ptr;
- const CharType* m_end;
- };
-
- class StackGuard;
- JSValue parse(ParserState);
- ExecState* m_exec;
- typename LiteralParser<CharType>::Lexer m_lexer;
- ParserMode m_mode;
- String m_parseErrorMessage;
- static unsigned const MaximumCachableCharacter = 128;
- FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers;
- FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers;
- ALWAYS_INLINE const Identifier makeIdentifier(const LChar* characters, size_t length);
- ALWAYS_INLINE const Identifier makeIdentifier(const UChar* characters, size_t length);
- };
- }
- #endif
|