2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_COMPILER_PARSER_H_
18 #define incl_HPHP_COMPILER_PARSER_H_
20 #include "hphp/runtime/base/util/exceptions.h"
21 #include "hphp/util/parser/parser.h"
22 #include "hphp/compiler/construct.h"
23 #include "hphp/compiler/option.h"
24 #include "hphp/compiler/type_annotation.h"
25 #include "hphp/compiler/expression/scalar_expression.h"
30 #define HPHP_PARSER_NS Compiler
32 #ifdef HPHP_PARSER_ERROR
33 #undef HPHP_PARSER_ERROR
35 #define HPHP_PARSER_ERROR(fmt, p, args...) \
37 if (HPHP::Option::WholeProgram) { \
38 HPHP::Logger::Error(fmt " %s", ##args, (p)->getMessage(true).c_str()); \
40 throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), \
46 ///////////////////////////////////////////////////////////////////////////////
48 DECLARE_BOOST_TYPES(Expression
);
49 DECLARE_BOOST_TYPES(Statement
);
50 DECLARE_BOOST_TYPES(StatementList
);
51 DECLARE_BOOST_TYPES(Location
);
52 DECLARE_BOOST_TYPES(AnalysisResult
);
53 DECLARE_BOOST_TYPES(BlockScope
);
54 DECLARE_BOOST_TYPES(TypeAnnotation
);
57 ///////////////////////////////////////////////////////////////////////////////
60 class Token
: public ScannerToken
{
64 TypeAnnotationPtr typeAnnotation
;
66 Token
&operator+(const char *str
) {
70 Token
&operator+(const Token
&token
) {
72 m_text
+= token
.m_text
;
78 void operator=(int num
) {
81 void operator=(Token
&other
) {
82 ScannerToken::operator=(other
);
85 typeAnnotation
= other
.typeAnnotation
;
90 typeAnnotation
.reset();
91 ScannerToken::reset();
93 const std::string
typeAnnotationName() {
94 return (typeAnnotation
) ? typeAnnotation
->fullName() : "";
98 ///////////////////////////////////////////////////////////////////////////////
100 DECLARE_BOOST_TYPES(Parser
);
101 class Parser
: public ParserBase
{
103 static StatementListPtr
ParseString(CStrRef input
, AnalysisResultPtr ar
,
104 const char *fileName
= nullptr,
105 bool lambdaMode
= false);
108 Parser(Scanner
&scanner
, const char *fileName
,
109 AnalysisResultPtr ar
, int fileSize
= 0);
111 // implementing ParserBase
112 virtual bool parseImpl();
114 virtual void error(const char* fmt
, ...) ATTRIBUTE_PRINTF(2,3);
115 virtual bool enableXHP();
116 virtual bool enableFinallyStatement();
117 IMPLEMENT_XHP_ATTRIBUTES
;
119 virtual void fatal(Location
*loc
, const char *msg
);
120 std::string
errString();
123 StatementListPtr
getTree() const { return m_tree
;}
126 void initParseTree();
127 void finiParseTree();
128 void onHaltCompiler();
129 void onName(Token
&out
, Token
&name
, NameKind kind
);
130 void onVariable(Token
&out
, Token
*exprs
, Token
&var
, Token
*value
,
131 bool constant
= false,
132 const std::string
&docComment
= "");
133 void onStaticVariable(Token
&out
, Token
*exprs
, Token
&var
, Token
*value
);
134 void onClassVariableModifer(Token
&mod
) {}
135 void onClassVariableStart(Token
&out
, Token
*modifiers
, Token
&decl
,
137 void onClassVariable(Token
&out
, Token
*exprs
, Token
&var
, Token
*value
);
138 void onClassConstant(Token
&out
, Token
*exprs
, Token
&var
, Token
&value
);
139 void onSimpleVariable(Token
&out
, Token
&var
);
140 void onSynthesizedVariable(Token
&out
, Token
&var
) {
141 onSimpleVariable(out
, var
);
143 void onDynamicVariable(Token
&out
, Token
&expr
, bool encap
);
144 void onIndirectRef(Token
&out
, Token
&refCount
, Token
&var
);
145 void onStaticMember(Token
&out
, Token
&cls
, Token
&name
);
146 void onRefDim(Token
&out
, Token
&var
, Token
&offset
);
147 void onCallParam(Token
&out
, Token
*params
, Token
&expr
, bool ref
);
148 void onCall(Token
&out
, bool dynamic
, Token
&name
, Token
¶ms
,
149 Token
*cls
, bool fromCompiler
= false);
150 void onEncapsList(Token
&out
, int type
, Token
&list
);
151 void addEncap(Token
&out
, Token
*list
, Token
&expr
, int type
);
152 void encapRefDim(Token
&out
, Token
&var
, Token
&offset
);
153 void encapObjProp(Token
&out
, Token
&var
, Token
&name
);
154 void encapArray(Token
&out
, Token
&var
, Token
&expr
);
155 void onConstantValue(Token
&out
, Token
&constant
);
156 void onScalar(Token
&out
, int type
, Token
&scalar
);
157 void onExprListElem(Token
&out
, Token
*exprs
, Token
&expr
);
159 void onObjectProperty(Token
&out
, Token
&base
, Token
&prop
);
160 void onObjectMethodCall(Token
&out
, Token
&base
, Token
&prop
, Token
¶ms
);
162 void onListAssignment(Token
&out
, Token
&vars
, Token
*expr
,
163 bool rhsFirst
= false);
164 void onAListVar(Token
&out
, Token
*list
, Token
*var
);
165 void onAListSub(Token
&out
, Token
*list
, Token
&sublist
);
166 void onAssign(Token
&out
, Token
&var
, Token
&expr
, bool ref
,
167 bool rhsFirst
= false);
168 void onAssignNew(Token
&out
, Token
&var
, Token
&name
, Token
&args
);
169 void onNewObject(Token
&out
, Token
&name
, Token
&args
);
170 void onUnaryOpExp(Token
&out
, Token
&operand
, int op
, bool front
);
171 void onBinaryOpExp(Token
&out
, Token
&operand1
, Token
&operand2
, int op
);
172 void onQOp(Token
&out
, Token
&exprCond
, Token
*expYes
, Token
&expNo
);
173 void onArray(Token
&out
, Token
&pairs
, int op
= T_ARRAY
);
174 void onArrayPair(Token
&out
, Token
*pairs
, Token
*name
, Token
&value
,
176 void onEmptyCollection(Token
&out
);
177 void onCollectionPair(Token
&out
, Token
*pairs
, Token
*name
, Token
&value
);
178 void onUserAttribute(Token
&out
, Token
*attrList
, Token
&name
, Token
&value
);
179 void onClassConst(Token
&out
, Token
&cls
, Token
&name
, bool text
);
180 void fixStaticVars();
181 void onFunctionStart(Token
&name
, bool doPushComment
= true);
182 void onFunction(Token
&out
, Token
*modifier
, Token
&ret
, Token
&ref
,
183 Token
&name
, Token
¶ms
, Token
&stmt
, Token
*attr
);
184 void onParam(Token
&out
, Token
*params
, Token
&type
, Token
&var
,
185 bool ref
, Token
*defValue
, Token
*attr
, Token
*modifiers
);
186 void onClassStart(int type
, Token
&name
);
187 void onClass(Token
&out
, int type
, Token
&name
, Token
&base
,
188 Token
&baseInterface
, Token
&stmt
, Token
*attr
);
189 void onInterface(Token
&out
, Token
&name
, Token
&base
, Token
&stmt
,
191 void onInterfaceName(Token
&out
, Token
*names
, Token
&name
);
192 void onTraitUse(Token
&out
, Token
&traits
, Token
&rules
);
193 void onTraitName(Token
&out
, Token
*names
, Token
&name
);
194 void onTraitRule(Token
&out
, Token
&stmtList
, Token
&newStmt
);
195 void onTraitPrecRule(Token
&out
, Token
&className
, Token
&methodName
,
196 Token
&otherClasses
);
197 void onTraitAliasRuleStart(Token
&out
, Token
&className
, Token
&methodName
);
198 void onTraitAliasRuleModify(Token
&out
, Token
&rule
, Token
&accessModifiers
,
199 Token
&newMethodName
);
200 void onMethodStart(Token
&name
, Token
&mods
, bool doPushComment
= true);
201 void onMethod(Token
&out
, Token
&modifiers
, Token
&ret
, Token
&ref
,
202 Token
&name
, Token
¶ms
, Token
&stmt
, Token
*attr
,
204 void onMemberModifier(Token
&out
, Token
*modifiers
, Token
&modifier
);
205 void onStatementListStart(Token
&out
);
206 void addStatement(Token
&out
, Token
&stmts
, Token
&new_stmt
);
207 void addTopStatement(Token
&new_stmt
);
208 void onClassStatement(Token
&out
, Token
&stmts
, Token
&new_stmt
) {
209 addStatement(out
, stmts
, new_stmt
);
211 void finishStatement(Token
&out
, Token
&stmts
);
212 void onBlock(Token
&out
, Token
&stmts
);
213 void onIf(Token
&out
, Token
&cond
, Token
&stmt
, Token
&elseifs
,
215 void onElseIf(Token
&out
, Token
&elseifs
, Token
&cond
, Token
&stmt
);
216 void onWhile(Token
&out
, Token
&cond
, Token
&stmt
);
217 void onDo(Token
&out
, Token
&stmt
, Token
&cond
);
218 void onFor(Token
&out
, Token
&expr1
, Token
&expr2
, Token
&expr3
,
220 void onSwitch(Token
&out
, Token
&expr
, Token
&cases
);
221 void onCase(Token
&out
, Token
&cases
, Token
*cond
, Token
&stmt
);
222 void onBreak(Token
&out
, Token
*expr
);
223 void onContinue(Token
&out
, Token
*expr
);
224 void onReturn(Token
&out
, Token
*expr
);
225 void onYield(Token
&out
, Token
&expr
);
226 void onYieldPair(Token
&out
, Token
&key
, Token
&val
);
227 void onYieldBreak(Token
&out
);
228 void onGlobal(Token
&out
, Token
&expr
);
229 void onGlobalVar(Token
&out
, Token
*exprs
, Token
&expr
);
230 void onStatic(Token
&out
, Token
&expr
);
231 void onEcho(Token
&out
, Token
&expr
, bool html
);
232 void onUnset(Token
&out
, Token
&expr
);
233 void onExpStatement(Token
&out
, Token
&expr
);
234 void onForEachStart();
235 void onForEach(Token
&out
, Token
&arr
, Token
&name
, Token
&value
,
237 void onTry(Token
&out
, Token
&tryStmt
, Token
&className
, Token
&var
,
238 Token
&catchStmt
, Token
&catches
, Token
&finallyStmt
);
239 void onTry(Token
&out
, Token
&tryStmt
, Token
&finallyStmt
);
240 void onCatch(Token
&out
, Token
&catches
, Token
&className
, Token
&var
,
242 void onFinally(Token
&out
, Token
&stmt
);
243 void onThrow(Token
&out
, Token
&expr
);
245 void onClosureStart(Token
&name
);
246 void onClosure(Token
&out
, Token
&ret
, Token
&ref
, Token
¶ms
,
247 Token
&cparams
, Token
&stmts
, bool is_static
);
248 void onClosureParam(Token
&out
, Token
*params
, Token
¶m
, bool ref
);
249 void onLabel(Token
&out
, Token
&label
);
250 void onGoto(Token
&out
, Token
&label
, bool limited
);
251 void onTypedef(Token
& out
, const Token
& name
, const Token
& type
);
253 void onTypeAnnotation(Token
& out
, const Token
& name
, const Token
& typeArgs
);
254 void onTypeList(Token
& type1
, const Token
& type2
);
255 void onTypeSpecialization(Token
& type
, char specialization
);
257 // for namespace support
258 void onNamespaceStart(const std::string
&ns
, bool file_scope
= false);
259 void onNamespaceEnd();
260 void onUse(const std::string
&ns
, const std::string
&as
);
261 void nns(int token
= 0);
262 std::string
nsDecl(const std::string
&name
);
263 std::string
resolve(const std::string
&ns
, bool cls
);
265 virtual void invalidateGoto(TStatementPtr stmt
, GotoError error
);
266 virtual void invalidateLabel(TStatementPtr stmt
);
268 virtual TStatementPtr
extractStatement(ScannerToken
*stmt
);
270 FileScopePtr
getFileScope() { return m_file
; }
273 struct FunctionContext
{
275 : isNotGenerator(false)
279 // mark this function as generator; returns true on success
280 bool setIsGenerator() {
281 if (!isNotGenerator
) isGenerator
= true;
282 return !isNotGenerator
;
285 // mark this function as non-generator; returns true on success
286 bool setIsNotGenerator() {
287 if (!isGenerator
) isNotGenerator
= true;
291 void checkFinalAssertions() {
292 assert(!isGenerator
|| !isNotGenerator
);
295 bool isNotGenerator
; // function determined to not be a generator
296 bool isGenerator
; // function determined to be a generator
299 AnalysisResultPtr m_ar
;
301 std::vector
<std::string
> m_comments
; // for docComment stack
302 std::vector
<BlockScopePtrVec
> m_scopes
;
303 std::vector
<FunctionContext
> m_funcContexts
;
304 std::vector
<std::vector
<StatementPtr
> > m_prependingStatements
;
305 std::vector
<ScalarExpressionPtr
> m_compilerHaltOffsetVec
;
306 std::string m_clsName
; // for T_CLASS_C inside a closure
307 std::string m_funcName
;
308 std::string m_containingFuncName
;
312 StatementListPtr m_tree
;
315 std::vector
<bool> m_hasCallToGetArgs
;
316 std::vector
<StringToExpressionPtrVecMap
> m_staticVars
;
318 bool m_closureGenerator
;
321 void pushComment(const std::string
& s
);
322 std::string
popComment();
325 void completeScope(BlockScopePtr inner
);
327 bool setIsGenerator();
329 ExpressionPtr
getDynamicVariable(ExpressionPtr exp
, bool encap
);
330 ExpressionPtr
createDynamicVariable(ExpressionPtr exp
);
332 bool hasType(Token
&type
);
334 void checkAssignThis(Token
&var
);
336 void addStatement(StatementPtr stmt
, StatementPtr new_stmt
);
338 // for namespace support
339 enum NamespaceState
{
341 SeenNonNamespaceStatement
,
342 SeenNamespaceStatement
,
345 NamespaceState m_nsState
;
347 std::string m_namespace
; // current namespace
348 hphp_string_imap
<std::string
> m_aliases
;
349 void registerAlias(std::string name
);
352 ///////////////////////////////////////////////////////////////////////////////