2 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef LiteralParser_h
27 #define LiteralParser_h
29 #include "Identifier.h"
30 #include "JSCJSValue.h"
31 #include "JSGlobalObjectFunctions.h"
33 #include <wtf/text/WTFString.h>
37 typedef enum { StrictJSON
, NonStrictJSON
, JSONP
} ParserMode
;
39 enum JSONPPathEntryType
{
40 JSONPPathEntryTypeDeclare
, // var pathEntryName = JSON
41 JSONPPathEntryTypeDot
, // <prior entries>.pathEntryName = JSON
42 JSONPPathEntryTypeLookup
, // <prior entries>[pathIndex] = JSON
43 JSONPPathEntryTypeCall
// <prior entries>(JSON)
46 enum ParserState
{ StartParseObject
, StartParseArray
, StartParseExpression
,
47 StartParseStatement
, StartParseStatementEndStatement
,
48 DoParseObjectStartExpression
, DoParseObjectEndExpression
,
49 DoParseArrayStartExpression
, DoParseArrayEndExpression
};
50 enum TokenType
{ TokLBracket
, TokRBracket
, TokLBrace
, TokRBrace
,
51 TokString
, TokIdentifier
, TokNumber
, TokColon
,
52 TokLParen
, TokRParen
, TokComma
, TokTrue
, TokFalse
,
53 TokNull
, TokEnd
, TokDot
, TokAssign
, TokSemi
, TokError
};
55 struct JSONPPathEntry
{
56 JSONPPathEntryType m_type
;
57 Identifier m_pathEntryName
;
62 Vector
<JSONPPathEntry
> m_path
;
63 Strong
<Unknown
> m_value
;
66 template <typename CharType
>
67 struct LiteralParserToken
{
69 const CharType
* start
;
76 const LChar
* stringToken8
;
77 const UChar
* stringToken16
;
79 unsigned stringIs8Bit
: 1;
80 unsigned stringLength
: 31;
85 template <typename CharType
>
86 ALWAYS_INLINE
void setParserTokenString(LiteralParserToken
<CharType
>&, const CharType
* string
);
88 template <typename CharType
>
91 LiteralParser(ExecState
* exec
, const CharType
* characters
, unsigned length
, ParserMode mode
)
93 , m_lexer(characters
, length
, mode
)
98 String
getErrorMessage()
100 if (!m_lexer
.getErrorMessage().isEmpty())
101 return String::format("JSON Parse error: %s", m_lexer
.getErrorMessage().ascii().data());
102 if (!m_parseErrorMessage
.isEmpty())
103 return String::format("JSON Parse error: %s", m_parseErrorMessage
.ascii().data());
104 return ASCIILiteral("JSON Parse error: Unable to parse JSON string");
107 JSValue
tryLiteralParse()
110 JSValue result
= parse(m_mode
== StrictJSON
? StartParseExpression
: StartParseStatement
);
111 if (m_lexer
.currentToken().type
== TokSemi
)
113 if (m_lexer
.currentToken().type
!= TokEnd
)
118 bool tryJSONPParse(Vector
<JSONPData
>&, bool needsFullSourceInfo
);
123 Lexer(const CharType
* characters
, unsigned length
, ParserMode mode
)
126 , m_end(characters
+ length
)
132 const LiteralParserToken
<CharType
>& currentToken()
134 return m_currentToken
;
137 String
getErrorMessage() { return m_lexErrorMessage
; }
140 String m_lexErrorMessage
;
141 template <ParserMode mode
> TokenType
lex(LiteralParserToken
<CharType
>&);
142 ALWAYS_INLINE TokenType
lexIdentifier(LiteralParserToken
<CharType
>&);
143 template <ParserMode mode
, char terminator
> ALWAYS_INLINE TokenType
lexString(LiteralParserToken
<CharType
>&);
144 ALWAYS_INLINE TokenType
lexNumber(LiteralParserToken
<CharType
>&);
145 LiteralParserToken
<CharType
> m_currentToken
;
147 const CharType
* m_ptr
;
148 const CharType
* m_end
;
152 JSValue
parse(ParserState
);
155 typename LiteralParser
<CharType
>::Lexer m_lexer
;
157 String m_parseErrorMessage
;
158 static unsigned const MaximumCachableCharacter
= 128;
159 std::array
<Identifier
, MaximumCachableCharacter
> m_shortIdentifiers
;
160 std::array
<Identifier
, MaximumCachableCharacter
> m_recentIdentifiers
;
161 ALWAYS_INLINE
const Identifier
makeIdentifier(const LChar
* characters
, size_t length
);
162 ALWAYS_INLINE
const Identifier
makeIdentifier(const UChar
* characters
, size_t length
);