Skip to content

Latest commit

 

History

History
276 lines (245 loc) · 9.08 KB

mojoshader_lexer.re

File metadata and controls

276 lines (245 loc) · 9.08 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
/**
* MojoShader; generate shader programs from bytecode of compiled
* Direct3D shaders.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
// This was originally based on examples/pp-c.re from re2c: http://re2c.org/
// re2c is public domain code.
//
Sep 27, 2015
Sep 27, 2015
13
14
// You build mojoshader_lexer.c from the .re file with re2c...
// re2c -is -o mojoshader_lexer.c mojoshader_lexer.re
15
16
17
18
19
20
21
22
23
24
25
26
//
// Changes to the lexer are done to the .re file, not the C code!
//
// Please note that this isn't a perfect C lexer, since it is used for both
// HLSL and shader assembly language, and follows the quirks of Microsoft's
// tools.
#define __MOJOSHADER_INTERNAL__ 1
#include "mojoshader_internal.h"
typedef unsigned char uchar;
Feb 17, 2009
Feb 17, 2009
27
/*!max:re2c */
Nov 15, 2009
Nov 15, 2009
28
#define RET(t) return update_state(s, eoi, cursor, token, (Token) t)
29
30
31
32
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT limit
#define YYMARKER s->lexer_marker
Feb 17, 2009
Feb 17, 2009
33
#define YYFILL(n) { if ((n) == 1) { cursor = sentinel; limit = cursor + YYMAXFILL; eoi = 1; } }
Feb 17, 2009
Feb 17, 2009
35
36
static uchar sentinel[YYMAXFILL];
Feb 18, 2009
Feb 18, 2009
37
38
static Token update_state(IncludeState *s, int eoi, const uchar *cur,
const uchar *tok, const Token val)
Feb 17, 2009
Feb 17, 2009
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
if (eoi)
{
s->bytes_left = 0;
s->source = (const char *) s->source_base + s->orig_length;
if ( (tok >= sentinel) && (tok < (sentinel+YYMAXFILL)) )
s->token = s->source;
else
s->token = (const char *) tok;
} // if
else
{
s->bytes_left -= (unsigned int) (cur - ((const uchar *) s->source));
s->source = (const char *) cur;
s->token = (const char *) tok;
} // else
Feb 18, 2009
Feb 18, 2009
55
s->tokenlen = (unsigned int) (s->source - s->token);
Feb 18, 2009
Feb 18, 2009
56
57
s->tokenval = val;
return val;
58
59
} // update_state
Feb 18, 2009
Feb 18, 2009
60
Token preprocessor_lexer(IncludeState *s)
61
62
{
const uchar *cursor = (const uchar *) s->source;
Feb 22, 2009
Feb 22, 2009
63
const uchar *token = cursor;
Feb 13, 2009
Feb 13, 2009
64
const uchar *matchptr;
65
const uchar *limit = cursor + s->bytes_left;
Feb 17, 2009
Feb 17, 2009
66
int eoi = 0;
67
68
/*!re2c
Feb 13, 2009
Feb 13, 2009
69
ANY = [\000-\377];
Feb 13, 2009
Feb 13, 2009
70
ANYLEGAL = [a-zA-Z0-9_/'*=+%^&|!#<>()[{}.,~^:;? \t\v\f\r\n\-\]\\];
71
72
73
74
75
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
Nov 22, 2010
Nov 22, 2010
76
FS = [fFhH];
77
78
79
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
PP = "#" [ \t]*;
Feb 13, 2009
Feb 13, 2009
80
NEWLINE = ("\r\n" | "\r" | "\n");
81
82
83
WHITESPACE = [ \t\v\f]+;
*/
Feb 22, 2009
Feb 22, 2009
84
85
86
87
88
89
90
91
// preprocessor directives are only valid at start of line.
if (s->tokenval == ((Token) '\n'))
goto ppdirective; // may jump back to scanner_loop.
scanner_loop:
if (YYLIMIT == YYCURSOR) YYFILL(1);
token = cursor;
Feb 15, 2009
Feb 15, 2009
93
94
"\\" [ \t\v\f]* NEWLINE { s->line++; goto scanner_loop; }
95
96
97
98
99
100
"/*" { goto multilinecomment; }
"//" { goto singlelinecomment; }
L (L|D)* { RET(TOKEN_IDENTIFIER); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
Feb 13, 2009
Feb 13, 2009
101
(['] (ESC|ANY\[\r\n\\'])* ['])
102
103
104
105
106
{ RET(TOKEN_INT_LITERAL); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(TOKEN_FLOAT_LITERAL); }
Feb 13, 2009
Feb 13, 2009
107
(["] (ESC|ANY\[\r\n\\"])* ["])
108
{ RET(TOKEN_STRING_LITERAL); }
Feb 15, 2009
Feb 15, 2009
109
Feb 12, 2009
Feb 12, 2009
110
111
112
113
114
115
116
117
118
119
120
121
">>=" { RET(TOKEN_RSHIFTASSIGN); }
"<<=" { RET(TOKEN_LSHIFTASSIGN); }
"+=" { RET(TOKEN_ADDASSIGN); }
"-=" { RET(TOKEN_SUBASSIGN); }
"*=" { RET(TOKEN_MULTASSIGN); }
"/=" { RET(TOKEN_DIVASSIGN); }
"%=" { RET(TOKEN_MODASSIGN); }
"^=" { RET(TOKEN_XORASSIGN); }
"&=" { RET(TOKEN_ANDASSIGN); }
"|=" { RET(TOKEN_ORASSIGN); }
"++" { RET(TOKEN_INCREMENT); }
"--" { RET(TOKEN_DECREMENT); }
122
123
124
125
126
127
128
129
">>" { RET(TOKEN_RSHIFT); }
"<<" { RET(TOKEN_LSHIFT); }
"&&" { RET(TOKEN_ANDAND); }
"||" { RET(TOKEN_OROR); }
"<=" { RET(TOKEN_LEQ); }
">=" { RET(TOKEN_GEQ); }
"==" { RET(TOKEN_EQL); }
"!=" { RET(TOKEN_NEQ); }
Feb 25, 2010
Feb 25, 2010
130
"#" { RET(TOKEN_HASH); }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"##" { RET(TOKEN_HASHHASH); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"," { RET(','); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
":" { RET(':'); }
"{" { RET('{'); }
"}" { RET('}'); }
"=" { RET('='); }
"?" { RET('?'); }
Feb 24, 2009
Feb 24, 2009
156
157
";" { if (s->asm_comments) goto singlelinecomment; RET(';'); }
Feb 17, 2009
Feb 17, 2009
158
159
"\000" { if (eoi) { RET(TOKEN_EOI); } goto bad_chars; }
Feb 17, 2009
Feb 17, 2009
160
WHITESPACE { if (s->report_whitespace) RET(' '); goto scanner_loop; }
Feb 12, 2009
Feb 12, 2009
161
NEWLINE { s->line++; RET('\n'); }
Feb 13, 2009
Feb 13, 2009
162
ANY { goto bad_chars; }
163
164
165
*/
multilinecomment:
Feb 17, 2009
Feb 17, 2009
166
if (YYLIMIT == YYCURSOR) YYFILL(1);
Feb 13, 2009
Feb 13, 2009
167
matchptr = cursor;
168
169
// The "*\/" is just to avoid screwing up text editor syntax highlighting.
/*!re2c
Feb 12, 2009
Feb 12, 2009
170
"*\/" {
Feb 14, 2013
Feb 14, 2013
171
172
if (s->report_comments)
RET(TOKEN_MULTI_COMMENT);
Feb 17, 2009
Feb 17, 2009
173
174
else if (s->report_whitespace)
RET(' ');
Oct 2, 2014
Oct 2, 2014
175
176
177
178
179
180
181
182
183
184
185
186
// Microsoft's preprocessor allows multiline comments
// before a preprocessor directive, even though C/C++
// doesn't. See if we've hit this case.
#if MATCH_MICROSOFT_PREPROCESSOR
if (s->tokenval == ((Token) '\n')) // was start of line?
{
update_state(s, eoi, cursor, token, (Token) '\n');
goto ppdirective; // may jump back to scanner_loop.
}
#endif
Feb 12, 2009
Feb 12, 2009
187
188
189
190
191
192
goto scanner_loop;
}
NEWLINE {
s->line++;
goto multilinecomment;
}
Feb 17, 2009
Feb 17, 2009
193
194
195
196
197
"\000" {
if (eoi)
RET(TOKEN_INCOMPLETE_COMMENT);
goto multilinecomment;
}
Feb 13, 2009
Feb 13, 2009
198
ANY { goto multilinecomment; }
199
200
201
*/
singlelinecomment:
Feb 17, 2009
Feb 17, 2009
202
if (YYLIMIT == YYCURSOR) YYFILL(1);
Feb 13, 2009
Feb 13, 2009
203
matchptr = cursor;
204
/*!re2c
Feb 14, 2013
Feb 14, 2013
205
206
207
NEWLINE {
s->line++;
if (s->report_comments)
Feb 15, 2013
Feb 15, 2013
208
209
{
cursor = matchptr; // so we RET('\n') next.
Feb 14, 2013
Feb 14, 2013
210
RET(TOKEN_SINGLE_COMMENT);
Feb 15, 2013
Feb 15, 2013
211
}
Feb 14, 2013
Feb 14, 2013
212
213
214
215
216
217
218
219
220
221
222
223
224
token = matchptr;
RET('\n');
}
"\000" {
if (eoi)
{
if (s->report_comments)
RET(TOKEN_SINGLE_COMMENT);
else
RET(TOKEN_EOI);
}
goto singlelinecomment;
}
Feb 13, 2009
Feb 13, 2009
225
ANY { goto singlelinecomment; }
Feb 22, 2009
Feb 22, 2009
228
229
230
231
232
233
234
235
236
237
238
239
240
241
ppdirective:
if (YYLIMIT == YYCURSOR) YYFILL(1);
/*!re2c
PP "include" { RET(TOKEN_PP_INCLUDE); }
PP "line" { RET(TOKEN_PP_LINE); }
PP "define" { RET(TOKEN_PP_DEFINE); }
PP "undef" { RET(TOKEN_PP_UNDEF); }
PP "if" { RET(TOKEN_PP_IF); }
PP "ifdef" { RET(TOKEN_PP_IFDEF); }
PP "ifndef" { RET(TOKEN_PP_IFNDEF); }
PP "else" { RET(TOKEN_PP_ELSE); }
PP "elif" { RET(TOKEN_PP_ELIF); }
PP "endif" { RET(TOKEN_PP_ENDIF); }
PP "error" { RET(TOKEN_PP_ERROR); }
May 31, 2010
May 31, 2010
242
PP "pragma" { RET(TOKEN_PP_PRAGMA); }
Feb 22, 2009
Feb 22, 2009
243
WHITESPACE { goto ppdirective; }
Feb 24, 2009
Feb 24, 2009
244
245
246
247
248
249
ANY {
token = cursor = (const uchar *) s->source;
limit = cursor + s->bytes_left;
goto scanner_loop;
}
Feb 22, 2009
Feb 22, 2009
250
251
*/
252
bad_chars:
Feb 17, 2009
Feb 17, 2009
253
if (YYLIMIT == YYCURSOR) YYFILL(1);
254
/*!re2c
Feb 13, 2009
Feb 13, 2009
255
ANYLEGAL { cursor--; RET(TOKEN_BAD_CHARS); }
Feb 17, 2009
Feb 17, 2009
256
257
258
259
260
261
262
263
264
265
266
267
"\000" {
if (eoi)
{
assert( !((token >= sentinel) &&
(token < sentinel+YYMAXFILL)) );
eoi = 0;
cursor = (uchar *) s->source_base + s->orig_length;
RET(TOKEN_BAD_CHARS); // next call will be EOI.
}
goto bad_chars;
}
Feb 13, 2009
Feb 13, 2009
268
ANY { goto bad_chars; }
269
270
271
272
*/
assert(0 && "Shouldn't hit this code");
RET(TOKEN_UNKNOWN);
Feb 18, 2009
Feb 18, 2009
273
} // preprocessor_lexer
Sep 27, 2015
Sep 27, 2015
275
// end of mojoshader_lexer.re (or .c) ...