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 "JSGlobalObjectFunctions.h"
36 typedef enum { StrictJSON
, NonStrictJSON
, JSONP
} ParserMode
;
38 enum JSONPPathEntryType
{
39 JSONPPathEntryTypeDeclare
, // var pathEntryName = JSON
40 JSONPPathEntryTypeDot
, // <prior entries>.pathEntryName = JSON
41 JSONPPathEntryTypeLookup
, // <prior entries>[pathIndex] = JSON
42 JSONPPathEntryTypeCall
// <prior entries>(JSON)
45 enum ParserState
{ StartParseObject
, StartParseArray
, StartParseExpression
,
46 StartParseStatement
, StartParseStatementEndStatement
,
47 DoParseObjectStartExpression
, DoParseObjectEndExpression
,
48 DoParseArrayStartExpression
, DoParseArrayEndExpression
};
49 enum TokenType
{ TokLBracket
, TokRBracket
, TokLBrace
, TokRBrace
,
50 TokString
, TokIdentifier
, TokNumber
, TokColon
,
51 TokLParen
, TokRParen
, TokComma
, TokTrue
, TokFalse
,
52 TokNull
, TokEnd
, TokDot
, TokAssign
, TokSemi
, TokError
};
54 struct JSONPPathEntry
{
55 JSONPPathEntryType m_type
;
56 Identifier m_pathEntryName
;
61 Vector
<JSONPPathEntry
> m_path
;
62 Strong
<Unknown
> m_value
;
65 template <typename CharType
>
66 struct LiteralParserToken
{
68 const CharType
* start
;
75 const LChar
* stringToken8
;
76 const UChar
* stringToken16
;
78 unsigned stringIs8Bit
: 1;
79 unsigned stringLength
: 31;
84 template <typename CharType
>
85 ALWAYS_INLINE
void setParserTokenString(LiteralParserToken
<CharType
>&, const CharType
* string
);
87 template <typename CharType
>
90 LiteralParser(ExecState
* exec
, const CharType
* characters
, unsigned length
, ParserMode mode
)
92 , m_lexer(characters
, length
, mode
)
97 UString
getErrorMessage()
99 if (!m_lexer
.getErrorMessage().isEmpty())
100 return String::format("JSON Parse error: %s", m_lexer
.getErrorMessage().ascii().data()).impl();
101 if (!m_parseErrorMessage
.isEmpty())
102 return String::format("JSON Parse error: %s", m_parseErrorMessage
.ascii().data()).impl();
103 return "JSON Parse error: Unable to parse JSON string";
106 JSValue
tryLiteralParse()
109 JSValue result
= parse(m_mode
== StrictJSON
? StartParseExpression
: StartParseStatement
);
110 if (m_lexer
.currentToken().type
== TokSemi
)
112 if (m_lexer
.currentToken().type
!= TokEnd
)
117 bool tryJSONPParse(Vector
<JSONPData
>&, bool needsFullSourceInfo
);
122 Lexer(const CharType
* characters
, unsigned length
, ParserMode mode
)
125 , m_end(characters
+ length
)
131 const LiteralParserToken
<CharType
>& currentToken()
133 return m_currentToken
;
136 UString
getErrorMessage() { return m_lexErrorMessage
; }
139 UString m_lexErrorMessage
;
140 template <ParserMode mode
> TokenType
lex(LiteralParserToken
<CharType
>&);
141 ALWAYS_INLINE TokenType
lexIdentifier(LiteralParserToken
<CharType
>&);
142 template <ParserMode mode
, char terminator
> ALWAYS_INLINE TokenType
lexString(LiteralParserToken
<CharType
>&);
143 ALWAYS_INLINE TokenType
lexNumber(LiteralParserToken
<CharType
>&);
144 LiteralParserToken
<CharType
> m_currentToken
;
146 const CharType
* m_ptr
;
147 const CharType
* m_end
;
151 JSValue
parse(ParserState
);
154 typename LiteralParser
<CharType
>::Lexer m_lexer
;
156 UString m_parseErrorMessage
;
157 static unsigned const MaximumCachableCharacter
= 128;
158 FixedArray
<Identifier
, MaximumCachableCharacter
> m_shortIdentifiers
;
159 FixedArray
<Identifier
, MaximumCachableCharacter
> m_recentIdentifiers
;
160 ALWAYS_INLINE
const Identifier
makeIdentifier(const LChar
* characters
, size_t length
);
161 ALWAYS_INLINE
const Identifier
makeIdentifier(const UChar
* characters
, size_t length
);