BsParserFX.y 18 KB

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