2 * Copyright (C) 2010, 2013 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef SyntaxChecker_h
27 #define SyntaxChecker_h
30 #include "YarrSyntaxChecker.h"
36 struct BinaryExprContext
{
37 BinaryExprContext(SyntaxChecker
& context
)
40 m_context
->m_topBinaryExprs
.append(m_context
->m_topBinaryExpr
);
41 m_context
->m_topBinaryExpr
= 0;
45 m_context
->m_topBinaryExpr
= m_context
->m_topBinaryExprs
.last();
46 m_context
->m_topBinaryExprs
.removeLast();
49 SyntaxChecker
* m_context
;
51 struct UnaryExprContext
{
52 UnaryExprContext(SyntaxChecker
& context
)
55 m_context
->m_topUnaryTokens
.append(m_context
->m_topUnaryToken
);
56 m_context
->m_topUnaryToken
= 0;
60 m_context
->m_topUnaryToken
= m_context
->m_topUnaryTokens
.last();
61 m_context
->m_topUnaryTokens
.removeLast();
64 SyntaxChecker
* m_context
;
67 SyntaxChecker(VM
* , void*)
71 typedef SyntaxChecker FunctionBodyBuilder
;
73 ResolveEvalExpr
, ResolveExpr
, NumberExpr
, StringExpr
,
74 ThisExpr
, NullExpr
, BoolExpr
, RegExpExpr
, ObjectLiteralExpr
,
75 FunctionExpr
, BracketExpr
, DotExpr
, CallExpr
,
76 NewExpr
, PreExpr
, PostExpr
, UnaryExpr
, BinaryExpr
,
77 ConditionalExpr
, AssignmentExpr
, TypeofExpr
,
78 DeleteExpr
, ArrayLiteralExpr
, BindingDeconstruction
,
79 ArrayDeconstruction
, ObjectDeconstruction
, SourceElementsResult
,
80 FunctionBodyResult
, SpreadExpr
, ArgumentsResult
,
81 PropertyListResult
, ArgumentsListResult
, ElementsListResult
,
82 StatementResult
, FormalParameterListResult
, ClauseResult
,
83 ClauseListResult
, CommaExpr
, DeconstructingAssignment
85 typedef int ExpressionType
;
87 typedef ExpressionType Expression
;
88 typedef int SourceElements
;
89 typedef int Arguments
;
90 typedef ExpressionType Comma
;
92 ALWAYS_INLINE
Property(void* = 0)
93 : type((PropertyNode::Type
)0)
96 ALWAYS_INLINE
Property(const Identifier
* ident
, PropertyNode::Type ty
)
101 ALWAYS_INLINE
Property(PropertyNode::Type ty
)
106 ALWAYS_INLINE
bool operator!() { return !type
; }
107 const Identifier
* name
;
108 PropertyNode::Type type
;
110 typedef int PropertyList
;
111 typedef int ElementList
;
112 typedef int ArgumentsList
;
113 typedef int FormalParameterList
;
114 typedef int FunctionBody
;
115 typedef int Statement
;
116 typedef int ClauseList
;
118 typedef int ConstDeclList
;
119 typedef int BinaryOperand
;
120 typedef int DeconstructionPattern
;
121 typedef DeconstructionPattern ArrayPattern
;
122 typedef DeconstructionPattern ObjectPattern
;
124 static const bool CreatesAST
= false;
125 static const bool NeedsFreeVariableInfo
= false;
126 static const bool CanUseFunctionCache
= true;
127 static const unsigned DontBuildKeywords
= LexexFlagsDontBuildKeywords
;
128 static const unsigned DontBuildStrings
= LexerFlagsDontBuildStrings
;
130 int createSourceElements() { return SourceElementsResult
; }
131 ExpressionType
makeFunctionCallNode(const JSTokenLocation
&, int, int, int, int, int) { return CallExpr
; }
132 void appendToComma(ExpressionType
& base
, ExpressionType right
) { base
= right
; }
133 ExpressionType
createCommaExpr(const JSTokenLocation
&, ExpressionType
, ExpressionType right
) { return right
; }
134 ExpressionType
makeAssignNode(const JSTokenLocation
&, ExpressionType
, Operator
, ExpressionType
, bool, bool, int, int, int) { return AssignmentExpr
; }
135 ExpressionType
makePrefixNode(const JSTokenLocation
&, ExpressionType
, Operator
, int, int, int) { return PreExpr
; }
136 ExpressionType
makePostfixNode(const JSTokenLocation
&, ExpressionType
, Operator
, int, int, int) { return PostExpr
; }
137 ExpressionType
makeTypeOfNode(const JSTokenLocation
&, ExpressionType
) { return TypeofExpr
; }
138 ExpressionType
makeDeleteNode(const JSTokenLocation
&, ExpressionType
, int, int, int) { return DeleteExpr
; }
139 ExpressionType
makeNegateNode(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
140 ExpressionType
makeBitwiseNotNode(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
141 ExpressionType
createLogicalNot(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
142 ExpressionType
createUnaryPlus(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
143 ExpressionType
createVoid(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
144 ExpressionType
thisExpr(const JSTokenLocation
&) { return ThisExpr
; }
145 ExpressionType
createResolve(const JSTokenLocation
&, const Identifier
*, int) { return ResolveExpr
; }
146 ExpressionType
createObjectLiteral(const JSTokenLocation
&) { return ObjectLiteralExpr
; }
147 ExpressionType
createObjectLiteral(const JSTokenLocation
&, int) { return ObjectLiteralExpr
; }
148 ExpressionType
createArray(const JSTokenLocation
&, int) { return ArrayLiteralExpr
; }
149 ExpressionType
createArray(const JSTokenLocation
&, int, int) { return ArrayLiteralExpr
; }
150 ExpressionType
createNumberExpr(const JSTokenLocation
&, double) { return NumberExpr
; }
151 ExpressionType
createString(const JSTokenLocation
&, const Identifier
*) { return StringExpr
; }
152 ExpressionType
createBoolean(const JSTokenLocation
&, bool) { return BoolExpr
; }
153 ExpressionType
createNull(const JSTokenLocation
&) { return NullExpr
; }
154 ExpressionType
createBracketAccess(const JSTokenLocation
&, ExpressionType
, ExpressionType
, bool, int, int, int) { return BracketExpr
; }
155 ExpressionType
createDotAccess(const JSTokenLocation
&, ExpressionType
, const Identifier
*, int, int, int) { return DotExpr
; }
156 ExpressionType
createRegExp(const JSTokenLocation
&, const Identifier
& pattern
, const Identifier
&, int) { return Yarr::checkSyntax(pattern
.string()) ? 0 : RegExpExpr
; }
157 ExpressionType
createNewExpr(const JSTokenLocation
&, ExpressionType
, int, int, int, int) { return NewExpr
; }
158 ExpressionType
createNewExpr(const JSTokenLocation
&, ExpressionType
, int, int) { return NewExpr
; }
159 ExpressionType
createConditionalExpr(const JSTokenLocation
&, ExpressionType
, ExpressionType
, ExpressionType
) { return ConditionalExpr
; }
160 ExpressionType
createAssignResolve(const JSTokenLocation
&, const Identifier
&, ExpressionType
, int, int, int) { return AssignmentExpr
; }
161 ExpressionType
createFunctionExpr(const JSTokenLocation
&, const Identifier
*, int, int, int, int, int, int, int) { return FunctionExpr
; }
162 int createFunctionBody(const JSTokenLocation
&, const JSTokenLocation
&, int, int, bool) { return FunctionBodyResult
; }
163 void setFunctionNameStart(int, int) { }
164 int createArguments() { return ArgumentsResult
; }
165 int createArguments(int) { return ArgumentsResult
; }
166 ExpressionType
createSpreadExpression(const JSTokenLocation
&, ExpressionType
, int, int, int) { return SpreadExpr
; }
167 int createArgumentsList(const JSTokenLocation
&, int) { return ArgumentsListResult
; }
168 int createArgumentsList(const JSTokenLocation
&, int, int) { return ArgumentsListResult
; }
169 Property
createProperty(const Identifier
* name
, int, PropertyNode::Type type
, bool complete
)
172 return Property(type
);
174 return Property(name
, type
);
176 Property
createProperty(VM
* vm
, double name
, int, PropertyNode::Type type
, bool complete
)
179 return Property(type
);
180 return Property(&vm
->parserArena
->identifierArena().makeNumericIdentifier(vm
, name
), type
);
182 Property
createProperty(VM
*, ExpressionNode
*, int, PropertyNode::Type type
, bool)
184 return Property(type
);
186 int createPropertyList(const JSTokenLocation
&, Property
) { return PropertyListResult
; }
187 int createPropertyList(const JSTokenLocation
&, Property
, int) { return PropertyListResult
; }
188 int createElementList(int, int) { return ElementsListResult
; }
189 int createElementList(int, int, int) { return ElementsListResult
; }
190 int createFormalParameterList(DeconstructionPattern
) { return FormalParameterListResult
; }
191 int createFormalParameterList(int, DeconstructionPattern
) { return FormalParameterListResult
; }
192 int createClause(int, int) { return ClauseResult
; }
193 int createClauseList(int) { return ClauseListResult
; }
194 int createClauseList(int, int) { return ClauseListResult
; }
195 void setUsesArguments(int) { }
196 int createFuncDeclStatement(const JSTokenLocation
&, const Identifier
*, int, int, int, int, int, int, int) { return StatementResult
; }
197 int createBlockStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
198 int createExprStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
199 int createIfStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
200 int createIfStatement(const JSTokenLocation
&, int, int, int, int, int) { return StatementResult
; }
201 int createForLoop(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
202 int createForInLoop(const JSTokenLocation
&, int, int, int, int, int, int, int, int) { return StatementResult
; }
203 int createForOfLoop(const JSTokenLocation
&, int, int, int, int, int, int, int, int) { return StatementResult
; }
204 int createEmptyStatement(const JSTokenLocation
&) { return StatementResult
; }
205 int createVarStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
206 int createReturnStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
207 int createBreakStatement(const JSTokenLocation
&, int, int) { return StatementResult
; }
208 int createBreakStatement(const JSTokenLocation
&, const Identifier
*, int, int) { return StatementResult
; }
209 int createContinueStatement(const JSTokenLocation
&, int, int) { return StatementResult
; }
210 int createContinueStatement(const JSTokenLocation
&, const Identifier
*, int, int) { return StatementResult
; }
211 int createTryStatement(const JSTokenLocation
&, int, const Identifier
*, int, int, int, int) { return StatementResult
; }
212 int createSwitchStatement(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
213 int createWhileStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
214 int createWithStatement(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
215 int createDoWhileStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
216 int createLabelStatement(const JSTokenLocation
&, const Identifier
*, int, int, int) { return StatementResult
; }
217 int createThrowStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
218 int createDebugger(const JSTokenLocation
&, int, int) { return StatementResult
; }
219 int createConstStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
220 int appendConstDecl(const JSTokenLocation
&, int, const Identifier
*, int) { return StatementResult
; }
221 Property
createGetterOrSetterProperty(const JSTokenLocation
&, PropertyNode::Type type
, bool strict
, const Identifier
* name
, int, int, int, int, int, int, int)
225 return Property(type
);
226 return Property(name
, type
);
228 Property
createGetterOrSetterProperty(VM
* vm
, const JSTokenLocation
&, PropertyNode::Type type
, bool strict
, double name
, int, int, int, int, int, int, int)
231 return Property(type
);
232 return Property(&vm
->parserArena
->identifierArena().makeNumericIdentifier(vm
, name
), type
);
235 void appendStatement(int, int) { }
236 void addVar(const Identifier
*, bool) { }
237 int combineCommaNodes(const JSTokenLocation
&, int, int) { return CommaExpr
; }
238 int evalCount() const { return 0; }
239 void appendBinaryExpressionInfo(int& operandStackDepth
, int expr
, int, int, int, bool)
241 if (!m_topBinaryExpr
)
242 m_topBinaryExpr
= expr
;
244 m_topBinaryExpr
= BinaryExpr
;
248 // Logic to handle datastructures used during parsing of binary expressions
249 void operatorStackPop(int& operatorStackDepth
) { operatorStackDepth
--; }
250 bool operatorStackHasHigherPrecedence(int&, int) { return true; }
251 BinaryOperand
getFromOperandStack(int) { return m_topBinaryExpr
; }
252 void shrinkOperandStackBy(int& operandStackDepth
, int amount
) { operandStackDepth
-= amount
; }
253 void appendBinaryOperation(const JSTokenLocation
&, int& operandStackDepth
, int&, BinaryOperand
, BinaryOperand
) { operandStackDepth
++; }
254 void operatorStackAppend(int& operatorStackDepth
, int, int) { operatorStackDepth
++; }
255 int popOperandStack(int&) { int res
= m_topBinaryExpr
; m_topBinaryExpr
= 0; return res
; }
257 void appendUnaryToken(int& stackDepth
, int tok
, int) { stackDepth
= 1; m_topUnaryToken
= tok
; }
258 int unaryTokenStackLastType(int&) { return m_topUnaryToken
; }
259 JSTextPosition
unaryTokenStackLastStart(int&) { return JSTextPosition(0, 0, 0); }
260 void unaryTokenStackRemoveLast(int& stackDepth
) { stackDepth
= 0; }
262 void assignmentStackAppend(int, int, int, int, int, Operator
) { }
263 int createAssignment(const JSTokenLocation
&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return AssignmentExpr
; }
264 const Identifier
* getName(const Property
& property
) const { ASSERT(property
.name
); return property
.name
; }
265 PropertyNode::Type
getType(const Property
& property
) const { return property
.type
; }
266 bool isResolve(ExpressionType expr
) const { return expr
== ResolveExpr
|| expr
== ResolveEvalExpr
; }
267 ExpressionType
createDeconstructingAssignment(const JSTokenLocation
&, int, ExpressionType
)
269 return DeconstructingAssignment
;
272 ArrayPattern
createArrayPattern(const JSTokenLocation
&)
274 return ArrayDeconstruction
;
276 void appendArrayPatternSkipEntry(ArrayPattern
, const JSTokenLocation
&)
279 void appendArrayPatternEntry(ArrayPattern
, const JSTokenLocation
&, DeconstructionPattern
)
282 ObjectPattern
createObjectPattern(const JSTokenLocation
&)
284 return ObjectDeconstruction
;
286 void appendObjectPatternEntry(ArrayPattern
, const JSTokenLocation
&, bool, const Identifier
&, DeconstructionPattern
)
289 DeconstructionPattern
createBindingLocation(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
&, const JSTextPosition
&)
291 return BindingDeconstruction
;
294 bool isBindingNode(DeconstructionPattern pattern
)
296 return pattern
== BindingDeconstruction
;
302 Vector
<int, 8> m_topBinaryExprs
;
303 Vector
<int, 8> m_topUnaryTokens
;