1 // glsl.rl by Leszek Godlewski <ineqvation ay tee gmail dee oh tee cee oh em>
2 // Written according to GLSL 1.20.8 specificiation
3 // Based on c.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
5 /************************* Required for every parser *************************/
6 #ifndef OHCOUNT_GLSL_PARSER_H
7 #define OHCOUNT_GLSL_PARSER_H
9 #include "../parser_macros.h"
11 // the name of the language
12 const char *GLSL_LANG = LANG_GLSL;
14 // the languages entities
15 const char *glsl_entities[] = {
16 "space", "comment", "string", "number", "preproc",
17 "keyword", "identifier", "operator", "any"
20 // constants associated with the entities
22 GLSL_SPACE = 0, GLSL_COMMENT, GLSL_STRING, GLSL_NUMBER, GLSL_PREPROC,
23 GLSL_KEYWORD, GLSL_IDENTIFIER, GLSL_OPERATOR, GLSL_ANY
26 /*****************************************************************************/
31 include common "common.rl";
33 # Line counting machine
35 action glsl_ccallback {
44 std_internal_newline(GLSL_LANG)
47 std_newline(GLSL_LANG)
53 escaped_newline %{ entity = INTERNAL_NL; } %glsl_ccallback
57 (nonnewline - ws) @comment
61 newline %{ entity = INTERNAL_NL; } %glsl_ccallback
65 (nonnewline - ws) @comment
67 glsl_comment = glsl_line_comment | glsl_block_comment;
71 escaped_newline %{ entity = INTERNAL_NL; } %glsl_ccallback
81 escaped_newline %{ entity = INTERNAL_NL; } %glsl_ccallback
89 glsl_string = glsl_sq_str | glsl_dq_str;
92 spaces ${ entity = GLSL_SPACE; } => glsl_ccallback;
95 newline ${ entity = NEWLINE; } => glsl_ccallback;
96 ^space ${ entity = GLSL_ANY; } => glsl_ccallback;
101 action glsl_ecallback {
102 callback(GLSL_LANG, glsl_entities[entity], cint(ts), cint(te), userdata);
105 glsl_line_comment_entity = '//' (escaped_newline | nonnewline)*;
106 glsl_block_comment_entity = '/*' any* :>> '*/';
107 glsl_comment_entity = glsl_line_comment_entity | glsl_block_comment_entity;
109 glsl_string_entity = sq_str_with_escapes | dq_str_with_escapes;
111 glsl_number_entity = float | integer;
117 'if' | 'ifdef' | 'ifndef' | 'else' | 'elif' | 'endif' |
119 'pragma' | 'error' | 'extension' | 'version' | 'line';
120 # TODO: find some way of making preproc match the beginning of a line.
121 # Putting a 'when starts_line' conditional throws an assertion error.
122 glsl_preproc_entity =
123 '#' space* (glsl_block_comment_entity space*)?
124 glsl_preproc_word (escaped_newline | nonnewline)*;
126 glsl_identifier_entity = (alpha | '_') (alnum | '_')*;
128 glsl_keyword_entity =
129 'attribute' | 'const' | 'uniform' | 'varying' | 'centroid' | 'break' |
130 'continue' | 'do' | 'for' | 'while' | 'if' | 'else' | 'in' | 'out' |
131 'inout' | 'float' | 'int' | 'void' | 'bool' | 'true' | 'false' |
132 'invariant' | 'discard' | 'return' | 'mat2' | 'mat3' | 'mat4' |
133 'mat2x2' | 'mat2x3' | 'mat2x4' | 'mat3x2' | 'mat3x3' | 'mat3x4' |
134 'mat4x2' | 'mat4x3' | 'mat4x4' | 'vec2' | 'vec3' | 'vec4' | 'ivec2' |
135 'ivec3' | 'ivec4' | 'bvec2' | 'bvec3' | 'bvec4' | 'sampler1D' |
136 'sampler2D' | 'sampler3D' | 'samplerCube' | 'sampler1DShadow' |
137 'sampler2DShadow' | 'struct';
138 # not including keywords reserved for future use
140 glsl_operator_entity = [+\-/*%<>!=^&|?~:;.,()\[\]{}];
143 space+ ${ entity = GLSL_SPACE; } => glsl_ecallback;
144 glsl_comment_entity ${ entity = GLSL_COMMENT; } => glsl_ecallback;
145 glsl_string_entity ${ entity = GLSL_STRING; } => glsl_ecallback;
146 glsl_number_entity ${ entity = GLSL_NUMBER; } => glsl_ecallback;
147 glsl_preproc_entity ${ entity = GLSL_PREPROC; } => glsl_ecallback;
148 glsl_identifier_entity ${ entity = GLSL_IDENTIFIER; } => glsl_ecallback;
149 glsl_keyword_entity ${ entity = GLSL_KEYWORD; } => glsl_ecallback;
150 glsl_operator_entity ${ entity = GLSL_OPERATOR; } => glsl_ecallback;
151 ^(space | digit) ${ entity = GLSL_ANY; } => glsl_ecallback;
155 /************************* Required for every parser *************************/
157 /* Parses a string buffer with OpenGL Shading Language code.
159 * @param *buffer The string to parse.
160 * @param length The length of the string to parse.
161 * @param count Integer flag specifying whether or not to count lines. If yes,
162 * uses the Ragel machine optimized for counting. Otherwise uses the Ragel
163 * machine optimized for returning entity positions.
164 * @param *callback Callback function. If count is set, callback is called for
165 * every line of code, comment, or blank with 'lcode', 'lcomment', and
166 * 'lblank' respectively. Otherwise callback is called for each entity found.
168 void parse_glsl(char *buffer, int length, int count,
169 void (*callback) (const char *lang, const char *entity, int s,
176 cs = (count) ? glsl_en_glsl_line : glsl_en_glsl_entity;
179 // if no newline at EOF; callback contents of last line
180 if (count) { process_last_line(GLSL_LANG) }
185 /*****************************************************************************/