BsParserFX.y 19 KB

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