ffi.g 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Author: Dmitry Stogov <dmitry@zend.com> |
  14. +----------------------------------------------------------------------+
  15. */
  16. /*
  17. To generate ffi_parser.c use llk <https://github.com/dstogov/llk>:
  18. php llk.php ffi.g
  19. */
  20. %start declarations
  21. %sub-start type_name
  22. %case-sensetive true
  23. %global-vars false
  24. %output "ffi_parser.c"
  25. %language "c"
  26. %indent "\t"
  27. %{
  28. /*
  29. +----------------------------------------------------------------------+
  30. | Copyright (c) The PHP Group |
  31. +----------------------------------------------------------------------+
  32. | This source file is subject to version 3.01 of the PHP license, |
  33. | that is bundled with this package in the file LICENSE, and is |
  34. | available through the world-wide-web at the following url: |
  35. | https://www.php.net/license/3_01.txt |
  36. | If you did not receive a copy of the PHP license and are unable to |
  37. | obtain it through the world-wide-web, please send a note to |
  38. | license@php.net so we can mail you a copy immediately. |
  39. +----------------------------------------------------------------------+
  40. | Author: Dmitry Stogov <dmitry@zend.com> |
  41. +----------------------------------------------------------------------+
  42. */
  43. #ifdef HAVE_CONFIG_H
  44. # include "config.h"
  45. #endif
  46. #include "php.h"
  47. #include "php_ffi.h"
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #define yy_buf FFI_G(buf)
  52. #define yy_end FFI_G(end)
  53. #define yy_pos FFI_G(pos)
  54. #define yy_text FFI_G(text)
  55. #define yy_line FFI_G(line)
  56. /* forward declarations */
  57. static void yy_error(const char *msg);
  58. static void yy_error_sym(const char *msg, int sym);
  59. %}
  60. declarations:
  61. (
  62. {zend_ffi_dcl common_dcl = ZEND_FFI_ATTR_INIT;}
  63. "__extension__"?
  64. declaration_specifiers(&common_dcl)
  65. (
  66. {const char *name;}
  67. {size_t name_len;}
  68. {zend_ffi_dcl dcl;}
  69. {dcl = common_dcl;}
  70. declarator(&dcl, &name, &name_len)
  71. (
  72. {zend_ffi_val asm_str;}
  73. "__asm__"
  74. "("
  75. STRING(&asm_str)+
  76. /*TODO*/
  77. ")"
  78. )?
  79. attributes(&dcl)?
  80. initializer?
  81. {zend_ffi_declare(name, name_len, &dcl);}
  82. ( ","
  83. {dcl = common_dcl;}
  84. declarator(&dcl, &name, &name_len)
  85. attributes(&dcl)?
  86. initializer?
  87. {zend_ffi_declare(name, name_len, &dcl);}
  88. )*
  89. )?
  90. ";"
  91. )*
  92. ;
  93. declaration_specifiers(zend_ffi_dcl *dcl):
  94. ( ?{sym != YY_ID || !(dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS)}
  95. ( {if (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) yy_error_sym("unexpected", sym);}
  96. "typedef"
  97. {dcl->flags |= ZEND_FFI_DCL_TYPEDEF;}
  98. | {if (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) yy_error_sym("unexpected", sym);}
  99. "extern"
  100. {dcl->flags |= ZEND_FFI_DCL_EXTERN;}
  101. | {if (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) yy_error_sym("unexpected", sym);}
  102. "static"
  103. {dcl->flags |= ZEND_FFI_DCL_STATIC;}
  104. | {if (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) yy_error_sym("unexpected", sym);}
  105. "auto"
  106. {dcl->flags |= ZEND_FFI_DCL_AUTO;}
  107. | {if (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) yy_error_sym("unexpected", sym);}
  108. "register"
  109. {dcl->flags |= ZEND_FFI_DCL_REGISTER;}
  110. // | "_Thread_local" // TODO: not-implemented ???
  111. | ("inline"|"__inline"|"__inline__")
  112. {dcl->flags |= ZEND_FFI_DCL_INLINE;}
  113. | "_Noreturn"
  114. {dcl->flags |= ZEND_FFI_DCL_NO_RETURN;}
  115. | "_Alignas"
  116. "("
  117. ( &type_name_start
  118. {zend_ffi_dcl align_dcl = ZEND_FFI_ATTR_INIT;}
  119. type_name(&align_dcl)
  120. {zend_ffi_align_as_type(dcl, &align_dcl);}
  121. | {zend_ffi_val align_val;}
  122. constant_expression(&align_val)
  123. {zend_ffi_align_as_val(dcl, &align_val);}
  124. )
  125. ")"
  126. | attributes(dcl)
  127. | type_qualifier(dcl)
  128. | type_specifier(dcl)
  129. )
  130. )+
  131. ;
  132. specifier_qualifier_list(zend_ffi_dcl *dcl):
  133. "__extension__"?
  134. ( ?{sym != YY_ID || zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text) || (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) == 0}
  135. ( type_specifier(dcl)
  136. | type_qualifier(dcl)
  137. | attributes(dcl)
  138. )
  139. )+
  140. ;
  141. type_qualifier_list(zend_ffi_dcl *dcl):
  142. ( type_qualifier(dcl)
  143. | attributes(dcl)
  144. )+
  145. ;
  146. type_qualifier(zend_ffi_dcl *dcl):
  147. ("const"|"__const"|"__const__")
  148. {dcl->flags |= ZEND_FFI_DCL_CONST;}
  149. {dcl->attr |= ZEND_FFI_ATTR_CONST;}
  150. | ("restrict"|"__restrict"|"__restrict__")
  151. {dcl->flags |= ZEND_FFI_DCL_RESTRICT;}
  152. | ("volatile"|"__volatile"|"__volatile__")
  153. {dcl->flags |= ZEND_FFI_DCL_VOLATILE;}
  154. | "_Atomic"
  155. {dcl->flags |= ZEND_FFI_DCL_ATOMIC;}
  156. ;
  157. type_specifier(zend_ffi_dcl *dcl):
  158. {const char *name;}
  159. {size_t name_len;}
  160. ( {if (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) yy_error_sym("unexpected", sym);}
  161. "void"
  162. {dcl->flags |= ZEND_FFI_DCL_VOID;}
  163. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_UNSIGNED))) yy_error_sym("unexpected", sym);}
  164. "char"
  165. {dcl->flags |= ZEND_FFI_DCL_CHAR;}
  166. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_INT))) yy_error_sym("unexpected", sym);}
  167. "short"
  168. {dcl->flags |= ZEND_FFI_DCL_SHORT;}
  169. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_SHORT|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_LONG_LONG))) yy_error_sym("unexpected", sym);}
  170. "int"
  171. {dcl->flags |= ZEND_FFI_DCL_INT;}
  172. | {
  173. if (dcl->flags & ZEND_FFI_DCL_LONG) {
  174. if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_INT))) yy_error_sym("unexpected", sym);
  175. dcl->flags |= ZEND_FFI_DCL_LONG_LONG;
  176. } else {
  177. if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_SIGNED|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_INT|ZEND_FFI_DCL_DOUBLE|ZEND_FFI_DCL_COMPLEX))) yy_error_sym("unexpected", sym);
  178. dcl->flags |= ZEND_FFI_DCL_LONG;
  179. }
  180. }
  181. "long"
  182. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_COMPLEX))) yy_error_sym("unexpected", sym);}
  183. "float"
  184. {dcl->flags |= ZEND_FFI_DCL_FLOAT;}
  185. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_COMPLEX))) yy_error_sym("unexpected", sym);}
  186. "double"
  187. {dcl->flags |= ZEND_FFI_DCL_DOUBLE;}
  188. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_CHAR|ZEND_FFI_DCL_SHORT|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_INT))) yy_error_sym("unexpected", sym);}
  189. "signed"
  190. {dcl->flags |= ZEND_FFI_DCL_SIGNED;}
  191. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_CHAR|ZEND_FFI_DCL_SHORT|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_LONG_LONG|ZEND_FFI_DCL_INT))) yy_error_sym("unexpected", sym);}
  192. "unsigned"
  193. {dcl->flags |= ZEND_FFI_DCL_UNSIGNED;}
  194. | {if (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) yy_error_sym("unexpected", sym);}
  195. "_Bool"
  196. {dcl->flags |= ZEND_FFI_DCL_BOOL;}
  197. | {if (dcl->flags & (ZEND_FFI_DCL_TYPE_SPECIFIERS-(ZEND_FFI_DCL_FLOAT|ZEND_FFI_DCL_DOUBLE|ZEND_FFI_DCL_LONG))) yy_error_sym("unexpected", sym);}
  198. ("_Complex"|"complex"|"__complex"|"__complex__")
  199. {dcl->flags |= ZEND_FFI_DCL_COMPLEX;}
  200. // | "_Atomic" "(" type_name ")" // TODO: not-implemented ???
  201. | {if (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) yy_error_sym("unexpected", sym);}
  202. struct_or_union_specifier(dcl)
  203. | {if (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) yy_error_sym("unexpected", sym);}
  204. enum_specifier(dcl)
  205. | {if (dcl->flags & ZEND_FFI_DCL_TYPE_SPECIFIERS) yy_error_sym("unexpected", sym);}
  206. {/*redeclaration of '%.*s' ??? */}
  207. ID(&name, &name_len)
  208. {dcl->flags |= ZEND_FFI_DCL_TYPEDEF_NAME;}
  209. {zend_ffi_resolve_typedef(name, name_len, dcl);}
  210. )
  211. ;
  212. struct_or_union_specifier(zend_ffi_dcl *dcl):
  213. ( "struct"
  214. {dcl->flags |= ZEND_FFI_DCL_STRUCT;}
  215. | "union"
  216. {dcl->flags |= ZEND_FFI_DCL_UNION;}
  217. )
  218. attributes(dcl)?
  219. ( {const char *name;}
  220. {size_t name_len;}
  221. ID(&name, &name_len)
  222. {zend_ffi_declare_tag(name, name_len, dcl, 1);}
  223. ( struct_contents(dcl)
  224. {zend_ffi_declare_tag(name, name_len, dcl, 0);}
  225. )?
  226. | {zend_ffi_make_struct_type(dcl);}
  227. struct_contents(dcl)
  228. )
  229. ;
  230. struct_contents(zend_ffi_dcl *dcl):
  231. "{"
  232. ( struct_declaration(dcl)
  233. ( ";"
  234. struct_declaration(dcl)
  235. )*
  236. (";")?
  237. )?
  238. "}"
  239. attributes(dcl)?+
  240. {zend_ffi_adjust_struct_size(dcl);}
  241. ;
  242. struct_declaration(zend_ffi_dcl *struct_dcl):
  243. {zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;}
  244. specifier_qualifier_list(&common_field_dcl)
  245. ( /* empty */
  246. {zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);}
  247. | struct_declarator(struct_dcl, &common_field_dcl)
  248. ( ","
  249. {zend_ffi_dcl field_dcl = common_field_dcl;}
  250. attributes(&field_dcl)?
  251. struct_declarator(struct_dcl, &field_dcl)
  252. )*
  253. )
  254. ;
  255. struct_declarator(zend_ffi_dcl *struct_dcl, zend_ffi_dcl *field_dcl):
  256. {const char *name = NULL;}
  257. {size_t name_len = 0;}
  258. {zend_ffi_val bits;}
  259. ( declarator(field_dcl, &name, &name_len)
  260. ( ":"
  261. constant_expression(&bits)
  262. attributes(field_dcl)?
  263. {zend_ffi_add_bit_field(struct_dcl, name, name_len, field_dcl, &bits);}
  264. | /*empty */
  265. attributes(field_dcl)?
  266. {zend_ffi_add_field(struct_dcl, name, name_len, field_dcl);}
  267. )
  268. | ":"
  269. constant_expression(&bits)
  270. {zend_ffi_add_bit_field(struct_dcl, NULL, 0, field_dcl, &bits);}
  271. )
  272. ;
  273. enum_specifier(zend_ffi_dcl *dcl):
  274. "enum"
  275. {dcl->flags |= ZEND_FFI_DCL_ENUM;}
  276. attributes(dcl)?
  277. ( {const char *name;}
  278. {size_t name_len;}
  279. ID(&name, &name_len)
  280. ( {zend_ffi_declare_tag(name, name_len, dcl, 0);}
  281. "{"
  282. enumerator_list(dcl)
  283. "}"
  284. attributes(dcl)?+
  285. | {zend_ffi_declare_tag(name, name_len, dcl, 1);}
  286. )
  287. | "{"
  288. {zend_ffi_make_enum_type(dcl);}
  289. enumerator_list(dcl)
  290. "}"
  291. attributes(dcl)?+
  292. )
  293. ;
  294. enumerator_list(zend_ffi_dcl *enum_dcl):
  295. {int64_t min = 0, max = 0, last = -1;}
  296. enumerator(enum_dcl, &min, &max, &last)
  297. ( ","
  298. enumerator(enum_dcl, &min, &max, &last)
  299. )*
  300. ","?
  301. ;
  302. enumerator(zend_ffi_dcl *enum_dcl, int64_t *min, int64_t *max, int64_t *last):
  303. {const char *name;}
  304. {size_t name_len;}
  305. {zend_ffi_val val = {.kind = ZEND_FFI_VAL_EMPTY};}
  306. ID(&name, &name_len)
  307. ( "="
  308. constant_expression(&val)
  309. )?
  310. {zend_ffi_add_enum_val(enum_dcl, name, name_len, &val, min, max, last);}
  311. ;
  312. declarator(zend_ffi_dcl *dcl, const char **name, size_t *name_len):
  313. {zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL};}
  314. {bool nested = 0;}
  315. pointer(dcl)?
  316. ( ID(name, name_len)
  317. | "("
  318. attributes(&nested_dcl)?
  319. declarator(&nested_dcl, name, name_len)
  320. ")"
  321. {nested = 1;}
  322. )
  323. array_or_function_declarators(dcl, &nested_dcl)?
  324. {if (nested) zend_ffi_nested_declaration(dcl, &nested_dcl);}
  325. ;
  326. abstract_declarator(zend_ffi_dcl *dcl):
  327. {zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL};}
  328. {bool nested = 0;}
  329. pointer(dcl)?
  330. ( &nested_declarator_start
  331. "("
  332. attributes(&nested_dcl)?
  333. abstract_declarator(&nested_dcl)
  334. ")"
  335. {nested = 1;}
  336. )?
  337. array_or_function_declarators(dcl, &nested_dcl)?
  338. {if (nested) zend_ffi_nested_declaration(dcl, &nested_dcl);}
  339. ;
  340. parameter_declarator(zend_ffi_dcl *dcl, const char **name, size_t *name_len):
  341. {zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL};}
  342. {bool nested = 0;}
  343. pointer(dcl)?
  344. ( &nested_declarator_start
  345. "("
  346. attributes(&nested_dcl)?
  347. parameter_declarator(&nested_dcl, name, name_len)
  348. ")"
  349. {nested = 1;}
  350. | ID(name, name_len)
  351. | /* empty */
  352. )
  353. array_or_function_declarators(dcl, &nested_dcl)?
  354. {if (nested) zend_ffi_nested_declaration(dcl, &nested_dcl);}
  355. ;
  356. pointer(zend_ffi_dcl *dcl):
  357. ( "*"
  358. {zend_ffi_make_pointer_type(dcl);}
  359. type_qualifier_list(dcl)?
  360. )+
  361. ;
  362. array_or_function_declarators(zend_ffi_dcl *dcl, zend_ffi_dcl *nested_dcl):
  363. {zend_ffi_dcl dummy = ZEND_FFI_ATTR_INIT;}
  364. {zend_ffi_val len = {.kind = ZEND_FFI_VAL_EMPTY};}
  365. {HashTable *args = NULL;}
  366. {uint32_t attr = 0;}
  367. ( "["
  368. ( "static"
  369. type_qualifier_list(&dummy)?
  370. assignment_expression(&len)
  371. | type_qualifier_list(&dummy)
  372. ( "static" assignment_expression(&len)
  373. | /* empty */
  374. {attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;}
  375. | "*"
  376. {attr |= ZEND_FFI_ATTR_VLA;}
  377. | assignment_expression(&len)
  378. )
  379. | ( /* empty */
  380. {attr |= ZEND_FFI_ATTR_INCOMPLETE_ARRAY;}
  381. | "*"
  382. {attr |= ZEND_FFI_ATTR_VLA;}
  383. | assignment_expression(&len)
  384. )
  385. )
  386. "]"
  387. array_or_function_declarators(dcl, nested_dcl)?
  388. {dcl->attr |= attr;}
  389. {zend_ffi_make_array_type(dcl, &len);}
  390. | "("
  391. (
  392. parameter_declaration(&args)
  393. ( ","
  394. parameter_declaration(&args)
  395. )*
  396. (
  397. ","
  398. "..."
  399. {attr |= ZEND_FFI_ATTR_VARIADIC;}
  400. )?
  401. | "..."
  402. {attr |= ZEND_FFI_ATTR_VARIADIC;}
  403. )?
  404. ")"
  405. array_or_function_declarators(dcl, nested_dcl)?
  406. {dcl->attr |= attr;}
  407. {zend_ffi_make_func_type(dcl, args, nested_dcl);}
  408. // | "(" (ID ("," ID)*)? ")" // TODO: ANSI function not-implemented ???
  409. )
  410. ;
  411. parameter_declaration(HashTable **args):
  412. {const char *name = NULL;}
  413. {size_t name_len = 0;}
  414. {bool old_allow_vla = FFI_G(allow_vla);}
  415. {FFI_G(allow_vla) = 1;}
  416. {zend_ffi_dcl param_dcl = ZEND_FFI_ATTR_INIT;}
  417. specifier_qualifier_list(&param_dcl)
  418. parameter_declarator(&param_dcl, &name, &name_len)
  419. /*attributes(&param_dcl)? conflict ???*/
  420. {zend_ffi_add_arg(args, name, name_len, &param_dcl);}
  421. {FFI_G(allow_vla) = old_allow_vla;}
  422. ;
  423. type_name(zend_ffi_dcl *dcl):
  424. specifier_qualifier_list(dcl)
  425. abstract_declarator(dcl)
  426. ;
  427. attributes(zend_ffi_dcl *dcl):
  428. {const char *name;}
  429. {size_t name_len;}
  430. {zend_ffi_val val;}
  431. (
  432. ("__attribute"|"__attribute__")
  433. "("
  434. "("
  435. attrib(dcl)
  436. ( ","
  437. attrib(dcl)
  438. )*
  439. ")"
  440. ")"
  441. | "__declspec"
  442. "("
  443. ( ID(&name, &name_len)
  444. (
  445. "("
  446. assignment_expression(&val)
  447. {zend_ffi_add_msvc_attribute_value(dcl, name, name_len, &val);}
  448. ")"
  449. )?
  450. )+
  451. ")"
  452. | "__cdecl"
  453. {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_CDECL);}
  454. | "__stdcall"
  455. {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_STDCALL);}
  456. | "__fastcall"
  457. {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_FASTCALL);}
  458. | "__thiscall"
  459. {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_THISCALL);}
  460. | "__vectorcall"
  461. {zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL);}
  462. )++
  463. ;
  464. attrib(zend_ffi_dcl *dcl):
  465. {const char *name;}
  466. {size_t name_len;}
  467. {int n;}
  468. {zend_ffi_val val;}
  469. {bool orig_attribute_parsing;}
  470. ( ID(&name, &name_len)
  471. ( /* empty */
  472. {zend_ffi_add_attribute(dcl, name, name_len);}
  473. | "("
  474. {orig_attribute_parsing = FFI_G(attribute_parsing);}
  475. {FFI_G(attribute_parsing) = 1;}
  476. assignment_expression(&val)
  477. {zend_ffi_add_attribute_value(dcl, name, name_len, 0, &val);}
  478. {n = 0;}
  479. ( ","
  480. assignment_expression(&val)
  481. {zend_ffi_add_attribute_value(dcl, name, name_len, ++n, &val);}
  482. )*
  483. {FFI_G(attribute_parsing) = orig_attribute_parsing;}
  484. ")"
  485. )
  486. | "const"
  487. | "__const"
  488. | "__const__"
  489. )?
  490. ;
  491. initializer:
  492. {zend_ffi_val dummy;}
  493. "="
  494. ( assignment_expression(&dummy)
  495. | "{" designation? initializer ( "," designation? initializer)* ","? "}"
  496. )
  497. ;
  498. designation:
  499. {const char *name;}
  500. {size_t name_len;}
  501. {zend_ffi_val dummy;}
  502. ( "[" constant_expression(&dummy) "]"
  503. | "." ID(&name, &name_len)
  504. )+
  505. "="
  506. ;
  507. expr_list:
  508. {zend_ffi_val dummy;}
  509. assignment_expression(&dummy)
  510. ( ","
  511. assignment_expression(&dummy)
  512. )*
  513. ;
  514. expression(zend_ffi_val *val):
  515. assignment_expression(val)
  516. ( ","
  517. assignment_expression(val)
  518. )*
  519. ;
  520. assignment_expression(zend_ffi_val *val):
  521. // ( unary_expression
  522. // ("="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|=")
  523. // )* // TODO: not-implemented ???
  524. conditional_expression(val)
  525. ;
  526. constant_expression(zend_ffi_val *val):
  527. conditional_expression(val)
  528. ;
  529. conditional_expression(zend_ffi_val *val):
  530. {zend_ffi_val op2, op3;}
  531. logical_or_expression(val)
  532. ( "?"
  533. expression(&op2)
  534. ":"
  535. conditional_expression(&op3)
  536. {zend_ffi_expr_conditional(val, &op2, &op3);}
  537. )?
  538. ;
  539. logical_or_expression(zend_ffi_val *val):
  540. {zend_ffi_val op2;}
  541. logical_and_expression(val)
  542. ( "||"
  543. logical_and_expression(&op2)
  544. {zend_ffi_expr_bool_or(val, &op2);}
  545. )*
  546. ;
  547. logical_and_expression(zend_ffi_val *val):
  548. {zend_ffi_val op2;}
  549. inclusive_or_expression(val)
  550. ( "&&"
  551. inclusive_or_expression(&op2)
  552. {zend_ffi_expr_bool_and(val, &op2);}
  553. )*
  554. ;
  555. inclusive_or_expression(zend_ffi_val *val):
  556. {zend_ffi_val op2;}
  557. exclusive_or_expression(val)
  558. ( "|"
  559. exclusive_or_expression(&op2)
  560. {zend_ffi_expr_bw_or(val, &op2);}
  561. )*
  562. ;
  563. exclusive_or_expression(zend_ffi_val *val):
  564. {zend_ffi_val op2;}
  565. and_expression(val)
  566. ( "^"
  567. and_expression(&op2)
  568. {zend_ffi_expr_bw_xor(val, &op2);}
  569. )*
  570. ;
  571. and_expression(zend_ffi_val *val):
  572. {zend_ffi_val op2;}
  573. equality_expression(val)
  574. ( "&"
  575. equality_expression(&op2)
  576. {zend_ffi_expr_bw_and(val, &op2);}
  577. )*
  578. ;
  579. equality_expression(zend_ffi_val *val):
  580. {zend_ffi_val op2;}
  581. relational_expression(val)
  582. ( "=="
  583. relational_expression(&op2)
  584. {zend_ffi_expr_is_equal(val, &op2);}
  585. | "!="
  586. relational_expression(&op2)
  587. {zend_ffi_expr_is_not_equal(val, &op2);}
  588. )*
  589. ;
  590. relational_expression(zend_ffi_val *val):
  591. {zend_ffi_val op2;}
  592. shift_expression(val)
  593. ( "<"
  594. shift_expression(&op2)
  595. {zend_ffi_expr_is_less(val, &op2);}
  596. | ">"
  597. shift_expression(&op2)
  598. {zend_ffi_expr_is_greater(val, &op2);}
  599. | "<="
  600. shift_expression(&op2)
  601. {zend_ffi_expr_is_less_or_equal(val, &op2);}
  602. | ">="
  603. shift_expression(&op2)
  604. {zend_ffi_expr_is_greater_or_equal(val, &op2);}
  605. )*
  606. ;
  607. shift_expression(zend_ffi_val *val):
  608. {zend_ffi_val op2;}
  609. additive_expression(val)
  610. ( "<<"
  611. additive_expression(&op2)
  612. {zend_ffi_expr_shift_left(val, &op2);}
  613. | ">>"
  614. additive_expression(&op2)
  615. {zend_ffi_expr_shift_right(val, &op2);}
  616. )*
  617. ;
  618. additive_expression(zend_ffi_val *val):
  619. {zend_ffi_val op2;}
  620. multiplicative_expression(val)
  621. ( "+"
  622. multiplicative_expression(&op2)
  623. {zend_ffi_expr_add(val, &op2);}
  624. | "-"
  625. multiplicative_expression(&op2)
  626. {zend_ffi_expr_sub(val, &op2);}
  627. )*
  628. ;
  629. multiplicative_expression(zend_ffi_val *val):
  630. {zend_ffi_val op2;}
  631. cast_expression(val)
  632. ( "*"
  633. cast_expression(&op2)
  634. {zend_ffi_expr_mul(val, &op2);}
  635. | "/"
  636. cast_expression(&op2)
  637. {zend_ffi_expr_div(val, &op2);}
  638. | "%"
  639. cast_expression(&op2)
  640. {zend_ffi_expr_mod(val, &op2);}
  641. )*
  642. ;
  643. cast_expression(zend_ffi_val *val):
  644. {int do_cast = 0;}
  645. {zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT;}
  646. ( &( "(" type_name_start )
  647. "("
  648. type_name(&dcl)
  649. ")"
  650. {do_cast = 1;}
  651. )?
  652. unary_expression(val)
  653. {if (do_cast) zend_ffi_expr_cast(val, &dcl);}
  654. ;
  655. unary_expression(zend_ffi_val *val):
  656. {const char *name;}
  657. {size_t name_len;}
  658. {zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT;}
  659. ( ID(&name, &name_len)
  660. {zend_ffi_resolve_const(name, name_len, val);}
  661. (
  662. ( "["
  663. expr_list
  664. "]"
  665. | "("
  666. expr_list?
  667. ")"
  668. | "."
  669. ID(&name, &name_len)
  670. | "->"
  671. ID(&name, &name_len)
  672. | "++"
  673. | "--"
  674. )
  675. {zend_ffi_val_error(val);}
  676. )*
  677. | OCTNUMBER(val)
  678. | DECNUMBER(val)
  679. | HEXNUMBER(val)
  680. | FLOATNUMBER(val)
  681. | STRING(val)
  682. | CHARACTER(val)
  683. | "("
  684. expression(val)
  685. ")"
  686. | "++"
  687. unary_expression(val)
  688. {zend_ffi_val_error(val);}
  689. | "--"
  690. unary_expression(val)
  691. {zend_ffi_val_error(val);}
  692. | "&"
  693. cast_expression(val)
  694. {zend_ffi_val_error(val);}
  695. | "*"
  696. cast_expression(val)
  697. {zend_ffi_val_error(val);}
  698. | "+"
  699. cast_expression(val)
  700. {zend_ffi_expr_plus(val);}
  701. | "-"
  702. cast_expression(val)
  703. {zend_ffi_expr_neg(val);}
  704. | "~"
  705. cast_expression(val)
  706. {zend_ffi_expr_bw_not(val);}
  707. | "!"
  708. cast_expression(val)
  709. {zend_ffi_expr_bool_not(val);}
  710. | "sizeof"
  711. ( &( "(" type_name_start )
  712. "("
  713. type_name(&dcl)
  714. ")"
  715. {zend_ffi_expr_sizeof_type(val, &dcl);}
  716. | unary_expression(val)
  717. {zend_ffi_expr_sizeof_val(val);}
  718. )
  719. | "_Alignof"
  720. "("
  721. type_name(&dcl)
  722. ")"
  723. {zend_ffi_expr_alignof_type(val, &dcl);}
  724. | ("__alignof"|"__alignof__")
  725. ( &( "(" type_name_start )
  726. "("
  727. type_name(&dcl)
  728. ")"
  729. {zend_ffi_expr_alignof_type(val, &dcl);}
  730. | unary_expression(val)
  731. {zend_ffi_expr_alignof_val(val);}
  732. )
  733. )
  734. ;
  735. /* lookahead rules */
  736. nested_declarator_start:
  737. "("
  738. ( ?{!zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text)}
  739. ID
  740. | "__attribute"
  741. | "__attribute__"
  742. | "__declspec"
  743. | "*"
  744. | "("
  745. | "["
  746. )
  747. ;
  748. type_name_start:
  749. ( ?{zend_ffi_is_typedef_name((const char*)yy_text, yy_pos - yy_text)}
  750. ID
  751. | "void"
  752. | "char"
  753. | "short"
  754. | "int"
  755. | "long"
  756. | "float"
  757. | "double"
  758. | "signed"
  759. | "unsigned"
  760. | "_Bool"
  761. | "_Complex"
  762. | "complex"
  763. | "__complex"
  764. | "__complex__"
  765. | "struct"
  766. | "union"
  767. | "enum"
  768. | "const"
  769. | "__const"
  770. | "__const__"
  771. | "restrict"
  772. | "__restict"
  773. | "__restrict__"
  774. | "volatile"
  775. | "__volatile"
  776. | "__volatile__"
  777. | "_Atomic"
  778. | "__attribute"
  779. | "__attribute__"
  780. | "__declspec"
  781. )
  782. ;
  783. /* scanner rules */
  784. ID(const char **name, size_t *name_len):
  785. /[A-Za-z_][A-Za-z_0-9]*/
  786. {*name = (const char*)yy_text; *name_len = yy_pos - yy_text;}
  787. ;
  788. OCTNUMBER(zend_ffi_val *val):
  789. /0[0-7]*([Uu](L|l|LL|l)?|[Ll][Uu]?|(LL|ll)[Uu])?/
  790. {zend_ffi_val_number(val, 8, (const char*)yy_text, yy_pos - yy_text);}
  791. ;
  792. DECNUMBER(zend_ffi_val *val):
  793. /[1-9][0-9]*([Uu](L|l|LL|l)?|[Ll][Uu]?|(LL|ll)[Uu])?/
  794. {zend_ffi_val_number(val, 10, (const char*)yy_text, yy_pos - yy_text);}
  795. ;
  796. HEXNUMBER(zend_ffi_val *val):
  797. /0[xX][0-9A-Fa-f][0-9A-Fa-f]*([Uu](L|l|LL|l)?|[Ll][Uu]?|(LL|ll)[Uu])?/
  798. {zend_ffi_val_number(val, 16, (const char*)yy_text + 2, yy_pos - yy_text - 2);}
  799. ;
  800. FLOATNUMBER(zend_ffi_val *val):
  801. /([0-9]*\.[0-9]+([Ee][\+\-]?[0-9]+)?|[0-9]+\.([Ee][\+\-]?[0-9]+)?|[0-9]+[Ee][\+\-]?[0-9]+)[flFL]?/
  802. {zend_ffi_val_float_number(val, (const char*)yy_text, yy_pos - yy_text);}
  803. ;
  804. STRING(zend_ffi_val *val):
  805. /(u8|u|U|L)?"([^"\\]|\\.)*"/
  806. {zend_ffi_val_string(val, (const char*)yy_text, yy_pos - yy_text);}
  807. ;
  808. CHARACTER(zend_ffi_val *val):
  809. /[LuU]?'([^'\\]|\\.)*'/
  810. {zend_ffi_val_character(val, (const char*)yy_text, yy_pos - yy_text);}
  811. ;
  812. EOL: /\r\n|\r|\n/;
  813. WS: /[ \t\f\v]+/;
  814. ONE_LINE_COMMENT: /(\/\/|#)[^\r\n]*(\r\n|\r|\n)/;
  815. COMMENT: /\/\*([^\*]|\*+[^\*\/])*\*+\//;
  816. SKIP: ( EOL | WS | ONE_LINE_COMMENT | COMMENT )*;
  817. %%
  818. int zend_ffi_parse_decl(const char *str, size_t len) {
  819. if (SETJMP(FFI_G(bailout))==0) {
  820. FFI_G(allow_vla) = 0;
  821. FFI_G(attribute_parsing) = 0;
  822. yy_buf = (unsigned char*)str;
  823. yy_end = yy_buf + len;
  824. parse();
  825. return SUCCESS;
  826. } else {
  827. return FAILURE;
  828. }
  829. }
  830. int zend_ffi_parse_type(const char *str, size_t len, zend_ffi_dcl *dcl) {
  831. int sym;
  832. if (SETJMP(FFI_G(bailout))==0) {
  833. FFI_G(allow_vla) = 0;
  834. FFI_G(attribute_parsing) = 0;
  835. yy_pos = yy_text = yy_buf = (unsigned char*)str;
  836. yy_end = yy_buf + len;
  837. yy_line = 1;
  838. sym = parse_type_name(get_sym(), dcl);
  839. if (sym != YY_EOF) {
  840. yy_error_sym("<EOF> expected, got", sym);
  841. }
  842. zend_ffi_validate_type_name(dcl);
  843. return SUCCESS;
  844. } else {
  845. return FAILURE;
  846. };
  847. }
  848. static void yy_error(const char *msg) {
  849. zend_ffi_parser_error("%s at line %d", msg, yy_line);
  850. }
  851. static void yy_error_sym(const char *msg, int sym) {
  852. zend_ffi_parser_error("%s '%s' at line %d", msg, sym_name[sym], yy_line);
  853. }