BsParserFX.y 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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. %token <intValue> TOKEN_FILLMODEVALUE
  65. %token <intValue> TOKEN_CULLMODEVALUE
  66. %token <intValue> TOKEN_COMPFUNCVALUE
  67. %token <intValue> TOKEN_OPVALUE
  68. %token <intValue> TOKEN_COLORMASK
  69. %token <intValue> TOKEN_BLENDOPVALUE
  70. %token <intValue> TOKEN_QUEUETYPE
  71. /* Qualifiers */
  72. %token TOKEN_BASE TOKEN_INHERITS
  73. /* Shader keywords */
  74. %token TOKEN_SEPARABLE TOKEN_SORT TOKEN_PRIORITY TOKEN_TRANSPARENT
  75. %token TOKEN_TECHNIQUE
  76. /* Technique keywords */
  77. %token TOKEN_RENDERER TOKEN_PASS TOKEN_TAGS
  78. /* Pass keywords */
  79. %token TOKEN_VERTEX TOKEN_FRAGMENT TOKEN_GEOMETRY TOKEN_HULL TOKEN_DOMAIN TOKEN_COMPUTE TOKEN_COMMON
  80. %token TOKEN_STENCILREF
  81. %token TOKEN_FILLMODE TOKEN_CULLMODE TOKEN_DEPTHBIAS TOKEN_SDEPTHBIAS
  82. %token TOKEN_DEPTHCLIP TOKEN_SCISSOR TOKEN_MULTISAMPLE TOKEN_AALINE
  83. %token TOKEN_DEPTHREAD TOKEN_DEPTHWRITE TOKEN_COMPAREFUNC TOKEN_STENCIL
  84. %token TOKEN_STENCILREADMASK TOKEN_STENCILWRITEMASK TOKEN_STENCILOPFRONT TOKEN_STENCILOPBACK
  85. %token TOKEN_FAIL TOKEN_ZFAIL
  86. %token TOKEN_ALPHATOCOVERAGE TOKEN_INDEPENDANTBLEND TOKEN_TARGET TOKEN_INDEX
  87. %token TOKEN_BLEND TOKEN_COLOR TOKEN_ALPHA TOKEN_WRITEMASK
  88. %token TOKEN_SOURCE TOKEN_DEST TOKEN_OP
  89. %type <nodePtr> shader;
  90. %type <nodeOption> shader_statement;
  91. %type <nodeOption> shader_option;
  92. %type <nodePtr> technique;
  93. %type <nodePtr> technique_header;
  94. %type <nodeOption> technique_statement;
  95. %type <nodeOption> technique_option;
  96. %type <nodePtr> tags;
  97. %type <nodePtr> tags_header;
  98. %type <nodePtr> pass;
  99. %type <nodePtr> pass_header;
  100. %type <nodeOption> pass_statement;
  101. %type <nodeOption> pass_option;
  102. %type <nodePtr> code;
  103. %type <nodePtr> code_header;
  104. %type <nodePtr> stencil_op_front_header;
  105. %type <nodePtr> stencil_op_back_header;
  106. %type <nodeOption> stencil_op_option;
  107. %type <nodePtr> target;
  108. %type <nodePtr> target_header;
  109. %type <nodeOption> target_statement;
  110. %type <nodeOption> target_option;
  111. %type <nodePtr> blend_color_header;
  112. %type <nodePtr> blend_alpha_header;
  113. %type <nodeOption> blenddef_option;
  114. %type <nodeOption> technique_qualifier
  115. %%
  116. /* Shader */
  117. shader
  118. : /* empty */ { }
  119. | shader_statement shader { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  120. ;
  121. shader_statement
  122. : shader_option
  123. | technique { $$.type = OT_Technique; $$.value.nodePtr = $1; }
  124. ;
  125. shader_option
  126. : TOKEN_SEPARABLE '=' TOKEN_BOOLEAN ';' { $$.type = OT_Separable; $$.value.intValue = $3; }
  127. | TOKEN_SORT '=' TOKEN_QUEUETYPE ';' { $$.type = OT_Sort; $$.value.intValue = $3; }
  128. | TOKEN_PRIORITY '=' TOKEN_INTEGER ';' { $$.type = OT_Priority; $$.value.intValue = $3; }
  129. | TOKEN_TRANSPARENT '=' TOKEN_BOOLEAN ';' { $$.type = OT_Transparent; $$.value.intValue = $3; }
  130. ;
  131. /* Technique */
  132. technique
  133. : technique_header technique_qualifier_list '=' '{' technique_body '}' ';' { nodePop(parse_state); $$ = $1; }
  134. ;
  135. technique_header
  136. : TOKEN_TECHNIQUE
  137. {
  138. $$ = nodeCreate(parse_state->memContext, NT_Technique);
  139. nodePush(parse_state, $$);
  140. }
  141. ;
  142. technique_body
  143. : /* empty */
  144. | technique_statement technique_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  145. ;
  146. technique_statement
  147. : technique_option
  148. | pass { $$.type = OT_Pass; $$.value.nodePtr = $1; }
  149. | pass_option
  150. | code { $$.type = OT_Code; $$.value.nodePtr = $1; }
  151. ;
  152. technique_option
  153. : TOKEN_RENDERER '=' TOKEN_STRING ';' { $$.type = OT_Renderer; $$.value.strValue = $3; }
  154. | tags { $$.type = OT_Tags; $$.value.nodePtr = $1; }
  155. ;
  156. /* Technique tags */
  157. tags
  158. : tags_header '{' tags_body '}' ';' { nodePop(parse_state); $$ = $1; }
  159. ;
  160. tags_header
  161. : TOKEN_TAGS '='
  162. {
  163. $$ = nodeCreate(parse_state->memContext, NT_Tags);
  164. nodePush(parse_state, $$);
  165. }
  166. ;
  167. tags_body
  168. : /* empty */
  169. | TOKEN_STRING
  170. {
  171. NodeOption entry; entry.type = OT_TagValue; entry.value.strValue = $1;
  172. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &entry);
  173. }
  174. | TOKEN_STRING ',' tags_body
  175. {
  176. NodeOption entry; entry.type = OT_TagValue; entry.value.strValue = $1;
  177. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &entry);
  178. }
  179. ;
  180. /* Technique qualifiers */
  181. technique_qualifier_list
  182. : /* empty */
  183. | technique_qualifier technique_qualifier_list { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  184. ;
  185. technique_qualifier
  186. : ':' TOKEN_BASE '(' TOKEN_STRING ')' { $$.type = OT_Base; $$.value.strValue = $4; }
  187. | ':' TOKEN_INHERITS '(' TOKEN_STRING ')' { $$.type = OT_Inherits; $$.value.strValue = $4; }
  188. ;
  189. /* Pass */
  190. pass
  191. : pass_header '{' pass_body '}' ';' { nodePop(parse_state); $$ = $1; }
  192. ;
  193. pass_header
  194. : TOKEN_PASS '='
  195. {
  196. $$ = nodeCreate(parse_state->memContext, NT_Pass);
  197. nodePush(parse_state, $$);
  198. }
  199. ;
  200. pass_body
  201. : /* empty */
  202. | pass_statement pass_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  203. ;
  204. pass_statement
  205. : pass_option
  206. | code { $$.type = OT_Code; $$.value.nodePtr = $1; }
  207. ;
  208. pass_option
  209. : TOKEN_INDEX '=' TOKEN_INTEGER ';' { $$.type = OT_Index; $$.value.intValue = $3; }
  210. | TOKEN_FILLMODE '=' TOKEN_FILLMODEVALUE ';' { $$.type = OT_FillMode; $$.value.intValue = $3; }
  211. | TOKEN_CULLMODE '=' TOKEN_CULLMODEVALUE ';' { $$.type = OT_CullMode; $$.value.intValue = $3; }
  212. | TOKEN_DEPTHBIAS '=' TOKEN_FLOAT ';' { $$.type = OT_DepthBias; $$.value.floatValue = $3; }
  213. | TOKEN_SDEPTHBIAS '=' TOKEN_FLOAT ';' { $$.type = OT_SDepthBias; $$.value.floatValue = $3; }
  214. | TOKEN_DEPTHCLIP '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthClip; $$.value.intValue = $3; }
  215. | TOKEN_SCISSOR '=' TOKEN_BOOLEAN ';' { $$.type = OT_Scissor; $$.value.intValue = $3; }
  216. | TOKEN_MULTISAMPLE '=' TOKEN_BOOLEAN ';' { $$.type = OT_Multisample; $$.value.intValue = $3; }
  217. | TOKEN_AALINE '=' TOKEN_BOOLEAN ';' { $$.type = OT_AALine; $$.value.intValue = $3; }
  218. | TOKEN_DEPTHREAD '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthRead; $$.value.intValue = $3; }
  219. | TOKEN_DEPTHWRITE '=' TOKEN_BOOLEAN ';' { $$.type = OT_DepthWrite; $$.value.intValue = $3; }
  220. | TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';' { $$.type = OT_CompareFunc; $$.value.intValue = $3; }
  221. | TOKEN_STENCIL '=' TOKEN_BOOLEAN ';' { $$.type = OT_Stencil; $$.value.intValue = $3; }
  222. | TOKEN_STENCILREADMASK '=' TOKEN_INTEGER ';' { $$.type = OT_StencilReadMask; $$.value.intValue = $3; }
  223. | TOKEN_STENCILWRITEMASK '=' TOKEN_INTEGER ';' { $$.type = OT_StencilWriteMask; $$.value.intValue = $3; }
  224. | stencil_op_front_header '{' stencil_op_body '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
  225. | stencil_op_back_header '{' stencil_op_body '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
  226. | stencil_op_front_header '{' stencil_op_body_init '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
  227. | stencil_op_back_header '{' stencil_op_body_init '}' ';' { nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
  228. | TOKEN_ALPHATOCOVERAGE '=' TOKEN_BOOLEAN ';' { $$.type = OT_AlphaToCoverage; $$.value.intValue = $3; }
  229. | TOKEN_INDEPENDANTBLEND '=' TOKEN_BOOLEAN ';' { $$.type = OT_IndependantBlend; $$.value.intValue = $3; }
  230. | target { $$.type = OT_Target; $$.value.nodePtr = $1; }
  231. | TOKEN_STENCILREF '=' TOKEN_INTEGER ';' { $$.type = OT_StencilRef; $$.value.intValue = $3; }
  232. ;
  233. /* Code blocks */
  234. code
  235. : code_header '{' TOKEN_INDEX '=' TOKEN_INTEGER ';' '}' ';'
  236. {
  237. NodeOption index;
  238. index.type = OT_Index;
  239. index.value.intValue = $5;
  240. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &index);
  241. nodePop(parse_state);
  242. $$ = $1;
  243. }
  244. ;
  245. code_header
  246. : TOKEN_VERTEX '='
  247. {
  248. $$ = nodeCreate(parse_state->memContext, NT_CodeVertex);
  249. nodePush(parse_state, $$);
  250. }
  251. | TOKEN_FRAGMENT '='
  252. {
  253. $$ = nodeCreate(parse_state->memContext, NT_CodeFragment);
  254. nodePush(parse_state, $$);
  255. }
  256. | TOKEN_GEOMETRY '='
  257. {
  258. $$ = nodeCreate(parse_state->memContext, NT_CodeGeometry);
  259. nodePush(parse_state, $$);
  260. }
  261. | TOKEN_HULL '='
  262. {
  263. $$ = nodeCreate(parse_state->memContext, NT_CodeHull);
  264. nodePush(parse_state, $$);
  265. }
  266. | TOKEN_DOMAIN '='
  267. {
  268. $$ = nodeCreate(parse_state->memContext, NT_CodeDomain);
  269. nodePush(parse_state, $$);
  270. }
  271. | TOKEN_COMPUTE '='
  272. {
  273. $$ = nodeCreate(parse_state->memContext, NT_CodeCompute);
  274. nodePush(parse_state, $$);
  275. }
  276. | TOKEN_COMMON '='
  277. {
  278. $$ = nodeCreate(parse_state->memContext, NT_CodeCommon);
  279. nodePush(parse_state, $$);
  280. }
  281. ;
  282. /* Stencil op */
  283. stencil_op_front_header
  284. : TOKEN_STENCILOPFRONT '='
  285. {
  286. $$ = nodeCreate(parse_state->memContext, NT_StencilOp);
  287. nodePush(parse_state, $$);
  288. }
  289. ;
  290. stencil_op_back_header
  291. : TOKEN_STENCILOPBACK '='
  292. {
  293. $$ = nodeCreate(parse_state->memContext, NT_StencilOp);
  294. nodePush(parse_state, $$);
  295. }
  296. ;
  297. stencil_op_body_init
  298. : TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_COMPFUNCVALUE
  299. {
  300. NodeOption fail; fail.type = OT_Fail; fail.value.intValue = $1;
  301. NodeOption zfail; zfail.type = OT_ZFail; zfail.value.intValue = $3;
  302. NodeOption pass; pass.type = OT_PassOp; pass.value.intValue = $5;
  303. NodeOption cmp; cmp.type = OT_CompareFunc; cmp.value.intValue = $7;
  304. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &fail);
  305. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &zfail);
  306. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &pass);
  307. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &cmp);
  308. }
  309. ;
  310. stencil_op_body
  311. : /* empty */
  312. | stencil_op_option stencil_op_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  313. ;
  314. stencil_op_option
  315. : TOKEN_FAIL '=' TOKEN_OPVALUE ';' { $$.type = OT_Fail; $$.value.intValue = $3; }
  316. | TOKEN_ZFAIL '=' TOKEN_OPVALUE ';' { $$.type = OT_ZFail; $$.value.intValue = $3; }
  317. | TOKEN_PASS '=' TOKEN_OPVALUE ';' { $$.type = OT_PassOp; $$.value.intValue = $3; }
  318. | TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';' { $$.type = OT_CompareFunc; $$.value.intValue = $3; }
  319. ;
  320. /* Target */
  321. target
  322. : target_header '{' target_body '}' ';' { nodePop(parse_state); $$ = $1; }
  323. ;
  324. target_header
  325. : TOKEN_TARGET '='
  326. {
  327. $$ = nodeCreate(parse_state->memContext, NT_Target);
  328. nodePush(parse_state, $$);
  329. }
  330. ;
  331. target_body
  332. : /* empty */
  333. | target_statement target_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  334. ;
  335. target_statement
  336. : target_option
  337. ;
  338. target_option
  339. : TOKEN_INDEX '=' TOKEN_INTEGER ';' { $$.type = OT_Index; $$.value.intValue = $3; }
  340. | TOKEN_BLEND '=' TOKEN_BOOLEAN ';' { $$.type = OT_Blend; $$.value.intValue = $3; }
  341. | blend_color_header '{' blenddef_body '}' ';' { nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
  342. | blend_alpha_header '{' blenddef_body '}' ';' { nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
  343. | blend_color_header '{' blenddef_body_init '}' ';' { nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
  344. | blend_alpha_header '{' blenddef_body_init '}' ';' { nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
  345. | TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';' { $$.type = OT_WriteMask; $$.value.intValue = $3; }
  346. ;
  347. /* Blend definition */
  348. blend_color_header
  349. : TOKEN_COLOR '='
  350. {
  351. $$ = nodeCreate(parse_state->memContext, NT_BlendDef);
  352. nodePush(parse_state, $$);
  353. }
  354. ;
  355. blend_alpha_header
  356. : TOKEN_ALPHA '='
  357. {
  358. $$ = nodeCreate(parse_state->memContext, NT_BlendDef);
  359. nodePush(parse_state, $$);
  360. }
  361. ;
  362. blenddef_body
  363. : /* empty */
  364. | blenddef_option blenddef_body { nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
  365. ;
  366. blenddef_body_init
  367. : TOKEN_OPVALUE ',' TOKEN_OPVALUE ',' TOKEN_BLENDOPVALUE
  368. {
  369. NodeOption src; src.type = OT_Source; src.value.intValue = $1;
  370. NodeOption dst; dst.type = OT_Dest; dst.value.intValue = $3;
  371. NodeOption op; op.type = OT_Op; op.value.intValue = $5;
  372. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &src);
  373. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &dst);
  374. nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &op);
  375. }
  376. ;
  377. blenddef_option
  378. : TOKEN_SOURCE '=' TOKEN_OPVALUE ';' { $$.type = OT_Source; $$.value.intValue = $3; }
  379. | TOKEN_DEST '=' TOKEN_OPVALUE ';' { $$.type = OT_Dest; $$.value.intValue = $3; }
  380. | TOKEN_OP '=' TOKEN_BLENDOPVALUE ';' { $$.type = OT_Op; $$.value.intValue = $3; }
  381. ;
  382. %%
  383. void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const char *msg)
  384. {
  385. parse_state->hasError = 1;
  386. parse_state->errorLine = locp->first_line;
  387. parse_state->errorColumn = locp->first_column;
  388. parse_state->errorMessage = mmalloc_strdup(parse_state->memContext, msg);
  389. parse_state->errorFile = locp->filename;
  390. }