zend_language_parser.y 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705
  1. %require "3.0"
  2. /*
  3. +----------------------------------------------------------------------+
  4. | Zend Engine |
  5. +----------------------------------------------------------------------+
  6. | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
  7. +----------------------------------------------------------------------+
  8. | This source file is subject to version 2.00 of the Zend license, |
  9. | that is bundled with this package in the file LICENSE, and is |
  10. | available through the world-wide-web at the following url: |
  11. | http://www.zend.com/license/2_00.txt. |
  12. | If you did not receive a copy of the Zend license and are unable to |
  13. | obtain it through the world-wide-web, please send a note to |
  14. | license@zend.com so we can mail you a copy immediately. |
  15. +----------------------------------------------------------------------+
  16. | Authors: Andi Gutmans <andi@php.net> |
  17. | Zeev Suraski <zeev@php.net> |
  18. | Nikita Popov <nikic@php.net> |
  19. +----------------------------------------------------------------------+
  20. */
  21. %code top {
  22. #include "zend.h"
  23. #include "zend_list.h"
  24. #include "zend_globals.h"
  25. #include "zend_API.h"
  26. #include "zend_constants.h"
  27. #include "zend_language_scanner.h"
  28. #include "zend_exceptions.h"
  29. #define YYSIZE_T size_t
  30. #define yytnamerr zend_yytnamerr
  31. static YYSIZE_T zend_yytnamerr(char*, const char*);
  32. #ifdef _MSC_VER
  33. #define YYMALLOC malloc
  34. #define YYFREE free
  35. #endif
  36. }
  37. %code requires {
  38. #include "zend_compile.h"
  39. }
  40. %define api.prefix {zend}
  41. %define api.pure full
  42. %define api.value.type {zend_parser_stack_elem}
  43. %define parse.error verbose
  44. %expect 0
  45. %destructor { zend_ast_destroy($$); } <ast>
  46. %destructor { if ($$) zend_string_release_ex($$, 0); } <str>
  47. %precedence T_THROW
  48. %precedence PREC_ARROW_FUNCTION
  49. %precedence T_INCLUDE T_INCLUDE_ONCE T_REQUIRE T_REQUIRE_ONCE
  50. %left T_LOGICAL_OR
  51. %left T_LOGICAL_XOR
  52. %left T_LOGICAL_AND
  53. %precedence T_PRINT
  54. %precedence T_YIELD
  55. %precedence T_DOUBLE_ARROW
  56. %precedence T_YIELD_FROM
  57. %precedence '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL
  58. %left '?' ':'
  59. %right T_COALESCE
  60. %left T_BOOLEAN_OR
  61. %left T_BOOLEAN_AND
  62. %left '|'
  63. %left '^'
  64. %left T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
  65. %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
  66. %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
  67. %left '.'
  68. %left T_SL T_SR
  69. %left '+' '-'
  70. %left '*' '/' '%'
  71. %precedence '!'
  72. %precedence T_INSTANCEOF
  73. %precedence '~' T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
  74. %right T_POW
  75. %precedence T_CLONE
  76. /* Resolve danging else conflict */
  77. %precedence T_NOELSE
  78. %precedence T_ELSEIF
  79. %precedence T_ELSE
  80. %token <ast> T_LNUMBER "integer"
  81. %token <ast> T_DNUMBER "floating-point number"
  82. %token <ast> T_STRING "identifier"
  83. %token <ast> T_NAME_FULLY_QUALIFIED "fully qualified name"
  84. %token <ast> T_NAME_RELATIVE "namespace-relative name"
  85. %token <ast> T_NAME_QUALIFIED "namespaced name"
  86. %token <ast> T_VARIABLE "variable"
  87. %token <ast> T_INLINE_HTML
  88. %token <ast> T_ENCAPSED_AND_WHITESPACE "string content"
  89. %token <ast> T_CONSTANT_ENCAPSED_STRING "quoted string"
  90. %token <ast> T_STRING_VARNAME "variable name"
  91. %token <ast> T_NUM_STRING "number"
  92. %token <ident> T_INCLUDE "'include'"
  93. %token <ident> T_INCLUDE_ONCE "'include_once'"
  94. %token <ident> T_EVAL "'eval'"
  95. %token <ident> T_REQUIRE "'require'"
  96. %token <ident> T_REQUIRE_ONCE "'require_once'"
  97. %token <ident> T_LOGICAL_OR "'or'"
  98. %token <ident> T_LOGICAL_XOR "'xor'"
  99. %token <ident> T_LOGICAL_AND "'and'"
  100. %token <ident> T_PRINT "'print'"
  101. %token <ident> T_YIELD "'yield'"
  102. %token <ident> T_YIELD_FROM "'yield from'"
  103. %token <ident> T_INSTANCEOF "'instanceof'"
  104. %token <ident> T_NEW "'new'"
  105. %token <ident> T_CLONE "'clone'"
  106. %token <ident> T_EXIT "'exit'"
  107. %token <ident> T_IF "'if'"
  108. %token <ident> T_ELSEIF "'elseif'"
  109. %token <ident> T_ELSE "'else'"
  110. %token <ident> T_ENDIF "'endif'"
  111. %token <ident> T_ECHO "'echo'"
  112. %token <ident> T_DO "'do'"
  113. %token <ident> T_WHILE "'while'"
  114. %token <ident> T_ENDWHILE "'endwhile'"
  115. %token <ident> T_FOR "'for'"
  116. %token <ident> T_ENDFOR "'endfor'"
  117. %token <ident> T_FOREACH "'foreach'"
  118. %token <ident> T_ENDFOREACH "'endforeach'"
  119. %token <ident> T_DECLARE "'declare'"
  120. %token <ident> T_ENDDECLARE "'enddeclare'"
  121. %token <ident> T_AS "'as'"
  122. %token <ident> T_SWITCH "'switch'"
  123. %token <ident> T_ENDSWITCH "'endswitch'"
  124. %token <ident> T_CASE "'case'"
  125. %token <ident> T_DEFAULT "'default'"
  126. %token <ident> T_MATCH "'match'"
  127. %token <ident> T_BREAK "'break'"
  128. %token <ident> T_CONTINUE "'continue'"
  129. %token <ident> T_GOTO "'goto'"
  130. %token <ident> T_FUNCTION "'function'"
  131. %token <ident> T_FN "'fn'"
  132. %token <ident> T_CONST "'const'"
  133. %token <ident> T_RETURN "'return'"
  134. %token <ident> T_TRY "'try'"
  135. %token <ident> T_CATCH "'catch'"
  136. %token <ident> T_FINALLY "'finally'"
  137. %token <ident> T_THROW "'throw'"
  138. %token <ident> T_USE "'use'"
  139. %token <ident> T_INSTEADOF "'insteadof'"
  140. %token <ident> T_GLOBAL "'global'"
  141. %token <ident> T_STATIC "'static'"
  142. %token <ident> T_ABSTRACT "'abstract'"
  143. %token <ident> T_FINAL "'final'"
  144. %token <ident> T_PRIVATE "'private'"
  145. %token <ident> T_PROTECTED "'protected'"
  146. %token <ident> T_PUBLIC "'public'"
  147. %token <ident> T_READONLY "'readonly'"
  148. %token <ident> T_VAR "'var'"
  149. %token <ident> T_UNSET "'unset'"
  150. %token <ident> T_ISSET "'isset'"
  151. %token <ident> T_EMPTY "'empty'"
  152. %token <ident> T_HALT_COMPILER "'__halt_compiler'"
  153. %token <ident> T_CLASS "'class'"
  154. %token <ident> T_TRAIT "'trait'"
  155. %token <ident> T_INTERFACE "'interface'"
  156. %token <ident> T_ENUM "'enum'"
  157. %token <ident> T_EXTENDS "'extends'"
  158. %token <ident> T_IMPLEMENTS "'implements'"
  159. %token <ident> T_NAMESPACE "'namespace'"
  160. %token <ident> T_LIST "'list'"
  161. %token <ident> T_ARRAY "'array'"
  162. %token <ident> T_CALLABLE "'callable'"
  163. %token <ident> T_LINE "'__LINE__'"
  164. %token <ident> T_FILE "'__FILE__'"
  165. %token <ident> T_DIR "'__DIR__'"
  166. %token <ident> T_CLASS_C "'__CLASS__'"
  167. %token <ident> T_TRAIT_C "'__TRAIT__'"
  168. %token <ident> T_METHOD_C "'__METHOD__'"
  169. %token <ident> T_FUNC_C "'__FUNCTION__'"
  170. %token <ident> T_NS_C "'__NAMESPACE__'"
  171. %token END 0 "end of file"
  172. %token T_ATTRIBUTE "'#['"
  173. %token T_PLUS_EQUAL "'+='"
  174. %token T_MINUS_EQUAL "'-='"
  175. %token T_MUL_EQUAL "'*='"
  176. %token T_DIV_EQUAL "'/='"
  177. %token T_CONCAT_EQUAL "'.='"
  178. %token T_MOD_EQUAL "'%='"
  179. %token T_AND_EQUAL "'&='"
  180. %token T_OR_EQUAL "'|='"
  181. %token T_XOR_EQUAL "'^='"
  182. %token T_SL_EQUAL "'<<='"
  183. %token T_SR_EQUAL "'>>='"
  184. %token T_COALESCE_EQUAL "'??='"
  185. %token T_BOOLEAN_OR "'||'"
  186. %token T_BOOLEAN_AND "'&&'"
  187. %token T_IS_EQUAL "'=='"
  188. %token T_IS_NOT_EQUAL "'!='"
  189. %token T_IS_IDENTICAL "'==='"
  190. %token T_IS_NOT_IDENTICAL "'!=='"
  191. %token T_IS_SMALLER_OR_EQUAL "'<='"
  192. %token T_IS_GREATER_OR_EQUAL "'>='"
  193. %token T_SPACESHIP "'<=>'"
  194. %token T_SL "'<<'"
  195. %token T_SR "'>>'"
  196. %token T_INC "'++'"
  197. %token T_DEC "'--'"
  198. %token T_INT_CAST "'(int)'"
  199. %token T_DOUBLE_CAST "'(double)'"
  200. %token T_STRING_CAST "'(string)'"
  201. %token T_ARRAY_CAST "'(array)'"
  202. %token T_OBJECT_CAST "'(object)'"
  203. %token T_BOOL_CAST "'(bool)'"
  204. %token T_UNSET_CAST "'(unset)'"
  205. %token T_OBJECT_OPERATOR "'->'"
  206. %token T_NULLSAFE_OBJECT_OPERATOR "'?->'"
  207. %token T_DOUBLE_ARROW "'=>'"
  208. %token T_COMMENT "comment"
  209. %token T_DOC_COMMENT "doc comment"
  210. %token T_OPEN_TAG "open tag"
  211. %token T_OPEN_TAG_WITH_ECHO "'<?='"
  212. %token T_CLOSE_TAG "'?>'"
  213. %token T_WHITESPACE "whitespace"
  214. %token T_START_HEREDOC "heredoc start"
  215. %token T_END_HEREDOC "heredoc end"
  216. %token T_DOLLAR_OPEN_CURLY_BRACES "'${'"
  217. %token T_CURLY_OPEN "'{$'"
  218. %token T_PAAMAYIM_NEKUDOTAYIM "'::'"
  219. %token T_NS_SEPARATOR "'\\'"
  220. %token T_ELLIPSIS "'...'"
  221. %token T_COALESCE "'??'"
  222. %token T_POW "'**'"
  223. %token T_POW_EQUAL "'**='"
  224. /* We need to split the & token in two to avoid a shift/reduce conflict. For T1&$v and T1&T2,
  225. * with only one token lookahead, bison does not know whether to reduce T1 as a complete type,
  226. * or shift to continue parsing an intersection type. */
  227. %token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'"
  228. /* Bison warns on duplicate token literals, so use a different dummy value here.
  229. * It will be fixed up by zend_yytnamerr() later. */
  230. %token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp"
  231. %token T_BAD_CHARACTER "invalid character"
  232. /* Token used to force a parse error from the lexer */
  233. %token T_ERROR
  234. %type <ast> top_statement namespace_name name statement function_declaration_statement
  235. %type <ast> class_declaration_statement trait_declaration_statement legacy_namespace_name
  236. %type <ast> interface_declaration_statement interface_extends_list
  237. %type <ast> group_use_declaration inline_use_declarations inline_use_declaration
  238. %type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration
  239. %type <ast> unprefixed_use_declarations const_decl inner_statement
  240. %type <ast> expr optional_expr while_statement for_statement foreach_variable
  241. %type <ast> foreach_statement declare_statement finally_statement unset_variable variable
  242. %type <ast> extends_from parameter optional_type_without_static argument global_var
  243. %type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias
  244. %type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
  245. %type <ast> new_expr anonymous_class class_name class_name_reference simple_variable
  246. %type <ast> internal_functions_in_yacc
  247. %type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name
  248. %type <ast> variable_class_name dereferenceable_scalar constant class_constant
  249. %type <ast> fully_dereferenceable array_object_dereferenceable
  250. %type <ast> callable_expr callable_variable static_member new_variable
  251. %type <ast> encaps_var encaps_var_offset isset_variables
  252. %type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
  253. %type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
  254. %type <ast> echo_expr_list unset_variables catch_name_list catch_list optional_variable parameter_list class_statement_list
  255. %type <ast> implements_list case_list if_stmt_without_else
  256. %type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
  257. %type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
  258. %type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
  259. %type <ast> lexical_var_list encaps_list
  260. %type <ast> array_pair non_empty_array_pair_list array_pair_list possible_array_pair
  261. %type <ast> isset_variable type return_type type_expr type_without_static
  262. %type <ast> identifier type_expr_without_static union_type_without_static intersection_type_without_static
  263. %type <ast> inline_function union_type intersection_type
  264. %type <ast> attributed_statement attributed_class_statement attributed_parameter
  265. %type <ast> attribute_decl attribute attributes attribute_group namespace_declaration_name
  266. %type <ast> match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list
  267. %type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr
  268. %type <num> returns_ref function fn is_reference is_variadic variable_modifiers
  269. %type <num> method_modifiers non_empty_member_modifiers member_modifier
  270. %type <num> optional_property_modifiers property_modifier
  271. %type <num> class_modifiers class_modifier use_type backup_fn_flags
  272. %type <ptr> backup_lex_pos
  273. %type <str> backup_doc_comment
  274. %type <ident> reserved_non_modifiers semi_reserved
  275. %% /* Rules */
  276. start:
  277. top_statement_list { CG(ast) = $1; }
  278. ;
  279. reserved_non_modifiers:
  280. T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
  281. | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE
  282. | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY
  283. | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
  284. | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
  285. | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
  286. | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM
  287. ;
  288. semi_reserved:
  289. reserved_non_modifiers
  290. | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY
  291. ;
  292. ampersand:
  293. T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
  294. | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG
  295. ;
  296. identifier:
  297. T_STRING { $$ = $1; }
  298. | semi_reserved {
  299. zval zv;
  300. if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
  301. $$ = zend_ast_create_zval(&zv);
  302. }
  303. ;
  304. top_statement_list:
  305. top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); }
  306. | %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
  307. ;
  308. /* Name usable in a namespace declaration. */
  309. namespace_declaration_name:
  310. identifier { $$ = $1; }
  311. | T_NAME_QUALIFIED { $$ = $1; }
  312. ;
  313. /* Name usable in "use" declarations (leading separator forbidden). */
  314. namespace_name:
  315. T_STRING { $$ = $1; }
  316. | T_NAME_QUALIFIED { $$ = $1; }
  317. ;
  318. /* Name usable in "use" declarations (leading separator allowed). */
  319. legacy_namespace_name:
  320. namespace_name { $$ = $1; }
  321. | T_NAME_FULLY_QUALIFIED { $$ = $1; }
  322. ;
  323. name:
  324. T_STRING { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
  325. | T_NAME_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
  326. | T_NAME_FULLY_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_FQ; }
  327. | T_NAME_RELATIVE { $$ = $1; $$->attr = ZEND_NAME_RELATIVE; }
  328. ;
  329. attribute_decl:
  330. class_name
  331. { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL); }
  332. | class_name argument_list
  333. { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $2); }
  334. ;
  335. attribute_group:
  336. attribute_decl
  337. { $$ = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_GROUP, $1); }
  338. | attribute_group ',' attribute_decl
  339. { $$ = zend_ast_list_add($1, $3); }
  340. ;
  341. attribute:
  342. T_ATTRIBUTE attribute_group possible_comma ']' { $$ = $2; }
  343. ;
  344. attributes:
  345. attribute { $$ = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_LIST, $1); }
  346. | attributes attribute { $$ = zend_ast_list_add($1, $2); }
  347. ;
  348. attributed_statement:
  349. function_declaration_statement { $$ = $1; }
  350. | class_declaration_statement { $$ = $1; }
  351. | trait_declaration_statement { $$ = $1; }
  352. | interface_declaration_statement { $$ = $1; }
  353. | enum_declaration_statement { $$ = $1; }
  354. ;
  355. top_statement:
  356. statement { $$ = $1; }
  357. | attributed_statement { $$ = $1; }
  358. | attributes attributed_statement { $$ = zend_ast_with_attributes($2, $1); }
  359. | T_HALT_COMPILER '(' ')' ';'
  360. { $$ = zend_ast_create(ZEND_AST_HALT_COMPILER,
  361. zend_ast_create_zval_from_long(zend_get_scanned_file_offset()));
  362. zend_stop_lexing(); }
  363. | T_NAMESPACE namespace_declaration_name ';'
  364. { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, NULL);
  365. RESET_DOC_COMMENT(); }
  366. | T_NAMESPACE namespace_declaration_name { RESET_DOC_COMMENT(); }
  367. '{' top_statement_list '}'
  368. { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, $5); }
  369. | T_NAMESPACE { RESET_DOC_COMMENT(); }
  370. '{' top_statement_list '}'
  371. { $$ = zend_ast_create(ZEND_AST_NAMESPACE, NULL, $4); }
  372. | T_USE mixed_group_use_declaration ';' { $$ = $2; }
  373. | T_USE use_type group_use_declaration ';' { $$ = $3; $$->attr = $2; }
  374. | T_USE use_declarations ';' { $$ = $2; $$->attr = ZEND_SYMBOL_CLASS; }
  375. | T_USE use_type use_declarations ';' { $$ = $3; $$->attr = $2; }
  376. | T_CONST const_list ';' { $$ = $2; }
  377. ;
  378. use_type:
  379. T_FUNCTION { $$ = ZEND_SYMBOL_FUNCTION; }
  380. | T_CONST { $$ = ZEND_SYMBOL_CONST; }
  381. ;
  382. group_use_declaration:
  383. legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
  384. { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4); }
  385. ;
  386. mixed_group_use_declaration:
  387. legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
  388. { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4);}
  389. ;
  390. possible_comma:
  391. %empty
  392. | ','
  393. ;
  394. inline_use_declarations:
  395. inline_use_declarations ',' inline_use_declaration
  396. { $$ = zend_ast_list_add($1, $3); }
  397. | inline_use_declaration
  398. { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); }
  399. ;
  400. unprefixed_use_declarations:
  401. unprefixed_use_declarations ',' unprefixed_use_declaration
  402. { $$ = zend_ast_list_add($1, $3); }
  403. | unprefixed_use_declaration
  404. { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); }
  405. ;
  406. use_declarations:
  407. use_declarations ',' use_declaration
  408. { $$ = zend_ast_list_add($1, $3); }
  409. | use_declaration
  410. { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); }
  411. ;
  412. inline_use_declaration:
  413. unprefixed_use_declaration { $$ = $1; $$->attr = ZEND_SYMBOL_CLASS; }
  414. | use_type unprefixed_use_declaration { $$ = $2; $$->attr = $1; }
  415. ;
  416. unprefixed_use_declaration:
  417. namespace_name
  418. { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); }
  419. | namespace_name T_AS T_STRING
  420. { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); }
  421. ;
  422. use_declaration:
  423. legacy_namespace_name
  424. { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); }
  425. | legacy_namespace_name T_AS T_STRING
  426. { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); }
  427. ;
  428. const_list:
  429. const_list ',' const_decl { $$ = zend_ast_list_add($1, $3); }
  430. | const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CONST_DECL, $1); }
  431. ;
  432. inner_statement_list:
  433. inner_statement_list inner_statement
  434. { $$ = zend_ast_list_add($1, $2); }
  435. | %empty
  436. { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
  437. ;
  438. inner_statement:
  439. statement { $$ = $1; }
  440. | attributed_statement { $$ = $1; }
  441. | attributes attributed_statement { $$ = zend_ast_with_attributes($2, $1); }
  442. | T_HALT_COMPILER '(' ')' ';'
  443. { $$ = NULL; zend_throw_exception(zend_ce_compile_error,
  444. "__HALT_COMPILER() can only be used from the outermost scope", 0); YYERROR; }
  445. ;
  446. statement:
  447. '{' inner_statement_list '}' { $$ = $2; }
  448. | if_stmt { $$ = $1; }
  449. | alt_if_stmt { $$ = $1; }
  450. | T_WHILE '(' expr ')' while_statement
  451. { $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); }
  452. | T_DO statement T_WHILE '(' expr ')' ';'
  453. { $$ = zend_ast_create(ZEND_AST_DO_WHILE, $2, $5); }
  454. | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement
  455. { $$ = zend_ast_create(ZEND_AST_FOR, $3, $5, $7, $9); }
  456. | T_SWITCH '(' expr ')' switch_case_list
  457. { $$ = zend_ast_create(ZEND_AST_SWITCH, $3, $5); }
  458. | T_BREAK optional_expr ';' { $$ = zend_ast_create(ZEND_AST_BREAK, $2); }
  459. | T_CONTINUE optional_expr ';' { $$ = zend_ast_create(ZEND_AST_CONTINUE, $2); }
  460. | T_RETURN optional_expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); }
  461. | T_GLOBAL global_var_list ';' { $$ = $2; }
  462. | T_STATIC static_var_list ';' { $$ = $2; }
  463. | T_ECHO echo_expr_list ';' { $$ = $2; }
  464. | T_INLINE_HTML { $$ = zend_ast_create(ZEND_AST_ECHO, $1); }
  465. | expr ';' { $$ = $1; }
  466. | T_UNSET '(' unset_variables possible_comma ')' ';' { $$ = $3; }
  467. | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
  468. { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $5, NULL, $7); }
  469. | T_FOREACH '(' expr T_AS foreach_variable T_DOUBLE_ARROW foreach_variable ')'
  470. foreach_statement
  471. { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $7, $5, $9); }
  472. | T_DECLARE '(' const_list ')'
  473. { if (!zend_handle_encoding_declaration($3)) { YYERROR; } }
  474. declare_statement
  475. { $$ = zend_ast_create(ZEND_AST_DECLARE, $3, $6); }
  476. | ';' /* empty statement */ { $$ = NULL; }
  477. | T_TRY '{' inner_statement_list '}' catch_list finally_statement
  478. { $$ = zend_ast_create(ZEND_AST_TRY, $3, $5, $6); }
  479. | T_GOTO T_STRING ';' { $$ = zend_ast_create(ZEND_AST_GOTO, $2); }
  480. | T_STRING ':' { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
  481. ;
  482. catch_list:
  483. %empty
  484. { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); }
  485. | catch_list T_CATCH '(' catch_name_list optional_variable ')' '{' inner_statement_list '}'
  486. { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); }
  487. ;
  488. catch_name_list:
  489. class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
  490. | catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); }
  491. ;
  492. optional_variable:
  493. %empty { $$ = NULL; }
  494. | T_VARIABLE { $$ = $1; }
  495. ;
  496. finally_statement:
  497. %empty { $$ = NULL; }
  498. | T_FINALLY '{' inner_statement_list '}' { $$ = $3; }
  499. ;
  500. unset_variables:
  501. unset_variable { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); }
  502. | unset_variables ',' unset_variable { $$ = zend_ast_list_add($1, $3); }
  503. ;
  504. unset_variable:
  505. variable { $$ = zend_ast_create(ZEND_AST_UNSET, $1); }
  506. ;
  507. function_declaration_statement:
  508. function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type
  509. backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
  510. { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4,
  511. zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; }
  512. ;
  513. is_reference:
  514. %empty { $$ = 0; }
  515. | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG { $$ = ZEND_PARAM_REF; }
  516. ;
  517. is_variadic:
  518. %empty { $$ = 0; }
  519. | T_ELLIPSIS { $$ = ZEND_PARAM_VARIADIC; }
  520. ;
  521. class_declaration_statement:
  522. class_modifiers T_CLASS { $<num>$ = CG(zend_lineno); }
  523. T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
  524. { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>3, $7, zend_ast_get_str($4), $5, $6, $9, NULL, NULL); }
  525. | T_CLASS { $<num>$ = CG(zend_lineno); }
  526. T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
  527. { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $<num>2, $6, zend_ast_get_str($3), $4, $5, $8, NULL, NULL); }
  528. ;
  529. class_modifiers:
  530. class_modifier { $$ = $1; }
  531. | class_modifiers class_modifier
  532. { $$ = zend_add_class_modifier($1, $2); if (!$$) { YYERROR; } }
  533. ;
  534. class_modifier:
  535. T_ABSTRACT { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
  536. | T_FINAL { $$ = ZEND_ACC_FINAL; }
  537. ;
  538. trait_declaration_statement:
  539. T_TRAIT { $<num>$ = CG(zend_lineno); }
  540. T_STRING backup_doc_comment '{' class_statement_list '}'
  541. { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $<num>2, $4, zend_ast_get_str($3), NULL, NULL, $6, NULL, NULL); }
  542. ;
  543. interface_declaration_statement:
  544. T_INTERFACE { $<num>$ = CG(zend_lineno); }
  545. T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
  546. { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $5, zend_ast_get_str($3), NULL, $4, $7, NULL, NULL); }
  547. ;
  548. enum_declaration_statement:
  549. T_ENUM { $<num>$ = CG(zend_lineno); }
  550. T_STRING enum_backing_type implements_list backup_doc_comment '{' class_statement_list '}'
  551. { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_ENUM|ZEND_ACC_FINAL, $<num>2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4); }
  552. ;
  553. enum_backing_type:
  554. %empty { $$ = NULL; }
  555. | ':' type_expr { $$ = $2; }
  556. ;
  557. enum_case:
  558. T_CASE backup_doc_comment identifier enum_case_expr ';'
  559. { $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $3, $4, ($2 ? zend_ast_create_zval_from_str($2) : NULL), NULL); }
  560. ;
  561. enum_case_expr:
  562. %empty { $$ = NULL; }
  563. | '=' expr { $$ = $2; }
  564. ;
  565. extends_from:
  566. %empty { $$ = NULL; }
  567. | T_EXTENDS class_name { $$ = $2; }
  568. ;
  569. interface_extends_list:
  570. %empty { $$ = NULL; }
  571. | T_EXTENDS class_name_list { $$ = $2; }
  572. ;
  573. implements_list:
  574. %empty { $$ = NULL; }
  575. | T_IMPLEMENTS class_name_list { $$ = $2; }
  576. ;
  577. foreach_variable:
  578. variable { $$ = $1; }
  579. | ampersand variable { $$ = zend_ast_create(ZEND_AST_REF, $2); }
  580. | T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; }
  581. | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
  582. ;
  583. for_statement:
  584. statement { $$ = $1; }
  585. | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; }
  586. ;
  587. foreach_statement:
  588. statement { $$ = $1; }
  589. | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; }
  590. ;
  591. declare_statement:
  592. statement { $$ = $1; }
  593. | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; }
  594. ;
  595. switch_case_list:
  596. '{' case_list '}' { $$ = $2; }
  597. | '{' ';' case_list '}' { $$ = $3; }
  598. | ':' case_list T_ENDSWITCH ';' { $$ = $2; }
  599. | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; }
  600. ;
  601. case_list:
  602. %empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); }
  603. | case_list T_CASE expr case_separator inner_statement_list
  604. { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); }
  605. | case_list T_DEFAULT case_separator inner_statement_list
  606. { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); }
  607. ;
  608. case_separator:
  609. ':'
  610. | ';'
  611. ;
  612. match:
  613. T_MATCH '(' expr ')' '{' match_arm_list '}'
  614. { $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); };
  615. ;
  616. match_arm_list:
  617. %empty { $$ = zend_ast_create_list(0, ZEND_AST_MATCH_ARM_LIST); }
  618. | non_empty_match_arm_list possible_comma { $$ = $1; }
  619. ;
  620. non_empty_match_arm_list:
  621. match_arm { $$ = zend_ast_create_list(1, ZEND_AST_MATCH_ARM_LIST, $1); }
  622. | non_empty_match_arm_list ',' match_arm { $$ = zend_ast_list_add($1, $3); }
  623. ;
  624. match_arm:
  625. match_arm_cond_list possible_comma T_DOUBLE_ARROW expr
  626. { $$ = zend_ast_create(ZEND_AST_MATCH_ARM, $1, $4); }
  627. | T_DEFAULT possible_comma T_DOUBLE_ARROW expr
  628. { $$ = zend_ast_create(ZEND_AST_MATCH_ARM, NULL, $4); }
  629. ;
  630. match_arm_cond_list:
  631. expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); }
  632. | match_arm_cond_list ',' expr { $$ = zend_ast_list_add($1, $3); }
  633. ;
  634. while_statement:
  635. statement { $$ = $1; }
  636. | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
  637. ;
  638. if_stmt_without_else:
  639. T_IF '(' expr ')' statement
  640. { $$ = zend_ast_create_list(1, ZEND_AST_IF,
  641. zend_ast_create(ZEND_AST_IF_ELEM, $3, $5)); }
  642. | if_stmt_without_else T_ELSEIF '(' expr ')' statement
  643. { $$ = zend_ast_list_add($1,
  644. zend_ast_create(ZEND_AST_IF_ELEM, $4, $6)); }
  645. ;
  646. if_stmt:
  647. if_stmt_without_else %prec T_NOELSE { $$ = $1; }
  648. | if_stmt_without_else T_ELSE statement
  649. { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_IF_ELEM, NULL, $3)); }
  650. ;
  651. alt_if_stmt_without_else:
  652. T_IF '(' expr ')' ':' inner_statement_list
  653. { $$ = zend_ast_create_list(1, ZEND_AST_IF,
  654. zend_ast_create(ZEND_AST_IF_ELEM, $3, $6)); }
  655. | alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list
  656. { $$ = zend_ast_list_add($1,
  657. zend_ast_create(ZEND_AST_IF_ELEM, $4, $7)); }
  658. ;
  659. alt_if_stmt:
  660. alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; }
  661. | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';'
  662. { $$ = zend_ast_list_add($1,
  663. zend_ast_create(ZEND_AST_IF_ELEM, NULL, $4)); }
  664. ;
  665. parameter_list:
  666. non_empty_parameter_list possible_comma { $$ = $1; }
  667. | %empty { $$ = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); }
  668. ;
  669. non_empty_parameter_list:
  670. attributed_parameter
  671. { $$ = zend_ast_create_list(1, ZEND_AST_PARAM_LIST, $1); }
  672. | non_empty_parameter_list ',' attributed_parameter
  673. { $$ = zend_ast_list_add($1, $3); }
  674. ;
  675. attributed_parameter:
  676. attributes parameter { $$ = zend_ast_with_attributes($2, $1); }
  677. | parameter { $$ = $1; }
  678. ;
  679. optional_property_modifiers:
  680. %empty { $$ = 0; }
  681. | optional_property_modifiers property_modifier
  682. { $$ = zend_add_member_modifier($1, $2); if (!$$) { YYERROR; } }
  683. property_modifier:
  684. T_PUBLIC { $$ = ZEND_ACC_PUBLIC; }
  685. | T_PROTECTED { $$ = ZEND_ACC_PROTECTED; }
  686. | T_PRIVATE { $$ = ZEND_ACC_PRIVATE; }
  687. | T_READONLY { $$ = ZEND_ACC_READONLY; }
  688. ;
  689. parameter:
  690. optional_property_modifiers optional_type_without_static
  691. is_reference is_variadic T_VARIABLE backup_doc_comment
  692. { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, NULL,
  693. NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL); }
  694. | optional_property_modifiers optional_type_without_static
  695. is_reference is_variadic T_VARIABLE backup_doc_comment '=' expr
  696. { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $8,
  697. NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL); }
  698. ;
  699. optional_type_without_static:
  700. %empty { $$ = NULL; }
  701. | type_expr_without_static { $$ = $1; }
  702. ;
  703. type_expr:
  704. type { $$ = $1; }
  705. | '?' type { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; }
  706. | union_type { $$ = $1; }
  707. | intersection_type { $$ = $1; }
  708. ;
  709. type:
  710. type_without_static { $$ = $1; }
  711. | T_STATIC { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC); }
  712. ;
  713. union_type:
  714. type '|' type { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_UNION, $1, $3); }
  715. | union_type '|' type { $$ = zend_ast_list_add($1, $3); }
  716. ;
  717. intersection_type:
  718. type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_INTERSECTION, $1, $3); }
  719. | intersection_type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type { $$ = zend_ast_list_add($1, $3); }
  720. ;
  721. /* Duplicate the type rules without "static",
  722. * to avoid conflicts with "static" modifier for properties. */
  723. type_expr_without_static:
  724. type_without_static { $$ = $1; }
  725. | '?' type_without_static { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; }
  726. | union_type_without_static { $$ = $1; }
  727. | intersection_type_without_static { $$ = $1; }
  728. ;
  729. type_without_static:
  730. T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); }
  731. | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); }
  732. | name { $$ = $1; }
  733. ;
  734. union_type_without_static:
  735. type_without_static '|' type_without_static
  736. { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_UNION, $1, $3); }
  737. | union_type_without_static '|' type_without_static
  738. { $$ = zend_ast_list_add($1, $3); }
  739. ;
  740. intersection_type_without_static:
  741. type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static
  742. { $$ = zend_ast_create_list(2, ZEND_AST_TYPE_INTERSECTION, $1, $3); }
  743. | intersection_type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static
  744. { $$ = zend_ast_list_add($1, $3); }
  745. ;
  746. return_type:
  747. %empty { $$ = NULL; }
  748. | ':' type_expr { $$ = $2; }
  749. ;
  750. argument_list:
  751. '(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
  752. | '(' non_empty_argument_list possible_comma ')' { $$ = $2; }
  753. | '(' T_ELLIPSIS ')' { $$ = zend_ast_create(ZEND_AST_CALLABLE_CONVERT); }
  754. ;
  755. non_empty_argument_list:
  756. argument
  757. { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
  758. | non_empty_argument_list ',' argument
  759. { $$ = zend_ast_list_add($1, $3); }
  760. ;
  761. argument:
  762. expr { $$ = $1; }
  763. | identifier ':' expr
  764. { $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
  765. | T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
  766. ;
  767. global_var_list:
  768. global_var_list ',' global_var { $$ = zend_ast_list_add($1, $3); }
  769. | global_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); }
  770. ;
  771. global_var:
  772. simple_variable
  773. { $$ = zend_ast_create(ZEND_AST_GLOBAL, zend_ast_create(ZEND_AST_VAR, $1)); }
  774. ;
  775. static_var_list:
  776. static_var_list ',' static_var { $$ = zend_ast_list_add($1, $3); }
  777. | static_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); }
  778. ;
  779. static_var:
  780. T_VARIABLE { $$ = zend_ast_create(ZEND_AST_STATIC, $1, NULL); }
  781. | T_VARIABLE '=' expr { $$ = zend_ast_create(ZEND_AST_STATIC, $1, $3); }
  782. ;
  783. class_statement_list:
  784. class_statement_list class_statement
  785. { $$ = zend_ast_list_add($1, $2); }
  786. | %empty
  787. { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
  788. ;
  789. attributed_class_statement:
  790. variable_modifiers optional_type_without_static property_list ';'
  791. { $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, $3, NULL);
  792. $$->attr = $1; }
  793. | method_modifiers T_CONST class_const_list ';'
  794. { $$ = zend_ast_create(ZEND_AST_CLASS_CONST_GROUP, $3, NULL);
  795. $$->attr = $1; }
  796. | method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')'
  797. return_type backup_fn_flags method_body backup_fn_flags
  798. { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5,
  799. zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; }
  800. | enum_case { $$ = $1; }
  801. ;
  802. class_statement:
  803. attributed_class_statement { $$ = $1; }
  804. | attributes attributed_class_statement { $$ = zend_ast_with_attributes($2, $1); }
  805. | T_USE class_name_list trait_adaptations
  806. { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
  807. ;
  808. class_name_list:
  809. class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
  810. | class_name_list ',' class_name { $$ = zend_ast_list_add($1, $3); }
  811. ;
  812. trait_adaptations:
  813. ';' { $$ = NULL; }
  814. | '{' '}' { $$ = NULL; }
  815. | '{' trait_adaptation_list '}' { $$ = $2; }
  816. ;
  817. trait_adaptation_list:
  818. trait_adaptation
  819. { $$ = zend_ast_create_list(1, ZEND_AST_TRAIT_ADAPTATIONS, $1); }
  820. | trait_adaptation_list trait_adaptation
  821. { $$ = zend_ast_list_add($1, $2); }
  822. ;
  823. trait_adaptation:
  824. trait_precedence ';' { $$ = $1; }
  825. | trait_alias ';' { $$ = $1; }
  826. ;
  827. trait_precedence:
  828. absolute_trait_method_reference T_INSTEADOF class_name_list
  829. { $$ = zend_ast_create(ZEND_AST_TRAIT_PRECEDENCE, $1, $3); }
  830. ;
  831. trait_alias:
  832. trait_method_reference T_AS T_STRING
  833. { $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, $3); }
  834. | trait_method_reference T_AS reserved_non_modifiers
  835. { zval zv;
  836. if (zend_lex_tstring(&zv, $3) == FAILURE) { YYABORT; }
  837. $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&zv)); }
  838. | trait_method_reference T_AS member_modifier identifier
  839. { $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, $4); }
  840. | trait_method_reference T_AS member_modifier
  841. { $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, NULL); }
  842. ;
  843. trait_method_reference:
  844. identifier
  845. { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); }
  846. | absolute_trait_method_reference { $$ = $1; }
  847. ;
  848. absolute_trait_method_reference:
  849. class_name T_PAAMAYIM_NEKUDOTAYIM identifier
  850. { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
  851. ;
  852. method_body:
  853. ';' /* abstract method */ { $$ = NULL; }
  854. | '{' inner_statement_list '}' { $$ = $2; }
  855. ;
  856. variable_modifiers:
  857. non_empty_member_modifiers { $$ = $1; }
  858. | T_VAR { $$ = ZEND_ACC_PUBLIC; }
  859. ;
  860. method_modifiers:
  861. %empty { $$ = ZEND_ACC_PUBLIC; }
  862. | non_empty_member_modifiers
  863. { $$ = $1; if (!($$ & ZEND_ACC_PPP_MASK)) { $$ |= ZEND_ACC_PUBLIC; } }
  864. ;
  865. non_empty_member_modifiers:
  866. member_modifier { $$ = $1; }
  867. | non_empty_member_modifiers member_modifier
  868. { $$ = zend_add_member_modifier($1, $2); if (!$$) { YYERROR; } }
  869. ;
  870. member_modifier:
  871. T_PUBLIC { $$ = ZEND_ACC_PUBLIC; }
  872. | T_PROTECTED { $$ = ZEND_ACC_PROTECTED; }
  873. | T_PRIVATE { $$ = ZEND_ACC_PRIVATE; }
  874. | T_STATIC { $$ = ZEND_ACC_STATIC; }
  875. | T_ABSTRACT { $$ = ZEND_ACC_ABSTRACT; }
  876. | T_FINAL { $$ = ZEND_ACC_FINAL; }
  877. | T_READONLY { $$ = ZEND_ACC_READONLY; }
  878. ;
  879. property_list:
  880. property_list ',' property { $$ = zend_ast_list_add($1, $3); }
  881. | property { $$ = zend_ast_create_list(1, ZEND_AST_PROP_DECL, $1); }
  882. ;
  883. property:
  884. T_VARIABLE backup_doc_comment
  885. { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str($2) : NULL)); }
  886. | T_VARIABLE '=' expr backup_doc_comment
  887. { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); }
  888. ;
  889. class_const_list:
  890. class_const_list ',' class_const_decl { $$ = zend_ast_list_add($1, $3); }
  891. | class_const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); }
  892. ;
  893. class_const_decl:
  894. identifier '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); }
  895. ;
  896. const_decl:
  897. T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); }
  898. ;
  899. echo_expr_list:
  900. echo_expr_list ',' echo_expr { $$ = zend_ast_list_add($1, $3); }
  901. | echo_expr { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); }
  902. ;
  903. echo_expr:
  904. expr { $$ = zend_ast_create(ZEND_AST_ECHO, $1); }
  905. ;
  906. for_exprs:
  907. %empty { $$ = NULL; }
  908. | non_empty_for_exprs { $$ = $1; }
  909. ;
  910. non_empty_for_exprs:
  911. non_empty_for_exprs ',' expr { $$ = zend_ast_list_add($1, $3); }
  912. | expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); }
  913. ;
  914. anonymous_class:
  915. T_CLASS { $<num>$ = CG(zend_lineno); } ctor_arguments
  916. extends_from implements_list backup_doc_comment '{' class_statement_list '}' {
  917. zend_ast *decl = zend_ast_create_decl(
  918. ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, $<num>2, $6, NULL,
  919. $4, $5, $8, NULL, NULL);
  920. $$ = zend_ast_create(ZEND_AST_NEW, decl, $3);
  921. }
  922. ;
  923. new_expr:
  924. T_NEW class_name_reference ctor_arguments
  925. { $$ = zend_ast_create(ZEND_AST_NEW, $2, $3); }
  926. | T_NEW anonymous_class
  927. { $$ = $2; }
  928. | T_NEW attributes anonymous_class
  929. { zend_ast_with_attributes($3->child[0], $2); $$ = $3; }
  930. ;
  931. expr:
  932. variable
  933. { $$ = $1; }
  934. | T_LIST '(' array_pair_list ')' '=' expr
  935. { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
  936. | '[' array_pair_list ']' '=' expr
  937. { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); }
  938. | variable '=' expr
  939. { $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
  940. | variable '=' ampersand variable
  941. { $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
  942. | T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); }
  943. | variable T_PLUS_EQUAL expr
  944. { $$ = zend_ast_create_assign_op(ZEND_ADD, $1, $3); }
  945. | variable T_MINUS_EQUAL expr
  946. { $$ = zend_ast_create_assign_op(ZEND_SUB, $1, $3); }
  947. | variable T_MUL_EQUAL expr
  948. { $$ = zend_ast_create_assign_op(ZEND_MUL, $1, $3); }
  949. | variable T_POW_EQUAL expr
  950. { $$ = zend_ast_create_assign_op(ZEND_POW, $1, $3); }
  951. | variable T_DIV_EQUAL expr
  952. { $$ = zend_ast_create_assign_op(ZEND_DIV, $1, $3); }
  953. | variable T_CONCAT_EQUAL expr
  954. { $$ = zend_ast_create_assign_op(ZEND_CONCAT, $1, $3); }
  955. | variable T_MOD_EQUAL expr
  956. { $$ = zend_ast_create_assign_op(ZEND_MOD, $1, $3); }
  957. | variable T_AND_EQUAL expr
  958. { $$ = zend_ast_create_assign_op(ZEND_BW_AND, $1, $3); }
  959. | variable T_OR_EQUAL expr
  960. { $$ = zend_ast_create_assign_op(ZEND_BW_OR, $1, $3); }
  961. | variable T_XOR_EQUAL expr
  962. { $$ = zend_ast_create_assign_op(ZEND_BW_XOR, $1, $3); }
  963. | variable T_SL_EQUAL expr
  964. { $$ = zend_ast_create_assign_op(ZEND_SL, $1, $3); }
  965. | variable T_SR_EQUAL expr
  966. { $$ = zend_ast_create_assign_op(ZEND_SR, $1, $3); }
  967. | variable T_COALESCE_EQUAL expr
  968. { $$ = zend_ast_create(ZEND_AST_ASSIGN_COALESCE, $1, $3); }
  969. | variable T_INC { $$ = zend_ast_create(ZEND_AST_POST_INC, $1); }
  970. | T_INC variable { $$ = zend_ast_create(ZEND_AST_PRE_INC, $2); }
  971. | variable T_DEC { $$ = zend_ast_create(ZEND_AST_POST_DEC, $1); }
  972. | T_DEC variable { $$ = zend_ast_create(ZEND_AST_PRE_DEC, $2); }
  973. | expr T_BOOLEAN_OR expr
  974. { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); }
  975. | expr T_BOOLEAN_AND expr
  976. { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); }
  977. | expr T_LOGICAL_OR expr
  978. { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); }
  979. | expr T_LOGICAL_AND expr
  980. { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); }
  981. | expr T_LOGICAL_XOR expr
  982. { $$ = zend_ast_create_binary_op(ZEND_BOOL_XOR, $1, $3); }
  983. | expr '|' expr { $$ = zend_ast_create_binary_op(ZEND_BW_OR, $1, $3); }
  984. | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); }
  985. | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); }
  986. | expr '^' expr { $$ = zend_ast_create_binary_op(ZEND_BW_XOR, $1, $3); }
  987. | expr '.' expr { $$ = zend_ast_create_binary_op(ZEND_CONCAT, $1, $3); }
  988. | expr '+' expr { $$ = zend_ast_create_binary_op(ZEND_ADD, $1, $3); }
  989. | expr '-' expr { $$ = zend_ast_create_binary_op(ZEND_SUB, $1, $3); }
  990. | expr '*' expr { $$ = zend_ast_create_binary_op(ZEND_MUL, $1, $3); }
  991. | expr T_POW expr { $$ = zend_ast_create_binary_op(ZEND_POW, $1, $3); }
  992. | expr '/' expr { $$ = zend_ast_create_binary_op(ZEND_DIV, $1, $3); }
  993. | expr '%' expr { $$ = zend_ast_create_binary_op(ZEND_MOD, $1, $3); }
  994. | expr T_SL expr { $$ = zend_ast_create_binary_op(ZEND_SL, $1, $3); }
  995. | expr T_SR expr { $$ = zend_ast_create_binary_op(ZEND_SR, $1, $3); }
  996. | '+' expr %prec '~' { $$ = zend_ast_create(ZEND_AST_UNARY_PLUS, $2); }
  997. | '-' expr %prec '~' { $$ = zend_ast_create(ZEND_AST_UNARY_MINUS, $2); }
  998. | '!' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, $2); }
  999. | '~' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BW_NOT, $2); }
  1000. | expr T_IS_IDENTICAL expr
  1001. { $$ = zend_ast_create_binary_op(ZEND_IS_IDENTICAL, $1, $3); }
  1002. | expr T_IS_NOT_IDENTICAL expr
  1003. { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_IDENTICAL, $1, $3); }
  1004. | expr T_IS_EQUAL expr
  1005. { $$ = zend_ast_create_binary_op(ZEND_IS_EQUAL, $1, $3); }
  1006. | expr T_IS_NOT_EQUAL expr
  1007. { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_EQUAL, $1, $3); }
  1008. | expr '<' expr
  1009. { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER, $1, $3); }
  1010. | expr T_IS_SMALLER_OR_EQUAL expr
  1011. { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER_OR_EQUAL, $1, $3); }
  1012. | expr '>' expr
  1013. { $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); }
  1014. | expr T_IS_GREATER_OR_EQUAL expr
  1015. { $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); }
  1016. | expr T_SPACESHIP expr
  1017. { $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
  1018. | expr T_INSTANCEOF class_name_reference
  1019. { $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
  1020. | '(' expr ')' {
  1021. $$ = $2;
  1022. if ($$->kind == ZEND_AST_CONDITIONAL) $$->attr = ZEND_PARENTHESIZED_CONDITIONAL;
  1023. }
  1024. | new_expr { $$ = $1; }
  1025. | expr '?' expr ':' expr
  1026. { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); }
  1027. | expr '?' ':' expr
  1028. { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, NULL, $4); }
  1029. | expr T_COALESCE expr
  1030. { $$ = zend_ast_create(ZEND_AST_COALESCE, $1, $3); }
  1031. | internal_functions_in_yacc { $$ = $1; }
  1032. | T_INT_CAST expr { $$ = zend_ast_create_cast(IS_LONG, $2); }
  1033. | T_DOUBLE_CAST expr { $$ = zend_ast_create_cast(IS_DOUBLE, $2); }
  1034. | T_STRING_CAST expr { $$ = zend_ast_create_cast(IS_STRING, $2); }
  1035. | T_ARRAY_CAST expr { $$ = zend_ast_create_cast(IS_ARRAY, $2); }
  1036. | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); }
  1037. | T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); }
  1038. | T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); }
  1039. | T_EXIT exit_expr { $$ = zend_ast_create(ZEND_AST_EXIT, $2); }
  1040. | '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); }
  1041. | scalar { $$ = $1; }
  1042. | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); }
  1043. | T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); }
  1044. | T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
  1045. | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
  1046. | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
  1047. | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; }
  1048. | T_THROW expr { $$ = zend_ast_create(ZEND_AST_THROW, $2); }
  1049. | inline_function { $$ = $1; }
  1050. | attributes inline_function { $$ = zend_ast_with_attributes($2, $1); }
  1051. | T_STATIC inline_function { $$ = $2; ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; }
  1052. | attributes T_STATIC inline_function
  1053. { $$ = zend_ast_with_attributes($3, $1); ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; }
  1054. | match { $$ = $1; }
  1055. ;
  1056. inline_function:
  1057. function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type
  1058. backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
  1059. { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3,
  1060. zend_string_init("{closure}", sizeof("{closure}") - 1, 0),
  1061. $5, $7, $11, $8, NULL); CG(extra_fn_flags) = $9; }
  1062. | fn returns_ref backup_doc_comment '(' parameter_list ')' return_type
  1063. T_DOUBLE_ARROW backup_fn_flags backup_lex_pos expr backup_fn_flags
  1064. { $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $12, $1, $3,
  1065. zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $5, NULL,
  1066. zend_ast_create(ZEND_AST_RETURN, $11), $7, NULL);
  1067. ((zend_ast_decl *) $$)->lex_pos = $10;
  1068. CG(extra_fn_flags) = $9; }
  1069. ;
  1070. fn:
  1071. T_FN { $$ = CG(zend_lineno); }
  1072. ;
  1073. function:
  1074. T_FUNCTION { $$ = CG(zend_lineno); }
  1075. ;
  1076. backup_doc_comment:
  1077. %empty { $$ = CG(doc_comment); CG(doc_comment) = NULL; }
  1078. ;
  1079. backup_fn_flags:
  1080. %prec PREC_ARROW_FUNCTION %empty { $$ = CG(extra_fn_flags); CG(extra_fn_flags) = 0; }
  1081. ;
  1082. backup_lex_pos:
  1083. %empty { $$ = LANG_SCNG(yy_text); }
  1084. ;
  1085. returns_ref:
  1086. %empty { $$ = 0; }
  1087. | ampersand { $$ = ZEND_ACC_RETURN_REFERENCE; }
  1088. ;
  1089. lexical_vars:
  1090. %empty { $$ = NULL; }
  1091. | T_USE '(' lexical_var_list possible_comma ')' { $$ = $3; }
  1092. ;
  1093. lexical_var_list:
  1094. lexical_var_list ',' lexical_var { $$ = zend_ast_list_add($1, $3); }
  1095. | lexical_var { $$ = zend_ast_create_list(1, ZEND_AST_CLOSURE_USES, $1); }
  1096. ;
  1097. lexical_var:
  1098. T_VARIABLE { $$ = $1; }
  1099. | ampersand T_VARIABLE { $$ = $2; $$->attr = ZEND_BIND_REF; }
  1100. ;
  1101. function_call:
  1102. name argument_list
  1103. { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
  1104. | class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
  1105. { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
  1106. | variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
  1107. { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
  1108. | callable_expr argument_list
  1109. { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
  1110. ;
  1111. class_name:
  1112. T_STATIC
  1113. { zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_STATIC));
  1114. $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); }
  1115. | name { $$ = $1; }
  1116. ;
  1117. class_name_reference:
  1118. class_name { $$ = $1; }
  1119. | new_variable { $$ = $1; }
  1120. | '(' expr ')' { $$ = $2; }
  1121. ;
  1122. exit_expr:
  1123. %empty { $$ = NULL; }
  1124. | '(' optional_expr ')' { $$ = $2; }
  1125. ;
  1126. backticks_expr:
  1127. %empty
  1128. { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); }
  1129. | T_ENCAPSED_AND_WHITESPACE { $$ = $1; }
  1130. | encaps_list { $$ = $1; }
  1131. ;
  1132. ctor_arguments:
  1133. %empty { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
  1134. | argument_list { $$ = $1; }
  1135. ;
  1136. dereferenceable_scalar:
  1137. T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; }
  1138. | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
  1139. | T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
  1140. | '"' encaps_list '"' { $$ = $2; }
  1141. ;
  1142. scalar:
  1143. T_LNUMBER { $$ = $1; }
  1144. | T_DNUMBER { $$ = $1; }
  1145. | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
  1146. | T_START_HEREDOC T_END_HEREDOC
  1147. { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); }
  1148. | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
  1149. | dereferenceable_scalar { $$ = $1; }
  1150. | constant { $$ = $1; }
  1151. | class_constant { $$ = $1; }
  1152. ;
  1153. constant:
  1154. name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
  1155. | T_LINE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_LINE); }
  1156. | T_FILE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FILE); }
  1157. | T_DIR { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_DIR); }
  1158. | T_TRAIT_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_TRAIT_C); }
  1159. | T_METHOD_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_METHOD_C); }
  1160. | T_FUNC_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FUNC_C); }
  1161. | T_NS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_NS_C); }
  1162. | T_CLASS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_CLASS_C); }
  1163. ;
  1164. class_constant:
  1165. class_name T_PAAMAYIM_NEKUDOTAYIM identifier
  1166. { $$ = zend_ast_create_class_const_or_name($1, $3); }
  1167. | variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier
  1168. { $$ = zend_ast_create_class_const_or_name($1, $3); }
  1169. ;
  1170. optional_expr:
  1171. %empty { $$ = NULL; }
  1172. | expr { $$ = $1; }
  1173. ;
  1174. variable_class_name:
  1175. fully_dereferenceable { $$ = $1; }
  1176. ;
  1177. fully_dereferenceable:
  1178. variable { $$ = $1; }
  1179. | '(' expr ')' { $$ = $2; }
  1180. | dereferenceable_scalar { $$ = $1; }
  1181. | class_constant { $$ = $1; }
  1182. ;
  1183. array_object_dereferenceable:
  1184. fully_dereferenceable { $$ = $1; }
  1185. | constant { $$ = $1; }
  1186. ;
  1187. callable_expr:
  1188. callable_variable { $$ = $1; }
  1189. | '(' expr ')' { $$ = $2; }
  1190. | dereferenceable_scalar { $$ = $1; }
  1191. ;
  1192. callable_variable:
  1193. simple_variable
  1194. { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1195. | array_object_dereferenceable '[' optional_expr ']'
  1196. { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
  1197. | array_object_dereferenceable '{' expr '}'
  1198. { $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_DIM_ALTERNATIVE_SYNTAX, $1, $3); }
  1199. | array_object_dereferenceable T_OBJECT_OPERATOR property_name argument_list
  1200. { $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
  1201. | array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list
  1202. { $$ = zend_ast_create(ZEND_AST_NULLSAFE_METHOD_CALL, $1, $3, $4); }
  1203. | function_call { $$ = $1; }
  1204. ;
  1205. variable:
  1206. callable_variable
  1207. { $$ = $1; }
  1208. | static_member
  1209. { $$ = $1; }
  1210. | array_object_dereferenceable T_OBJECT_OPERATOR property_name
  1211. { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
  1212. | array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name
  1213. { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP, $1, $3); }
  1214. ;
  1215. simple_variable:
  1216. T_VARIABLE { $$ = $1; }
  1217. | '$' '{' expr '}' { $$ = $3; }
  1218. | '$' simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $2); }
  1219. ;
  1220. static_member:
  1221. class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
  1222. { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
  1223. | variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
  1224. { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
  1225. ;
  1226. new_variable:
  1227. simple_variable
  1228. { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1229. | new_variable '[' optional_expr ']'
  1230. { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
  1231. | new_variable '{' expr '}'
  1232. { $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_DIM_ALTERNATIVE_SYNTAX, $1, $3); }
  1233. | new_variable T_OBJECT_OPERATOR property_name
  1234. { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
  1235. | new_variable T_NULLSAFE_OBJECT_OPERATOR property_name
  1236. { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP, $1, $3); }
  1237. | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
  1238. { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
  1239. | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable
  1240. { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
  1241. ;
  1242. member_name:
  1243. identifier { $$ = $1; }
  1244. | '{' expr '}' { $$ = $2; }
  1245. | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1246. ;
  1247. property_name:
  1248. T_STRING { $$ = $1; }
  1249. | '{' expr '}' { $$ = $2; }
  1250. | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1251. ;
  1252. array_pair_list:
  1253. non_empty_array_pair_list
  1254. { /* allow single trailing comma */ $$ = zend_ast_list_rtrim($1); }
  1255. ;
  1256. possible_array_pair:
  1257. %empty { $$ = NULL; }
  1258. | array_pair { $$ = $1; }
  1259. ;
  1260. non_empty_array_pair_list:
  1261. non_empty_array_pair_list ',' possible_array_pair
  1262. { $$ = zend_ast_list_add($1, $3); }
  1263. | possible_array_pair
  1264. { $$ = zend_ast_create_list(1, ZEND_AST_ARRAY, $1); }
  1265. ;
  1266. array_pair:
  1267. expr T_DOUBLE_ARROW expr
  1268. { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); }
  1269. | expr
  1270. { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); }
  1271. | expr T_DOUBLE_ARROW ampersand variable
  1272. { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $4, $1); }
  1273. | ampersand variable
  1274. { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); }
  1275. | T_ELLIPSIS expr
  1276. { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
  1277. | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')'
  1278. { $5->attr = ZEND_ARRAY_SYNTAX_LIST;
  1279. $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
  1280. | T_LIST '(' array_pair_list ')'
  1281. { $3->attr = ZEND_ARRAY_SYNTAX_LIST;
  1282. $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); }
  1283. ;
  1284. encaps_list:
  1285. encaps_list encaps_var
  1286. { $$ = zend_ast_list_add($1, $2); }
  1287. | encaps_list T_ENCAPSED_AND_WHITESPACE
  1288. { $$ = zend_ast_list_add($1, $2); }
  1289. | encaps_var
  1290. { $$ = zend_ast_create_list(1, ZEND_AST_ENCAPS_LIST, $1); }
  1291. | T_ENCAPSED_AND_WHITESPACE encaps_var
  1292. { $$ = zend_ast_create_list(2, ZEND_AST_ENCAPS_LIST, $1, $2); }
  1293. ;
  1294. encaps_var:
  1295. T_VARIABLE
  1296. { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1297. | T_VARIABLE '[' encaps_var_offset ']'
  1298. { $$ = zend_ast_create(ZEND_AST_DIM,
  1299. zend_ast_create(ZEND_AST_VAR, $1), $3); }
  1300. | T_VARIABLE T_OBJECT_OPERATOR T_STRING
  1301. { $$ = zend_ast_create(ZEND_AST_PROP,
  1302. zend_ast_create(ZEND_AST_VAR, $1), $3); }
  1303. | T_VARIABLE T_NULLSAFE_OBJECT_OPERATOR T_STRING
  1304. { $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP,
  1305. zend_ast_create(ZEND_AST_VAR, $1), $3); }
  1306. | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
  1307. { $$ = zend_ast_create(ZEND_AST_VAR, $2); }
  1308. | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'
  1309. { $$ = zend_ast_create(ZEND_AST_VAR, $2); }
  1310. | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
  1311. { $$ = zend_ast_create(ZEND_AST_DIM,
  1312. zend_ast_create(ZEND_AST_VAR, $2), $4); }
  1313. | T_CURLY_OPEN variable '}' { $$ = $2; }
  1314. ;
  1315. encaps_var_offset:
  1316. T_STRING { $$ = $1; }
  1317. | T_NUM_STRING { $$ = $1; }
  1318. | '-' T_NUM_STRING { $$ = zend_negate_num_string($2); }
  1319. | T_VARIABLE { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
  1320. ;
  1321. internal_functions_in_yacc:
  1322. T_ISSET '(' isset_variables possible_comma ')' { $$ = $3; }
  1323. | T_EMPTY '(' expr ')' { $$ = zend_ast_create(ZEND_AST_EMPTY, $3); }
  1324. | T_INCLUDE expr
  1325. { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2); }
  1326. | T_INCLUDE_ONCE expr
  1327. { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2); }
  1328. | T_EVAL '(' expr ')'
  1329. { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_EVAL, $3); }
  1330. | T_REQUIRE expr
  1331. { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2); }
  1332. | T_REQUIRE_ONCE expr
  1333. { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2); }
  1334. ;
  1335. isset_variables:
  1336. isset_variable { $$ = $1; }
  1337. | isset_variables ',' isset_variable
  1338. { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); }
  1339. ;
  1340. isset_variable:
  1341. expr { $$ = zend_ast_create(ZEND_AST_ISSET, $1); }
  1342. ;
  1343. %%
  1344. /* Over-ride Bison formatting routine to give better token descriptions.
  1345. Copy to YYRES the contents of YYSTR for use in yyerror.
  1346. YYSTR is taken from yytname, from the %token declaration.
  1347. If YYRES is null, do not copy; instead, return the length of what
  1348. the result would have been. */
  1349. static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
  1350. {
  1351. const char *toktype = yystr;
  1352. size_t toktype_len = strlen(toktype);
  1353. /* CG(parse_error) states:
  1354. * 0 => yyres = NULL, yystr is the unexpected token
  1355. * 1 => yyres = NULL, yystr is one of the expected tokens
  1356. * 2 => yyres != NULL, yystr is the unexpected token
  1357. * 3 => yyres != NULL, yystr is one of the expected tokens
  1358. */
  1359. if (yyres && CG(parse_error) < 2) {
  1360. CG(parse_error) = 2;
  1361. }
  1362. if (CG(parse_error) % 2 == 0) {
  1363. /* The unexpected token */
  1364. char buffer[120];
  1365. const unsigned char *tokcontent, *tokcontent_end;
  1366. size_t tokcontent_len;
  1367. CG(parse_error)++;
  1368. if (LANG_SCNG(yy_text)[0] == 0 &&
  1369. LANG_SCNG(yy_leng) == 1 &&
  1370. strcmp(toktype, "\"end of file\"") == 0) {
  1371. if (yyres) {
  1372. yystpcpy(yyres, "end of file");
  1373. }
  1374. return sizeof("end of file")-1;
  1375. }
  1376. /* Prevent the backslash getting doubled in the output (eugh) */
  1377. if (strcmp(toktype, "\"'\\\\'\"") == 0) {
  1378. if (yyres) {
  1379. yystpcpy(yyres, "token \"\\\"");
  1380. }
  1381. return sizeof("token \"\\\"")-1;
  1382. }
  1383. /* We used "amp" as a dummy label to avoid a duplicate token literal warning. */
  1384. if (strcmp(toktype, "\"amp\"") == 0) {
  1385. if (yyres) {
  1386. yystpcpy(yyres, "token \"&\"");
  1387. }
  1388. return sizeof("token \"&\"")-1;
  1389. }
  1390. /* Avoid unreadable """ */
  1391. /* "'" would theoretically be just as bad, but is never currently parsed as a separate token */
  1392. if (strcmp(toktype, "'\"'") == 0) {
  1393. if (yyres) {
  1394. yystpcpy(yyres, "double-quote mark");
  1395. }
  1396. return sizeof("double-quote mark")-1;
  1397. }
  1398. /* Strip off the outer quote marks */
  1399. if (toktype_len >= 2 && *toktype == '"') {
  1400. toktype++;
  1401. toktype_len -= 2;
  1402. }
  1403. /* If the token always has one form, the %token line should have a single-quoted name */
  1404. /* The parser rules also include single-character un-named tokens which will be single-quoted here */
  1405. /* We re-format this with double quotes here to ensure everything's consistent */
  1406. if (toktype_len > 0 && *toktype == '\'') {
  1407. if (yyres) {
  1408. snprintf(buffer, sizeof(buffer), "token \"%.*s\"", (int)toktype_len-2, toktype+1);
  1409. yystpcpy(yyres, buffer);
  1410. }
  1411. return toktype_len + sizeof("token ")-1;
  1412. }
  1413. /* Fetch the content of the last seen token from global lexer state */
  1414. tokcontent = LANG_SCNG(yy_text);
  1415. tokcontent_len = LANG_SCNG(yy_leng);
  1416. /* For T_BAD_CHARACTER, the content probably won't be a printable char */
  1417. /* Also, "unexpected invalid character" sounds a bit redundant */
  1418. if (tokcontent_len == 1 && strcmp(yystr, "\"invalid character\"") == 0) {
  1419. if (yyres) {
  1420. snprintf(buffer, sizeof(buffer), "character 0x%02hhX", *tokcontent);
  1421. yystpcpy(yyres, buffer);
  1422. }
  1423. return sizeof("character 0x00")-1;
  1424. }
  1425. /* Truncate at line end to avoid messing up log formats */
  1426. tokcontent_end = memchr(tokcontent, '\n', tokcontent_len);
  1427. if (tokcontent_end != NULL) {
  1428. tokcontent_len = (tokcontent_end - tokcontent);
  1429. }
  1430. /* Try to be helpful about what kind of string was found, before stripping the quotes */
  1431. if (tokcontent_len > 0 && strcmp(yystr, "\"quoted string\"") == 0) {
  1432. if (*tokcontent == '"') {
  1433. toktype = "double-quoted string";
  1434. toktype_len = sizeof("double-quoted string")-1;
  1435. }
  1436. else if (*tokcontent == '\'') {
  1437. toktype = "single-quoted string";
  1438. toktype_len = sizeof("single-quoted string")-1;
  1439. }
  1440. }
  1441. /* For quoted strings, strip off another layer of quotes to avoid putting quotes inside quotes */
  1442. if (tokcontent_len > 0 && (*tokcontent == '\'' || *tokcontent=='"')) {
  1443. tokcontent++;
  1444. tokcontent_len--;
  1445. }
  1446. if (tokcontent_len > 0 && (tokcontent[tokcontent_len-1] == '\'' || tokcontent[tokcontent_len-1] == '"')) {
  1447. tokcontent_len--;
  1448. }
  1449. /* Truncate to 30 characters and add a ... */
  1450. if (tokcontent_len > 30 + sizeof("...")-1) {
  1451. if (yyres) {
  1452. snprintf(buffer, sizeof(buffer), "%.*s \"%.*s...\"", (int)toktype_len, toktype, 30, tokcontent);
  1453. yystpcpy(yyres, buffer);
  1454. }
  1455. return toktype_len + 30 + sizeof(" \"...\"")-1;
  1456. }
  1457. if (yyres) {
  1458. snprintf(buffer, sizeof(buffer), "%.*s \"%.*s\"", (int)toktype_len, toktype, (int)tokcontent_len, tokcontent);
  1459. yystpcpy(yyres, buffer);
  1460. }
  1461. return toktype_len + tokcontent_len + sizeof(" \"\"")-1;
  1462. }
  1463. /* One of the expected tokens */
  1464. /* Prevent the backslash getting doubled in the output (eugh) */
  1465. if (strcmp(toktype, "\"'\\\\'\"") == 0) {
  1466. if (yyres) {
  1467. yystpcpy(yyres, "\"\\\"");
  1468. }
  1469. return sizeof("\"\\\"")-1;
  1470. }
  1471. /* Strip off the outer quote marks */
  1472. if (toktype_len >= 2 && *toktype == '"') {
  1473. toktype++;
  1474. toktype_len -= 2;
  1475. }
  1476. if (yyres) {
  1477. YYSIZE_T yyn = 0;
  1478. for (; yyn < toktype_len; ++yyn) {
  1479. /* Replace single quotes with double for consistency */
  1480. if (toktype[yyn] == '\'') {
  1481. yyres[yyn] = '"';
  1482. }
  1483. else {
  1484. yyres[yyn] = toktype[yyn];
  1485. }
  1486. }
  1487. yyres[toktype_len] = '\0';
  1488. }
  1489. return toktype_len;
  1490. }