BsParserFX.y 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. %{
  2. #include "BsParserFX.h"
  3. #include "BsLexerFX.h"
  4. #define inline
  5. void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const char *msg);
  6. %}
  7. %code requires{
  8. #include "BsMMAlloc.h"
  9. #include "BsASTFX.h"
  10. #include "BsIncludeHandler.h"
  11. #ifndef YY_TYPEDEF_YY_SCANNER_T
  12. #define YY_TYPEDEF_YY_SCANNER_T
  13. typedef void* yyscan_t;
  14. #endif
  15. typedef struct YYLTYPE {
  16. int first_line;
  17. int first_column;
  18. int last_line;
  19. int last_column;
  20. char *filename;
  21. } YYLTYPE;
  22. #define YYLTYPE_IS_DECLARED 1
  23. #define YYLLOC_DEFAULT(Current, Rhs, N) \
  24. do \
  25. if (N) \
  26. { \
  27. (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
  28. (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
  29. (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
  30. (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
  31. (Current).filename = YYRHSLOC (Rhs, 1).filename; \
  32. } \
  33. else \
  34. { \
  35. (Current).first_line = (Current).last_line = YYRHSLOC (Rhs, 0).last_line; \
  36. (Current).first_column = (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \
  37. (Current).filename = NULL; \
  38. } \
  39. while (0)
  40. }
  41. %output "BsParserFX.c"
  42. %defines "BsParserFX.h"
  43. %define api.pure
  44. %locations
  45. %lex-param { yyscan_t scanner }
  46. %parse-param { ParseState* parse_state }
  47. %parse-param { yyscan_t scanner }
  48. %glr-parser
  49. %union {
  50. int intValue;
  51. float floatValue;
  52. float matrixValue[16];
  53. int intVectorValue[4];
  54. const char* strValue;
  55. ASTFXNode* nodePtr;
  56. NodeOption nodeOption;
  57. }
  58. /* Value types */
  59. %token <intValue> TOKEN_INTEGER
  60. %token <floatValue> TOKEN_FLOAT
  61. %token <intValue> TOKEN_BOOLEAN
  62. %token <strValue> TOKEN_STRING
  63. %token <strValue> TOKEN_IDENTIFIER
  64. /* State value types */
  65. %token <intValue> TOKEN_FILLMODEVALUE
  66. %token <intValue> TOKEN_CULLANDQUEUEVALUE
  67. %token <intValue> TOKEN_COMPFUNCVALUE
  68. %token <intValue> TOKEN_OPVALUE
  69. %token <intValue> TOKEN_BLENDOPVALUE
  70. %token <intValue> TOKEN_COLORMASK
  71. /* Qualifiers */
  72. %token TOKEN_BASE TOKEN_INHERITS
  73. /* Shader keywords */
  74. %token TOKEN_OPTIONS TOKEN_TECHNIQUE
  75. /* Options keywords */
  76. %token TOKEN_SEPARABLE TOKEN_SORT TOKEN_PRIORITY TOKEN_TRANSPARENT
  77. /* Technique keywords */
  78. %token TOKEN_RENDERER TOKEN_PASS TOKEN_TAGS
  79. /* Pass keywords */
  80. %token TOKEN_VERTEX TOKEN_FRAGMENT TOKEN_GEOMETRY TOKEN_HULL TOKEN_DOMAIN TOKEN_COMPUTE TOKEN_COMMON
  81. %token TOKEN_BLEND TOKEN_RASTER TOKEN_DEPTH TOKEN_STENCIL
  82. /* Rasterizer state keywords */
  83. %token TOKEN_FILLMODE TOKEN_CULLMODE TOKEN_DEPTHBIAS TOKEN_SDEPTHBIAS
  84. %token TOKEN_DEPTHCLIP TOKEN_SCISSOR TOKEN_MULTISAMPLE TOKEN_AALINE
  85. /* Depth state keywords */
  86. %token TOKEN_DEPTHREAD TOKEN_DEPTHWRITE TOKEN_COMPAREFUNC
  87. /* Stencil state keywords */
  88. %token TOKEN_STENCILREF TOKEN_ENABLED TOKEN_READMASK TOKEN_WRITEMASK
  89. %token TOKEN_STENCILOPFRONT TOKEN_STENCILOPBACK TOKEN_FAIL TOKEN_ZFAIL
  90. /* Blend state keywords */
  91. %token TOKEN_ALPHATOCOVERAGE TOKEN_INDEPENDANTBLEND TOKEN_TARGET TOKEN_INDEX
  92. %token TOKEN_COLOR TOKEN_ALPHA TOKEN_SOURCE TOKEN_DEST TOKEN_OP
  93. %type <nodePtr> shader;
  94. %type <nodeOption> shader_statement;
  95. %type <nodePtr> options;
  96. %type <nodePtr> options_header;
  97. %type <nodeOption> options_option;
  98. %type <nodePtr> technique;
  99. %type <nodePtr> technique_header;
  100. %type <nodeOption> technique_statement;
  101. %type <nodeOption> technique_option;
  102. %type <nodePtr> tags;
  103. %type <nodePtr> tags_header;
  104. %type <nodePtr> pass;
  105. %type <nodePtr> pass_header;
  106. %type <nodeOption> pass_statement;
  107. %type <nodeOption> pass_option;
  108. %type <nodePtr> raster;
  109. %type <nodePtr> raster_header;
  110. %type <nodeOption> raster_option;
  111. %type <nodePtr> depth;
  112. %type <nodePtr> depth_header;
  113. %type <nodeOption> depth_option;
  114. %type <nodePtr> stencil;
  115. %type <nodePtr> stencil_header;
  116. %type <nodeOption> stencil_option;
  117. %type <nodePtr> blend;
  118. %type <nodePtr> blend_header;
  119. %type <nodeOption> blend_option;
  120. %type <nodePtr> code;
  121. %type <nodePtr> code_header;
  122. %type <nodePtr> stencil_op_front_header;
  123. %type <nodePtr> stencil_op_back_header;
  124. %type <nodeOption> stencil_op_option;
  125. %type <nodePtr> target;
  126. %type <nodePtr> target_header;
  127. %type <nodeOption> target_statement;
  128. %type <nodeOption> target_option;
  129. %type <nodePtr> blend_color_header;
  130. %type <nodePtr> blend_alpha_header;
  131. %type <nodeOption> blenddef_option;
  132. %type <nodeOption> technique_qualifier
  133. %%
  134. /* Shader */
  135. shader
  136. : /* empty */ { }
  137. | shader_statement shader { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  138. ;
  139. shader_statement
  140. : options { $$.type = OT_Options; $$.value.nodePtr = $1; }
  141. | technique { $$.type = OT_Technique; $$.value.nodePtr = $1; }
  142. ;
  143. /* Options */
  144. options
  145. : options_header '{' options_body '}' ';' { nodePop(parse_state); $$ = $1; }
  146. ;
  147. options_header
  148. : TOKEN_OPTIONS
  149. {
  150. $$ = nodeCreate(parse_state->memContext, NT_Options);
  151. nodePush(parse_state, $$);
  152. }
  153. ;
  154. options_body
  155. : /* empty */
  156. | options_option options_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  157. ;
  158. options_option
  159. : TOKEN_SEPARABLE '=' TOKEN_BOOLEAN ';' { $$.type = OT_Separable; $$.value.intValue = $3; }
  160. | TOKEN_SORT '=' TOKEN_CULLANDQUEUEVALUE ';' { $$.type = OT_Sort; $$.value.intValue = $3; }
  161. | TOKEN_PRIORITY '=' TOKEN_INTEGER ';' { $$.type = OT_Priority; $$.value.intValue = $3; }
  162. | TOKEN_TRANSPARENT '=' TOKEN_BOOLEAN ';' { $$.type = OT_Transparent; $$.value.intValue = $3; }
  163. ;
  164. /* Technique */
  165. technique
  166. : technique_header technique_qualifier_list '{' technique_body '}' ';' { nodePop(parse_state); $$ = $1; }
  167. ;
  168. technique_header
  169. : TOKEN_TECHNIQUE
  170. {
  171. $$ = nodeCreate(parse_state->memContext, NT_Technique);
  172. nodePush(parse_state, $$);
  173. }
  174. ;
  175. technique_body
  176. : /* empty */
  177. | technique_statement technique_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  178. ;
  179. technique_statement
  180. : technique_option
  181. | pass { $$.type = OT_Pass; $$.value.nodePtr = $1; }
  182. | pass_option
  183. | code { $$.type = OT_Code; $$.value.nodePtr = $1; }
  184. ;
  185. technique_option
  186. : TOKEN_RENDERER '=' TOKEN_STRING ';' { $$.type = OT_Renderer; $$.value.strValue = $3; }
  187. | tags { $$.type = OT_Tags; $$.value.nodePtr = $1; }
  188. ;
  189. /* Technique tags */
  190. tags
  191. : tags_header '{' tags_body '}' ';' { nodePop(parse_state); $$ = $1; }
  192. ;
  193. tags_header
  194. : TOKEN_TAGS '='
  195. {
  196. $$ = nodeCreate(parse_state->memContext, NT_Tags);
  197. nodePush(parse_state, $$);
  198. }
  199. ;
  200. tags_body
  201. : /* empty */
  202. | TOKEN_STRING
  203. {
  204. NodeOption entry; entry.type = OT_TagValue; entry.value.strValue = $1;
  205. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &entry);
  206. }
  207. | TOKEN_STRING ',' tags_body
  208. {
  209. NodeOption entry; entry.type = OT_TagValue; entry.value.strValue = $1;
  210. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &entry);
  211. }
  212. ;
  213. /* Technique qualifiers */
  214. technique_qualifier_list
  215. : /* empty */
  216. | technique_qualifier technique_qualifier_list { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  217. ;
  218. technique_qualifier
  219. : ':' TOKEN_BASE '(' TOKEN_STRING ')' { $$.type = OT_Base; $$.value.strValue = $4; }
  220. | ':' TOKEN_INHERITS '(' TOKEN_STRING ')' { $$.type = OT_Inherits; $$.value.strValue = $4; }
  221. ;
  222. /* Pass */
  223. pass
  224. : pass_header '{' pass_body '}' ';' { nodePop(parse_state); $$ = $1; }
  225. ;
  226. pass_header
  227. : TOKEN_PASS
  228. {
  229. $$ = nodeCreate(parse_state->memContext, NT_Pass);
  230. nodePush(parse_state, $$);
  231. }
  232. ;
  233. pass_body
  234. : /* empty */
  235. | pass_statement pass_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  236. ;
  237. pass_statement
  238. : pass_option
  239. | code { $$.type = OT_Code; $$.value.nodePtr = $1; }
  240. ;
  241. pass_option
  242. : raster { $$.type = OT_Raster; $$.value.nodePtr = $1; }
  243. | depth { $$.type = OT_Depth; $$.value.nodePtr = $1; }
  244. | stencil { $$.type = OT_Stencil; $$.value.nodePtr = $1; }
  245. | blend { $$.type = OT_Blend; $$.value.nodePtr = $1; }
  246. ;
  247. /* Raster state */
  248. raster
  249. : raster_header '{' raster_body '}' ';' { nodePop(parse_state); $$ = $1; }
  250. ;
  251. raster_header
  252. : TOKEN_RASTER
  253. {
  254. $$ = nodeCreate(parse_state->memContext, NT_Raster);
  255. nodePush(parse_state, $$);
  256. }
  257. ;
  258. raster_body
  259. : /* empty */
  260. | raster_option raster_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  261. ;
  262. raster_option
  263. : TOKEN_FILLMODE '=' TOKEN_FILLMODEVALUE ';' { $$.type = OT_FillMode; $$.value.intValue = $3; }
  264. | TOKEN_CULLMODE '=' TOKEN_CULLANDQUEUEVALUE ';' { $$.type = OT_CullMode; $$.value.intValue = $3; }
  265. | TOKEN_DEPTHBIAS '=' TOKEN_FLOAT ';' { $$.type = OT_DepthBias; $$.value.floatValue = $3; }
  266. | TOKEN_SDEPTHBIAS '=' TOKEN_FLOAT ';' { $$.type = OT_SDepthBias; $$.value.floatValue = $3; }
  267. | TOKEN_DEPTHCLIP '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthClip; $$.value.intValue = $3; }
  268. | TOKEN_SCISSOR '=' TOKEN_BOOLEAN ';' { $$.type = OT_Scissor; $$.value.intValue = $3; }
  269. | TOKEN_MULTISAMPLE '=' TOKEN_BOOLEAN ';' { $$.type = OT_Multisample; $$.value.intValue = $3; }
  270. | TOKEN_AALINE '=' TOKEN_BOOLEAN ';' { $$.type = OT_AALine; $$.value.intValue = $3; }
  271. ;
  272. /* Depth state */
  273. depth
  274. : depth_header '{' depth_body '}' ';' { nodePop(parse_state); $$ = $1; }
  275. ;
  276. depth_header
  277. : TOKEN_DEPTH
  278. {
  279. $$ = nodeCreate(parse_state->memContext, NT_Depth);
  280. nodePush(parse_state, $$);
  281. }
  282. ;
  283. depth_body
  284. : /* empty */
  285. | depth_option depth_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  286. ;
  287. depth_option
  288. : TOKEN_DEPTHREAD '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthRead; $$.value.intValue = $3; }
  289. | TOKEN_DEPTHWRITE '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthWrite; $$.value.intValue = $3; }
  290. | TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';' { $$.type = OT_CompareFunc; $$.value.intValue = $3; }
  291. ;
  292. /* Stencil state */
  293. stencil
  294. : stencil_header '{' stencil_body '}' ';' { nodePop(parse_state); $$ = $1; }
  295. ;
  296. stencil_header
  297. : TOKEN_STENCIL
  298. {
  299. $$ = nodeCreate(parse_state->memContext, NT_Stencil);
  300. nodePush(parse_state, $$);
  301. }
  302. ;
  303. stencil_body
  304. : /* empty */
  305. | stencil_option stencil_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  306. ;
  307. stencil_option
  308. : TOKEN_ENABLED '=' TOKEN_BOOLEAN ';' { $$.type = OT_Enabled; $$.value.intValue = $3; }
  309. | TOKEN_READMASK '=' TOKEN_INTEGER ';' { $$.type = OT_StencilReadMask; $$.value.intValue = $3; }
  310. | TOKEN_WRITEMASK '=' TOKEN_INTEGER ';' { $$.type = OT_StencilWriteMask; $$.value.intValue = $3; }
  311. | stencil_op_front_header '{' stencil_op_body '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
  312. | stencil_op_back_header '{' stencil_op_body '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
  313. | stencil_op_front_header '{' stencil_op_body_init '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
  314. | stencil_op_back_header '{' stencil_op_body_init '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
  315. | TOKEN_STENCILREF '=' TOKEN_INTEGER ';' { $$.type = OT_StencilRef; $$.value.intValue = $3; }
  316. ;
  317. /* Blend state */
  318. blend
  319. : blend_header '{' blend_body '}' ';' { nodePop(parse_state); $$ = $1; }
  320. ;
  321. blend_header
  322. : TOKEN_BLEND
  323. {
  324. $$ = nodeCreate(parse_state->memContext, NT_Blend);
  325. nodePush(parse_state, $$);
  326. }
  327. ;
  328. blend_body
  329. : /* empty */
  330. | blend_option blend_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  331. ;
  332. blend_option
  333. : TOKEN_ALPHATOCOVERAGE '=' TOKEN_BOOLEAN ';' { $$.type = OT_AlphaToCoverage; $$.value.intValue = $3; }
  334. | TOKEN_INDEPENDANTBLEND '=' TOKEN_BOOLEAN ';' { $$.type = OT_IndependantBlend; $$.value.intValue = $3; }
  335. | target { $$.type = OT_Target; $$.value.nodePtr = $1; }
  336. ;
  337. /* Code blocks */
  338. code
  339. : code_header '{' TOKEN_INDEX '=' TOKEN_INTEGER ';' '}' ';'
  340. {
  341. NodeOption index;
  342. index.type = OT_Index;
  343. index.value.intValue = $5;
  344. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &index);
  345. nodePop(parse_state);
  346. $$ = $1;
  347. }
  348. ;
  349. code_header
  350. : TOKEN_VERTEX
  351. {
  352. $$ = nodeCreate(parse_state->memContext, NT_CodeVertex);
  353. nodePush(parse_state, $$);
  354. }
  355. | TOKEN_FRAGMENT
  356. {
  357. $$ = nodeCreate(parse_state->memContext, NT_CodeFragment);
  358. nodePush(parse_state, $$);
  359. }
  360. | TOKEN_GEOMETRY
  361. {
  362. $$ = nodeCreate(parse_state->memContext, NT_CodeGeometry);
  363. nodePush(parse_state, $$);
  364. }
  365. | TOKEN_HULL
  366. {
  367. $$ = nodeCreate(parse_state->memContext, NT_CodeHull);
  368. nodePush(parse_state, $$);
  369. }
  370. | TOKEN_DOMAIN
  371. {
  372. $$ = nodeCreate(parse_state->memContext, NT_CodeDomain);
  373. nodePush(parse_state, $$);
  374. }
  375. | TOKEN_COMPUTE
  376. {
  377. $$ = nodeCreate(parse_state->memContext, NT_CodeCompute);
  378. nodePush(parse_state, $$);
  379. }
  380. | TOKEN_COMMON
  381. {
  382. $$ = nodeCreate(parse_state->memContext, NT_CodeCommon);
  383. nodePush(parse_state, $$);
  384. }
  385. ;
  386. /* Stencil op */
  387. stencil_op_front_header
  388. : TOKEN_STENCILOPFRONT '='
  389. {
  390. $$ = nodeCreate(parse_state->memContext, NT_StencilOp);
  391. nodePush(parse_state, $$);
  392. }
  393. ;
  394. stencil_op_back_header
  395. : TOKEN_STENCILOPBACK '='
  396. {
  397. $$ = nodeCreate(parse_state->memContext, NT_StencilOp);
  398. nodePush(parse_state, $$);
  399. }
  400. ;
  401. stencil_op_body_init
  402. : TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_COMPFUNCVALUE
  403. {
  404. NodeOption fail; fail.type = OT_Fail; fail.value.intValue = $1;
  405. NodeOption zfail; zfail.type = OT_ZFail; zfail.value.intValue = $3;
  406. NodeOption pass; pass.type = OT_PassOp; pass.value.intValue = $5;
  407. NodeOption cmp; cmp.type = OT_CompareFunc; cmp.value.intValue = $7;
  408. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &fail);
  409. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &zfail);
  410. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &pass);
  411. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &cmp);
  412. }
  413. ;
  414. stencil_op_body
  415. : /* empty */
  416. | stencil_op_option stencil_op_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  417. ;
  418. stencil_op_option
  419. : TOKEN_FAIL '=' TOKEN_OPVALUE ';' { $$.type = OT_Fail; $$.value.intValue = $3; }
  420. | TOKEN_ZFAIL '=' TOKEN_OPVALUE ';' { $$.type = OT_ZFail; $$.value.intValue = $3; }
  421. | TOKEN_PASS '=' TOKEN_OPVALUE ';' { $$.type = OT_PassOp; $$.value.intValue = $3; }
  422. | TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';' { $$.type = OT_CompareFunc; $$.value.intValue = $3; }
  423. ;
  424. /* Target */
  425. target
  426. : target_header '{' target_body '}' ';' { nodePop(parse_state); $$ = $1; }
  427. ;
  428. target_header
  429. : TOKEN_TARGET
  430. {
  431. $$ = nodeCreate(parse_state->memContext, NT_Target);
  432. nodePush(parse_state, $$);
  433. }
  434. ;
  435. target_body
  436. : /* empty */
  437. | target_statement target_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  438. ;
  439. target_statement
  440. : target_option
  441. ;
  442. target_option
  443. : TOKEN_INDEX '=' TOKEN_INTEGER ';' { $$.type = OT_Index; $$.value.intValue = $3; }
  444. | TOKEN_ENABLED '=' TOKEN_BOOLEAN ';' { $$.type = OT_Enabled; $$.value.intValue = $3; }
  445. | blend_color_header '{' blenddef_body '}' ';' { nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
  446. | blend_alpha_header '{' blenddef_body '}' ';' { nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
  447. | blend_color_header '{' blenddef_body_init '}' ';' { nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
  448. | blend_alpha_header '{' blenddef_body_init '}' ';' { nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
  449. | TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';' { $$.type = OT_WriteMask; $$.value.intValue = $3; }
  450. ;
  451. /* Blend definition */
  452. blend_color_header
  453. : TOKEN_COLOR '='
  454. {
  455. $$ = nodeCreate(parse_state->memContext, NT_BlendDef);
  456. nodePush(parse_state, $$);
  457. }
  458. ;
  459. blend_alpha_header
  460. : TOKEN_ALPHA '='
  461. {
  462. $$ = nodeCreate(parse_state->memContext, NT_BlendDef);
  463. nodePush(parse_state, $$);
  464. }
  465. ;
  466. blenddef_body
  467. : /* empty */
  468. | blenddef_option blenddef_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  469. ;
  470. blenddef_body_init
  471. : TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_BLENDOPVALUE
  472. {
  473. NodeOption src; src.type = OT_Source; src.value.intValue = $1;
  474. NodeOption dst; dst.type = OT_Dest; dst.value.intValue = $3;
  475. NodeOption op; op.type = OT_Op; op.value.intValue = $5;
  476. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &src);
  477. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &dst);
  478. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &op);
  479. }
  480. ;
  481. blenddef_option
  482. : TOKEN_SOURCE '=' TOKEN_OPVALUE ';' { $$.type = OT_Source; $$.value.intValue = $3; }
  483. | TOKEN_DEST '=' TOKEN_OPVALUE ';' { $$.type = OT_Dest; $$.value.intValue = $3; }
  484. | TOKEN_OP '=' TOKEN_BLENDOPVALUE ';' { $$.type = OT_Op; $$.value.intValue = $3; }
  485. ;
  486. %%
  487. void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const char *msg)
  488. {
  489. parse_state->hasError = 1;
  490. parse_state->errorLine = locp->first_line;
  491. parse_state->errorColumn = locp->first_column;
  492. parse_state->errorMessage = mmalloc_strdup(parse_state->memContext, msg);
  493. parse_state->errorFile = locp->filename;
  494. }