BsLexerFX.l 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. %{
  2. #include "BsParserFX.h"
  3. #define YY_USER_ACTION yylloc->first_column = yycolumn + 1; yylloc->first_line = yylineno + 1; yycolumn += (int)yyleng; yylloc->filename = getCurrentFilename(yyextra);
  4. #define YY_USER_INIT yylineno = 0; yycolumn = 0;
  5. %}
  6. %option yylineno reentrant noyywrap nounistd never-interactive warn nodefault bison-bridge bison-locations
  7. %option outfile="BsLexerFX.c" header-file="BsLexerFX.h"
  8. %option extra-type="struct tagParseState *"
  9. INTEGER -?[0-9][0-9]*
  10. INTEGER_16 0[xX][0-9a-fA-F]+
  11. FLOAT [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]?
  12. STRING \"[^"\n]*\"
  13. IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
  14. WS [ \r\n\t]*
  15. SPACE [ \t]
  16. SINGLEWS [ \r\n\t]
  17. ENDLINE [\r\n]
  18. COMMENT \/\/[^\n]*
  19. DEFINE_EXPR [^\r\n]*
  20. /* Start conditions */
  21. %x INCLUDE
  22. %x CODEBLOCK_HEADER
  23. %x CODEBLOCK
  24. %x CODEBLOCK_END
  25. %x DEFINE_COND
  26. %x DEFINE_COND_EXPR
  27. %x UNDEF_COND
  28. %x CONDITIONAL_IF
  29. %x CONDITIONAL_IFDEF
  30. %x CONDITIONAL_IFNDEF
  31. %x CONDITIONAL_ELIF
  32. %x CONDITIONAL_IGNORE
  33. %%
  34. {WS} { /* Skip blank */ }
  35. {INTEGER} { yylval->intValue = atoi(yytext); return TOKEN_INTEGER; }
  36. {INTEGER_16} { yylval->intValue = (int)strtol(yytext, 0, 0); return TOKEN_INTEGER; }
  37. {FLOAT} { yylval->floatValue = (float)atof(yytext); return TOKEN_FLOAT; }
  38. {STRING} { yylval->strValue = mmalloc_strdup(yyextra->memContext, yytext); return TOKEN_STRING; }
  39. true { yylval->intValue = 1; return TOKEN_BOOLEAN; }
  40. false { yylval->intValue = 0; return TOKEN_BOOLEAN; }
  41. /* Shader keywords */
  42. options { return TOKEN_OPTIONS; }
  43. technique { return TOKEN_TECHNIQUE; }
  44. mixin { return TOKEN_MIXIN; }
  45. /* Options keywords */
  46. separable { return TOKEN_SEPARABLE; }
  47. sort { return TOKEN_SORT; }
  48. priority { return TOKEN_PRIORITY; }
  49. transparent { return TOKEN_TRANSPARENT; }
  50. /* Technique keywords */
  51. renderer { return TOKEN_RENDERER; }
  52. tags { return TOKEN_TAGS; }
  53. pass { return TOKEN_PASS; }
  54. /* Pass keywords */
  55. blend { return TOKEN_BLEND; }
  56. raster { return TOKEN_RASTER; }
  57. depth { return TOKEN_DEPTH; }
  58. stencil { return TOKEN_STENCIL; }
  59. /* Rasterizer state keywords */
  60. fill { return TOKEN_FILLMODE; }
  61. cull { return TOKEN_CULLMODE; }
  62. scissor { return TOKEN_SCISSOR; }
  63. multisample { return TOKEN_MULTISAMPLE; }
  64. lineaa { return TOKEN_AALINE; }
  65. /* Depth state keywords */
  66. read { return TOKEN_DEPTHREAD; }
  67. write { return TOKEN_DEPTHWRITE; }
  68. compare { return TOKEN_COMPAREFUNC; }
  69. bias { return TOKEN_DEPTHBIAS; }
  70. scaledbias { return TOKEN_SDEPTHBIAS; }
  71. clip { return TOKEN_DEPTHCLIP; }
  72. /* Stencil state keywords */
  73. reference { return TOKEN_STENCILREF; }
  74. enabled { return TOKEN_ENABLED; }
  75. readmask { return TOKEN_READMASK; }
  76. writemask { return TOKEN_WRITEMASK; }
  77. front { return TOKEN_STENCILOPFRONT; }
  78. back { return TOKEN_STENCILOPBACK; }
  79. fail { return TOKEN_FAIL; }
  80. zfail { return TOKEN_ZFAIL; }
  81. /* Blend state keywords */
  82. dither { return TOKEN_ALPHATOCOVERAGE; }
  83. independant { return TOKEN_INDEPENDANTBLEND; }
  84. target { return TOKEN_TARGET; }
  85. index { return TOKEN_INDEX; }
  86. color { return TOKEN_COLOR; }
  87. alpha { return TOKEN_ALPHA; }
  88. source { return TOKEN_SOURCE; }
  89. dest { return TOKEN_DEST; }
  90. op { return TOKEN_OP; }
  91. /* State values */
  92. wire { yylval->intValue = FMV_Wire; return TOKEN_FILLMODEVALUE; }
  93. solid { yylval->intValue = FMV_Solid; return TOKEN_FILLMODEVALUE; }
  94. none { yylval->intValue = CASV_None; return TOKEN_CULLANDQUEUEVALUE; }
  95. cw { yylval->intValue = CASV_CW; return TOKEN_CULLANDQUEUEVALUE; }
  96. ccw { yylval->intValue = CASV_CCW; return TOKEN_CULLANDQUEUEVALUE; }
  97. fronttoback { yylval->intValue = CASV_FrontToBack; return TOKEN_CULLANDQUEUEVALUE; }
  98. backtofront { yylval->intValue = CASV_BackToFront; return TOKEN_CULLANDQUEUEVALUE; }
  99. never { yylval->intValue = CFV_Fail; return TOKEN_COMPFUNCVALUE; }
  100. always { yylval->intValue = CFV_Pass; return TOKEN_COMPFUNCVALUE; }
  101. lt { yylval->intValue = CFV_LT; return TOKEN_COMPFUNCVALUE; }
  102. lte { yylval->intValue = CFV_LTE; return TOKEN_COMPFUNCVALUE; }
  103. eq { yylval->intValue = CFV_EQ; return TOKEN_COMPFUNCVALUE; }
  104. neq { yylval->intValue = CFV_NEQ; return TOKEN_COMPFUNCVALUE; }
  105. gte { yylval->intValue = CFV_GTE; return TOKEN_COMPFUNCVALUE; }
  106. gt { yylval->intValue = CFV_GT; return TOKEN_COMPFUNCVALUE; }
  107. keep { yylval->intValue = OV_Keep; return TOKEN_OPVALUE; }
  108. zero { yylval->intValue = OV_Zero; return TOKEN_OPVALUE; }
  109. replace { yylval->intValue = OV_Replace; return TOKEN_OPVALUE; }
  110. inc { yylval->intValue = OV_Incr; return TOKEN_OPVALUE; }
  111. dec { yylval->intValue = OV_Decr; return TOKEN_OPVALUE; }
  112. incwrap { yylval->intValue = OV_IncrWrap; return TOKEN_OPVALUE; }
  113. decwrap { yylval->intValue = OV_DecrWrap; return TOKEN_OPVALUE; }
  114. inverse { yylval->intValue = OV_Invert; return TOKEN_OPVALUE; }
  115. one { yylval->intValue = OV_One; return TOKEN_OPVALUE; }
  116. dstRGB { yylval->intValue = OV_DestColor; return TOKEN_OPVALUE; }
  117. srcRGB { yylval->intValue = OV_SrcColor; return TOKEN_OPVALUE; }
  118. dstIRGB { yylval->intValue = OV_InvDestColor; return TOKEN_OPVALUE; }
  119. srcIRGB { yylval->intValue = OV_InvSrcColor; return TOKEN_OPVALUE; }
  120. dstA { yylval->intValue = OV_DestAlpha; return TOKEN_OPVALUE; }
  121. srcA { yylval->intValue = OV_SrcAlpha; return TOKEN_OPVALUE; }
  122. dstIA { yylval->intValue = OV_InvDestAlpha; return TOKEN_OPVALUE; }
  123. srcIA { yylval->intValue = OV_InvSrcAlpha; return TOKEN_OPVALUE; }
  124. add { yylval->intValue = BOV_Add; return TOKEN_BLENDOPVALUE; }
  125. sub { yylval->intValue = BOV_Subtract; return TOKEN_BLENDOPVALUE; }
  126. rsub { yylval->intValue = BOV_RevSubtract; return TOKEN_BLENDOPVALUE; }
  127. min { yylval->intValue = BOV_Min; return TOKEN_BLENDOPVALUE; }
  128. max { yylval->intValue = BOV_Max; return TOKEN_BLENDOPVALUE; }
  129. empty { yylval->intValue = 0x0; return TOKEN_COLORMASK; }
  130. R { yylval->intValue = 0x1; return TOKEN_COLORMASK; }
  131. G { yylval->intValue = 0x2; return TOKEN_COLORMASK; }
  132. B { yylval->intValue = 0x4; return TOKEN_COLORMASK; }
  133. A { yylval->intValue = 0x8; return TOKEN_COLORMASK; }
  134. RG { yylval->intValue = 0x3; return TOKEN_COLORMASK; }
  135. RB { yylval->intValue = 0x5; return TOKEN_COLORMASK; }
  136. RA { yylval->intValue = 0x9; return TOKEN_COLORMASK; }
  137. GB { yylval->intValue = 0x6; return TOKEN_COLORMASK; }
  138. GA { yylval->intValue = 0xA; return TOKEN_COLORMASK; }
  139. BA { yylval->intValue = 0xC; return TOKEN_COLORMASK; }
  140. RGB { yylval->intValue = 0x7; return TOKEN_COLORMASK; }
  141. RGA { yylval->intValue = 0xB; return TOKEN_COLORMASK; }
  142. RBA { yylval->intValue = 0xD; return TOKEN_COLORMASK; }
  143. GBA { yylval->intValue = 0xE; return TOKEN_COLORMASK; }
  144. RGBA { yylval->intValue = 0xF; return TOKEN_COLORMASK; }
  145. /* Preprocessor */
  146. #include { BEGIN(INCLUDE); }
  147. <INCLUDE>{WS} { /* Skip blank */ }
  148. <INCLUDE>{STRING} {
  149. int size = 0;
  150. char* includeBuffer = includePush(yyextra, yytext, yylineno, yycolumn, &size);
  151. if(!includeBuffer)
  152. yyterminate();
  153. YY_BUFFER_STATE currentBuffer = YY_CURRENT_BUFFER;
  154. YY_BUFFER_STATE newBuffer = yy_scan_buffer(includeBuffer, size, yyscanner);
  155. yy_switch_to_buffer(currentBuffer, yyscanner);
  156. yypush_buffer_state(newBuffer, yyscanner);
  157. yylineno = 0;
  158. yycolumn = 0;
  159. BEGIN(INITIAL);
  160. }
  161. <INCLUDE>. { return yytext[0]; }
  162. <<EOF>> {
  163. if(!yyextra->includeStack)
  164. yyterminate();
  165. yypop_buffer_state(yyscanner);
  166. includePop(yyextra);
  167. }
  168. #define { BEGIN(DEFINE_COND); }
  169. <DEFINE_COND>{SPACE} { /* Skip blank */ }
  170. <DEFINE_COND>{IDENTIFIER} { addDefine(yyextra, yytext); BEGIN(DEFINE_COND_EXPR); }
  171. <DEFINE_COND>{ENDLINE} { BEGIN(INITIAL); }
  172. <DEFINE_COND>. { return yytext[0]; }
  173. <DEFINE_COND_EXPR>{DEFINE_EXPR} { addDefineExpr(yyextra, yytext); BEGIN(INITIAL); }
  174. <DEFINE_COND_EXPR>{ENDLINE} { BEGIN(INITIAL); }
  175. #undef { BEGIN(UNDEF_COND); }
  176. <UNDEF_COND>{WS} { /* Skip blank */ }
  177. <UNDEF_COND>{IDENTIFIER} { removeDefine(yyextra, yytext); BEGIN(INITIAL); }
  178. <UNDEF_COND>. { return yytext[0]; }
  179. #if { BEGIN(CONDITIONAL_IF); }
  180. <CONDITIONAL_IF>{WS} { /* Skip blank */ }
  181. <CONDITIONAL_IF>{IDENTIFIER} {
  182. int isEnabled = pushConditional(yyextra, isDefineEnabled(yyextra, yytext));
  183. if(!isEnabled)
  184. BEGIN(CONDITIONAL_IGNORE);
  185. else
  186. BEGIN(INITIAL);
  187. }
  188. <CONDITIONAL_IF>.
  189. #ifdef { BEGIN(CONDITIONAL_IFDEF); }
  190. <CONDITIONAL_IFDEF>{WS} { /* Skip blank */ }
  191. <CONDITIONAL_IFDEF>{IDENTIFIER} {
  192. int isEnabled = pushConditional(yyextra, hasDefine(yyextra, yytext));
  193. if(!isEnabled)
  194. BEGIN(CONDITIONAL_IGNORE);
  195. else
  196. BEGIN(INITIAL);
  197. }
  198. <CONDITIONAL_IFDEF>. { return yytext[0]; }
  199. #ifndef { BEGIN(CONDITIONAL_IFNDEF); }
  200. <CONDITIONAL_IFNDEF>{WS} { /* Skip blank */ }
  201. <CONDITIONAL_IFNDEF>{IDENTIFIER} {
  202. int isEnabled = pushConditional(yyextra, !hasDefine(yyextra, yytext));
  203. if(!isEnabled)
  204. BEGIN(CONDITIONAL_IGNORE);
  205. else
  206. BEGIN(INITIAL);
  207. }
  208. <CONDITIONAL_IFNDEF>. { return yytext[0]; }
  209. #else {
  210. if(!switchConditional(yyextra))
  211. BEGIN(CONDITIONAL_IGNORE);
  212. }
  213. #elif { BEGIN(CONDITIONAL_IGNORE); }
  214. #endif { popConditional(yyextra); }
  215. <CONDITIONAL_IGNORE>{WS} { /* Skip */ }
  216. <CONDITIONAL_IGNORE>#ifdef { pushConditional(yyextra, 0); }
  217. <CONDITIONAL_IGNORE>#ifndef { pushConditional(yyextra, 0); }
  218. <CONDITIONAL_IGNORE>#else {
  219. if(switchConditional(yyextra))
  220. BEGIN(INITIAL);
  221. }
  222. <CONDITIONAL_IGNORE>#elif { BEGIN(CONDITIONAL_ELIF); }
  223. <CONDITIONAL_IGNORE>#endif {
  224. if(popConditional(yyextra))
  225. BEGIN(INITIAL);
  226. }
  227. <CONDITIONAL_IGNORE>. { /* Skip */ }
  228. <CONDITIONAL_ELIF>{WS} { /* Skip blank */ }
  229. <CONDITIONAL_ELIF>{IDENTIFIER} {
  230. int isEnabled = setConditional(yyextra, hasDefine(yyextra, yytext));
  231. if(!isEnabled)
  232. BEGIN(CONDITIONAL_IGNORE);
  233. else
  234. BEGIN(INITIAL);
  235. }
  236. <CONDITIONAL_ELIF>. { return yytext[0]; }
  237. /* Code block */
  238. code { BEGIN(CODEBLOCK_HEADER); return TOKEN_CODE; }
  239. /* Track when the code block begins, insert all code block characters into our own buffer, record a sequential index */
  240. /* of all code blocks in the text, and track bracket open/closed state so we know when we're done with the code block. */
  241. /* And finally output a sequential code block index to the parser (it shouldn't be aware of anything else in the block). */
  242. <CODEBLOCK_HEADER>\{ { BEGIN(CODEBLOCK); beginCodeBlock(yyextra); yyextra->numOpenBrackets = 1; return yytext[0]; }
  243. <CODEBLOCK_HEADER>{WS} { /* Skip blank */ }
  244. <CODEBLOCK_HEADER>. { return yytext[0]; }
  245. <CODEBLOCK>\{ { yyextra->numOpenBrackets++; appendCodeBlock(yyextra, yytext, 1); }
  246. <CODEBLOCK>\} {
  247. yyextra->numOpenBrackets--;
  248. if(yyextra->numOpenBrackets == 0)
  249. {
  250. BEGIN(CODEBLOCK_END);
  251. unput('0');
  252. }
  253. else
  254. appendCodeBlock(yyextra, yytext, 1);
  255. }
  256. <CODEBLOCK>.|{SINGLEWS} { appendCodeBlock(yyextra, yytext, 1); }
  257. /* Logic for manually inserting "Index = codeBlockIndex;". We insert arbitrary numbers which allows us to sequentially */
  258. /* output all the tokens we need. We use only single-character values so we don't override anything in the text buffer */
  259. /* (since the starting value was also a single character "{"). */
  260. <CODEBLOCK_END>0 { unput('1'); return TOKEN_INDEX; }
  261. <CODEBLOCK_END>1 { unput('2'); return '='; }
  262. <CODEBLOCK_END>2 { yylval->intValue = getCodeBlockIndex(yyextra); unput('3'); return TOKEN_INTEGER; }
  263. <CODEBLOCK_END>3 { unput('4'); return ';'; }
  264. <CODEBLOCK_END>4 { BEGIN(INITIAL); return '}'; }
  265. <CODEBLOCK_END>.|{WS} { /* Never reached */ }
  266. /* Catch all rules */
  267. {COMMENT} { }
  268. {IDENTIFIER} { yylval->strValue = mmalloc_strdup(yyextra->memContext, yytext); return TOKEN_IDENTIFIER; }
  269. . { return yytext[0]; }
  270. %%