├── .gitignore ├── AstNodes.md ├── LICENSE ├── Makefile ├── Readme.md ├── glsl.lex ├── glsl.y ├── glsl_ast.c ├── glsl_ast.h ├── glsl_parser.h └── glsl_parser_test.c /.gitignore: -------------------------------------------------------------------------------- 1 | glsl.parser.c 2 | glsl.parser.h 3 | glsl.lexer.c 4 | glsl.lexer.h 5 | glsl_parser_test 6 | *.o 7 | -------------------------------------------------------------------------------- /AstNodes.md: -------------------------------------------------------------------------------- 1 | AST structure 2 | ============= 3 | 4 | Each node in the AST has the same type `struct glsl_node`. The `glsl_node` struct stores a variable number of children in an array past the end of the structure. It also contains a `code` field that identifies what type of node it is and how to interpret it's child nodes. The node types are documented in the list below. 5 | 6 | In each entry below the value on the left side of the ":" is a node type and the values on the right define the type of child nodes the type has. Nodes surrounded by brackets are optional and a "|" separated list denotes that the child can be any one of the types in the list. If a node is followed by `...` then it matches an arbitrary number of nodes (including zero) of that type. Entries in all lower case simply assign a label to an "|" list and do not define a node type. 7 | 8 | Some of the node descriptions below contain a comment indicating the equivalent GLSL code they represent in terms of identifier's 'a', 'b', 'c', which refer to the node's children. Comments 9 | in other nodes may list some arbitary examples of GLSL fragments the node type could represent. 10 | 11 | AST node types 12 | -------------- 13 | TRANSLATION_UNIT : DECLARATION | FUNCTION_DEFINITON 14 | 15 | FUNCTION_DEFINITION : FUNCTION_DECLARATION STATEMENT_LIST 16 | 17 | FUNCTION_DECLARATION : FUNCTION_HEADER FUNCTION_PARAMETER_LIST 18 | 19 | FUNCTION_HEADER : FULLY_SPECIFIED_TYPE IDENTIFIER 20 | 21 | FUNCTION_PARAMETER_LIST : PARAMETER_DECLARATION ... 22 | 23 | PARAMETER_DECLARATION : TYPE_QUALIFIER_LIST PARAMETER_DECLARATOR 24 | 25 | FULLY_SPECIFIED_TYPE : TYPE_QUALIFIER_LIST TYPE_SPECIFIER 26 | 27 | TYPE_SPECIFIER : type_specifier_nonarray ARRAY_SPECIFIER_LIST 28 | 29 | type_specifier_nonarray : type_token | STRUCT_SPECIFIER | IDENTIFIER 30 | 31 | STRUCT_SPECIFIER : IDENTIFIER STRUCT_DECLARATION_LIST 32 | 33 | STRUCT_DECLARATION_LIST : STRUCT_DECLARATION ... 34 | 35 | STRUCT_DECLARATION : TYPE_QUALIFIER_LIST TYPE_SPECIFIER STRUCT_DECLARATOR_LIST 36 | 37 | STRUCT_DECLARATOR_LIST : STRUCT_DECLARATOR ... 38 | 39 | STRUCT_DECLARATOR : IDENTIFIER ARRAY_SPECIFIER_LIST 40 | 41 | type_token : VOID | FLOAT | DOUBLE | INT | UINT | BOOL 42 | | VEC2 | VEC3 | VEC4 43 | | DVEC2 | DVEC3 | DVEC4 44 | | BVEC2 | BVEC3 | BVEC4 45 | | IVEC2 | IVEC3 | IVEC4 46 | | UVEC2 | UVEC3 | UVEC4 47 | | MAT2 | MAT3 | MAT4 48 | | MAT2X2 | MAT2X3 | MAT2X4 49 | | MAT3X2 | MAT3X3 | MAT3X4 50 | | MAT4X2 | MAT4X3 | MAT4X4 51 | | DMAT2 | DMAT3 | DMAT4 52 | | DMAT2X2 | DMAT2X3 | DMAT2X4 53 | | DMAT3X2 | DMAT3X3 | DMAT3X4 54 | | DMAT4X2 | DMAT4X3 | DMAT4X4 55 | | ATOMIC_UINT 56 | | SAMPLER1D | SAMPLER2D | SAMPLER3D 57 | | SAMPLERCUBE 58 | | SAMPLER1DSHADOW | SAMPLER2DSHADOW | SAMPLERCUBESHADOW 59 | | SAMPLER1DARRAY | SAMPLER2DARRAY 60 | | SAMPLER1DARRAYSHADOW | SAMPLER2DARRAYSHADOW 61 | | SAMPLERCUBEARRAY | SAMPLERCUBEARRAYSHADOW 62 | | ISAMPLER1D | ISAMPLER2D | ISAMPLER3D 63 | | ISAMPLERCUBE 64 | | ISAMPLER1DARRAY | ISAMPLER2DARRAY | ISAMPLERCUBEARRAY 65 | | USAMPLER1D | USAMPLER2D | USAMPLER3D 66 | | USAMPLERCUBE | USAMPLER1DARRAY 67 | | USAMPLER2DARRAY | USAMPLERCUBEARRAY | SAMPLER2DRECT 68 | | SAMPLER2DRECTSHADOW | ISAMPLER2DRECT | USAMPLER2DRECT 69 | | SAMPLERBUFFER | ISAMPLERBUFFER | USAMPLERBUFFER 70 | | SAMPLER2DMS | ISAMPLER2DMS | USAMPLER2DMS 71 | | SAMPLER2DMSARRAY | ISAMPLER2DMSARRAY | USAMPLER2DMSARRAY 72 | | IMAGE1D | IIMAGE1D | UIMAGE1D 73 | | IMAGE2D | IIMAGE2D | UIMAGE2D 74 | | IMAGE3D | IIMAGE3D | UIMAGE3D 75 | | IMAGE2DRECT | IIMAGE2DRECT | UIMAGE2DRECT 76 | | IMAGECUBE | IIMAGECUBE | UIMAGECUBE 77 | | IMAGEBUFFER | IIMAGEBUFFER | UIMAGEBUFFER 78 | | IMAGE1DARRAY | IIMAGE1DARRAY | UIMAGE1DARRAY 79 | | IMAGE2DARRAY | IIMAGE2DARRAY | UIMAGE2DARRAY 80 | | IMAGECUBEARRAY | IIMAGECUBEARRAY | UIMAGECUBEARRAY 81 | | IMAGE2DMS | IIMAGE2DMS | UIMAGE2DMS 82 | | IMAGE2DMSARRAY | IIMAGE2DMSARRAY | UIMAGE2DMSARRAY 83 | 84 | PARAMETER_DECLARATOR : TYPE_SPECIFIER IDENTIFIER ARRAY_SPECIFIER_LIST 85 | 86 | type_qualifier : LAYOUT_QUALIFIER_ID_LIST | HIGHP | MEDIUMP 87 | | LOWP | SMOOTH | FLAT| NOPERSPECTIVE 88 | | INVARIANT | PRECISE | storage_qualifier 89 | 90 | TYPE_QUALIFIER_LIST : type_qualifier ... 91 | 92 | storage_qualifier : CONST | INOUT | IN | OUT | CENTROID 93 | | PATCH | SAMPLE | UNIFORM | BUFFER | SHARED 94 | | COHERENT | VOLATILE | RESTRICT | READONLY | WRITEONLY 95 | | SUBROUTINE | SUBROUTINE_TYPE 96 | 97 | SUBROUTINE_TYPE : TYPE_NAME_LIST | IDENTIFIER 98 | 99 | TYPE_NAME_LIST : IDENTIFIER ... 100 | 101 | LAYOUT_QUALIFIER_ID_LIST: (LAYOUT_QUALIFIER_ID | SHARED ) ... 102 | 103 | LAYOUT_QUALIFIER_ID : (TODO) 104 | 105 | STATEMENT_LIST : statement ... 106 | 107 | statement : DECLARATION | EXPRESSION_STATEMENT | SELECTION_STATEMENT 108 | | RETURN | RETURN_VALUE | BREAK | FOR_STATEMENT | WHILE_STATEMENT 109 | | DO_STATEMENT 110 | 111 | DECLARATION : INIT_DECLARATOR_LIST | BLOCK_DECLARATION | FUNCTION_DECLARATION 112 | 113 | INIT_DECLARATOR_LIST : (SINGLE_DECLARATION | SINGLE_INIT_DECLARATION) INIT_DECLARATOR ... 114 | 115 | INIT_DECLARATOR : IDENTIFIER ARRAY_SPECIFIER_LIST INITIALIZER // example: int r = 0 116 | 117 | INITIALIZER : expression | INITIALIZER_LIST 118 | 119 | INITIALIZER_LIST : INITIALIZER... // { a, b, c, ...} 120 | 121 | EXPRESSION_STATEMENT : [expression] // "a;" or ";" 122 | 123 | expression : binary_operator | unary_expression 124 | | assignment_expression | TERNARY_EXPRESSION 125 | 126 | unary_expression : prefix_expression | postfix_expression 127 | 128 | binary_operator : PLUS | DASH | STAR | SLASH 129 | | PERCENT | AMPERSAND | EQ_OP | NE_OP 130 | | LEFT_ANGLE | RIGHT_ANGLE | LE_OP | GE_OP 131 | | LEFT_OP | RIGHT_OP | CARET | VERTICAL_BAR 132 | | AND_OP | OR_OP | XOR_OP 133 | 134 | PLUS : expression expression // a + b 135 | DASH : expression expression // a - b 136 | STAR : expression expression // a * b 137 | SLASH : expression expression // a / b 138 | PERCENT : expression expression // a % b 139 | AMPERSAND : expression expression // a & b 140 | EQ_OP : expression expression // a == b 141 | NE_OP : expression expression // a != b 142 | LEFT_ANGLE : expression expression // a < b 143 | RIGHT_ANGLE : expression expression // a > b 144 | LE_OP : expression expression // a <= b 145 | GE_OP : expression expression // a >= b 146 | LEFT_OP : expression expression // a << b 147 | RIGHT_OP : expression expression // a >> b 148 | CARET : expression expression // a ^ b 149 | VERTICAL_BAR : expression expression // a | b 150 | AND_OP : expression expression // a && b 151 | OR_OP : expression expression // a || b 152 | XOR_OP : expression expression // a ^^ b 153 | 154 | assignment_expression : EQUAL | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN 155 | | ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN 156 | | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN 157 | | OR_ASSIGN 158 | 159 | EQUAL : unary_expression expression // a = b 160 | MUL_ASSIGN : unary_expression expression // a *= b 161 | DIV_ASSIGN : unary_expression expression // a /= b 162 | MOD_ASSIGN : unary_expression expression // a %= b 163 | ADD_ASSIGN : unary_expression expression // a += b 164 | SUB_ASSIGN : unary_expression expression // a -= b 165 | LEFT_ASSIGN : unary_expression expression // a <<= b 166 | RIGHT_ASSIGN : unary_expression expression // a >>= b 167 | AND_ASSIGN : unary_expression expression // a &= b 168 | XOR_ASSIGN : unary_expression expression // a ^= b 169 | OR_ASSIGN : unary_expression expression // a |= b 170 | 171 | TERNARY_EXPRESSION : expression expression expression // a ? b : c 172 | 173 | prefix_expression : PRE_INC_OP | PRE_DEC_OP | UNARY_PLUS 174 | | UNARY_DASH | TILDE | BANG 175 | 176 | PRE_INC_OP : expression // ++a 177 | PRE_DEC_OP : expression // --a 178 | UNARY_PLUS : expression // +a 179 | UNARY_DASH : expression // -a 180 | TILDE : expression // ~a 181 | BANG : expression // !a 182 | 183 | POSTFIX_EXPRESSION : postfix_expression 184 | 185 | postfix_expression : POST_INC_OP | POST_DEC_OP | FUNCTION_CALL | ARRAY_REF_OP | DOT 186 | | IDENTIFIER | INTCONSTANT | UINTCONSTANT | FLOATCONSTANT | TRUE 187 | | FALSE | PAREN_EXPRESSION 188 | 189 | PAREN_EXPRESSION : expression // (a) 190 | 191 | POST_INC_OP : expression // a++ 192 | POST_DEC_OP : expression // a-- 193 | 194 | DOT : expression IDENTIFIER // a.b 195 | 196 | SINGLE_DECLARATION : FULLY_SPECIFIED_TYPE IDENTIFIER ARRAY_SPECIFIER_LIST //examples: "float x[10]", "vec3 y" 197 | 198 | SINGLE_INIT_DECLARATION : FULLY_SPECIFIED_TYPE IDENTIFIER ARRAY_SPECIFIER_LIST INITIALIZER //examples: "float x[10] = {...}", "float y = 1.0" 199 | 200 | BLOCK_DECLARATION : TYPE_QUALIFIER_LIST IDENTIFIER STRUCT_DECLARATION_LIST IDENTIFIER ARRAY_SPECIFIER_LIST // a b { c } d e; 201 | 202 | FUNCTION_CALL : (TYPE_SPECIFIER | POSTFIX_EXPRESSION) FUNCITON_CALL_PARAMETER_LIST //examples: "vec3(0,1,2)", "myfunc(0,1,2)" 203 | 204 | FUNCITON_CALL_PARAMETER_LIST : expression ... 205 | 206 | ARRAY_REF_OP : postfix_expression expression // a[b] 207 | 208 | BREAK : (empty) // break; 209 | 210 | SELECTION_STATEMENT : expression statement // if (a) b 211 | 212 | SELECTION_STATEMENT_ELSE: expression statement statement // if (a) b else c 213 | 214 | WHILE_STATEMENT : condition statement // while(a) b 215 | 216 | DO_STATEMENT : statement expression // do { a } while(b); 217 | 218 | FOR_STATEMENT : for_init_statement FOR_REST_STATEMENT statement // for (a; b) c 219 | 220 | for_init_statement : EXPRESSION_STATEMENT | DECLARATION // examples: "int r = 0", "r = 0" 221 | 222 | FOR_REST_STATEMENT : CONDITION_OPT [expression] // examples: "r > 0; r++", ";r++", "r>0;", ";" 223 | 224 | CONDITION_OPT : [condition] 225 | 226 | condition : EXPRESSION_CONDITION | ASSIGNMENT_CONDITION 227 | 228 | EXPRESSION_CONDITION : expression 229 | 230 | ASSIGNMENT_CONDITION : FULLY_SPECIFIED_TYPE IDENTIFIER INITIALIZER 231 | 232 | RETURN : (none) // return; 233 | 234 | RETURN_VALUE : expression // return a; 235 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OBJS=glsl.parser.o glsl.lexer.o glsl_ast.o glsl_parser_test.o 2 | 3 | all: glsl_parser_test 4 | 5 | glsl.lexer.c: glsl.lex 6 | flex --header-file=glsl.lexer.h -o $@ $< 7 | 8 | glsl.parser.c: glsl.y 9 | bison --defines=glsl.parser.h $< -o $@ 10 | 11 | %.o: %.c 12 | gcc -g -O0 -std=gnu99 -c -Wall $< -o $@ 13 | 14 | glsl.lexer.o: glsl_parser.h glsl.parser.c 15 | glsl.parser.o: glsl_parser.h glsl.lexer.c glsl.parser.c 16 | 17 | glsl_ast.o: glsl_ast.c glsl_parser.h glsl.lexer.c glsl.parser.c 18 | glsl_parser_test.o: glsl_parser_test.c glsl_parser.h glsl.parser.c 19 | 20 | glsl_parser_test: $(OBJS) 21 | gcc $(OBJS) -o $@ 22 | 23 | clean: 24 | @-rm -f glsl_parser_test 25 | @-rm -f glsl.parser.c 26 | @-rm -f glsl.parser.h 27 | @-rm -f glsl.lexer.c 28 | @-rm -f glsl.lexer.h 29 | @-rm -f *.o 30 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | glsl-parser 2 | ========= 3 | 4 | This is a GLSL parser implemented with `flex` and `bison`. The grammar is based on the OpenGL 4.5 reference specs. The parser generates an AST represented in C data structures. The AST structure is documented in AstNodes.md. 5 | 6 | The header file `glsl_parser.h` documents the interface to the parser and the header file `glsl_ast.h` defines some useful functions for working with the AST it generates. 7 | 8 | The included Makefile builds a test program that reads a shader from a file or standard input and prints out a human readable version of the shader's AST and attempts to regenerate the input shader from the AST. 9 | -------------------------------------------------------------------------------- /glsl.lex: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define YYSTYPE GLSL_STYPE 8 | #define YYLTYPE GLSL_LTYPE 9 | 10 | #define YY_USER_ACTION \ 11 | yylloc->first_line = yylloc->last_line; \ 12 | yylloc->first_column = yylloc->last_column; \ 13 | for(int i = 0; yytext[i] != '\0'; i++) { \ 14 | if(yytext[i] == '\n') { \ 15 | yylloc->last_line++; \ 16 | yylloc->last_column = 0; \ 17 | } \ 18 | else { \ 19 | yylloc->last_column++; \ 20 | } \ 21 | } 22 | 23 | #include "glsl_parser.h" 24 | #include "glsl.parser.h" 25 | 26 | %} 27 | 28 | 29 | %option reentrant 30 | %option bison-bridge 31 | %option bison-locations 32 | %option yylineno 33 | %option noyywrap 34 | %option prefix="glsl_" 35 | 36 | ws [ \t]+ 37 | digit [0-9] 38 | nondigit [_a-zA-Z] 39 | identifier {nondigit}({nondigit}|{digit})* 40 | integer_constant {digit}+ 41 | floating_constant {digit}+\.{digit}+ 42 | 43 | %x COMMENT 44 | 45 | %% 46 | 47 | [\t\n ]+ 48 | 49 | #.*\n 50 | 51 | \/\/.*\n 52 | 53 | "/*" BEGIN(COMMENT); 54 | "*/" BEGIN(INITIAL); 55 | [^*\n]+ { } 56 | 57 | const return CONST; 58 | uniform return UNIFORM; 59 | buffer return BUFFER; 60 | shared return SHARED; 61 | coherent return COHERENT; 62 | volatile return VOLATILE; 63 | restrict return RESTRICT; 64 | readonly return READONLY; 65 | writeonly return WRITEONLY; 66 | atomic_uint return ATOMIC_UINT; 67 | layout return LAYOUT; 68 | centroid return CENTROID; 69 | flat return FLAT; 70 | smooth return SMOOTH; 71 | noperspective return NOPERSPECTIVE; 72 | patch return PATCH; 73 | sample return SAMPLE; 74 | break return BREAK; 75 | continue return CONTINUE; 76 | do return DO; 77 | for return FOR; 78 | while return WHILE; 79 | switch return SWITCH; 80 | case return CASE; 81 | default return DEFAULT; 82 | if return IF; 83 | else return ELSE; 84 | subroutine return SUBROUTINE; 85 | in return IN; 86 | out return OUT; 87 | inout return INOUT; 88 | float return FLOAT; 89 | double return DOUBLE; 90 | int return INT; 91 | void return VOID; 92 | bool return BOOL; 93 | invariant return INVARIANT; 94 | precise return PRECISE; 95 | discard return DISCARD; 96 | return return RETURN; 97 | mat2 return MAT2; 98 | mat3 return MAT3; 99 | mat4 return MAT4; 100 | dmat2 return DMAT2; 101 | dmat3 return DMAT3; 102 | dmat4 return DMAT4; 103 | mat2x2 return MAT2X2; 104 | mat2x3 return MAT2X3; 105 | mat2x4 return MAT2X4; 106 | dmat2x2 return DMAT2X2; 107 | dmat2x3 return DMAT2X3; 108 | dmat2x4 return DMAT2X4; 109 | mat3x2 return MAT3X2; 110 | mat3x3 return MAT3X3; 111 | mat3x4 return MAT3X4; 112 | dmat3x2 return DMAT3X2; 113 | dmat3x3 return DMAT3X3; 114 | dmat3x4 return DMAT3X4; 115 | mat4x2 return MAT4X2; 116 | mat4x3 return MAT4X3; 117 | mat4x4 return MAT4X4; 118 | dmat4x2 return DMAT4X2; 119 | dmat4x3 return DMAT4X3; 120 | dmat4x4 return DMAT4X4; 121 | vec2 return VEC2; 122 | vec3 return VEC3; 123 | vec4 return VEC4; 124 | ivec2 return IVEC2; 125 | ivec3 return IVEC3; 126 | ivec4 return IVEC4; 127 | bvec2 return BVEC2; 128 | bvec3 return BVEC3; 129 | bvec4 return BVEC4; 130 | dvec2 return DVEC2; 131 | dvec3 return DVEC3; 132 | dvec4 return DVEC4; 133 | uint return UINT; 134 | uvec2 return UVEC2; 135 | uvec3 return UVEC3; 136 | uvec4 return UVEC4; 137 | lowp return LOWP; 138 | mediump return MEDIUMP; 139 | highp return HIGHP; 140 | precision return PRECISION; 141 | sampler1D return SAMPLER1D; 142 | sampler2D return SAMPLER2D; 143 | sampler3D return SAMPLER3D; 144 | samplerCube return SAMPLERCUBE; 145 | sampler1DShadow return SAMPLER1DSHADOW; 146 | sampler2DShadow return SAMPLER2DSHADOW; 147 | samplerCubeShadow return SAMPLERCUBESHADOW; 148 | sampler1DArray return SAMPLER1DARRAY; 149 | sampler2DArray return SAMPLER2DARRAY; 150 | sampler1DArrayShadow return SAMPLER1DARRAYSHADOW; 151 | sampler2DArrayShadow return SAMPLER2DARRAYSHADOW; 152 | isampler1D return ISAMPLER1D; 153 | isampler2D return ISAMPLER2D; 154 | isampler3D return ISAMPLER3D; 155 | isamplerCube return ISAMPLERCUBE; 156 | isampler1DArray return ISAMPLER1DARRAY; 157 | isampler2DArray return ISAMPLER2DARRAY; 158 | usampler1D return USAMPLER1D; 159 | usampler2D return USAMPLER2D; 160 | usampler3D return USAMPLER3D; 161 | usamplerCube return USAMPLERCUBE; 162 | usampler1DArray return USAMPLER1DARRAY; 163 | usampler2DArray return USAMPLER2DARRAY; 164 | sampler2DRect return SAMPLER2DRECT; 165 | sampler2DRectShadow return SAMPLER2DRECTSHADOW; 166 | isampler2DRect return ISAMPLER2DRECT; 167 | usampler2DRect return USAMPLER2DRECT; 168 | samplerBuffer return SAMPLERBUFFER; 169 | isamplerBuffer return ISAMPLERBUFFER; 170 | usamplerBuffer return USAMPLERBUFFER; 171 | sampler2DMS return SAMPLER2DMS; 172 | isampler2DMS return ISAMPLER2DMS; 173 | usampler2DMS return USAMPLER2DMS; 174 | sampler2DMSArray return SAMPLER2DMSARRAY; 175 | isampler2DMSArray return ISAMPLER2DMSARRAY; 176 | usampler2DMSArray return USAMPLER2DMSARRAY; 177 | samplerCubeArray return SAMPLERCUBEARRAY; 178 | samplerCubeArrayShadow return SAMPLERCUBEARRAYSHADOW; 179 | isamplerCubeArray return ISAMPLERCUBEARRAY; 180 | usamplerCubeArray return USAMPLERCUBEARRAY; 181 | image1D return IMAGE1D; 182 | iimage1D return IIMAGE1D; 183 | uimage1D return UIMAGE1D; 184 | image2D return IMAGE2D; 185 | iimage2D return IIMAGE2D; 186 | uimage2D return UIMAGE2D; 187 | image3D return IMAGE3D; 188 | iimage3D return IIMAGE3D; 189 | uimage3D return UIMAGE3D; 190 | image2DRect return IMAGE2DRECT; 191 | iimage2DRect return IIMAGE2DRECT; 192 | uimage2DRect return UIMAGE2DRECT; 193 | imageCube return IMAGECUBE; 194 | iimageCube return IIMAGECUBE; 195 | uimageCube return UIMAGECUBE; 196 | imageBuffer return IMAGEBUFFER; 197 | iimageBuffer return IIMAGEBUFFER; 198 | uimageBuffer return UIMAGEBUFFER; 199 | image1DArray return IMAGE1DARRAY; 200 | iimage1DArray return IIMAGE1DARRAY; 201 | uimage1DArray return UIMAGE1DARRAY; 202 | image2DArray return IMAGE2DARRAY; 203 | iimage2DArray return IIMAGE2DARRAY; 204 | uimage2DArray return UIMAGE2DARRAY; 205 | imageCubeArray return IMAGECUBEARRAY; 206 | iimageCubeArray return IIMAGECUBEARRAY; 207 | uimageCubeArray return UIMAGECUBEARRAY; 208 | image2DMS return IMAGE2DMS; 209 | iimage2DMS return IIMAGE2DMS; 210 | uimage2DMS return UIMAGE2DMS; 211 | image2DMSArray return IMAGE2DMSARRAY; 212 | iimage2DMSArray return IIMAGE2DMSARRAY; 213 | uimage2DMSArray return UIMAGE2DMSARRAY; 214 | struct return STRUCT; 215 | 216 | \<\< return LEFT_OP; 217 | \>\> return RIGHT_OP; 218 | \+\+ return INC_OP; 219 | \-\- return DEC_OP; 220 | \<\= return LE_OP; 221 | \>\= return GE_OP; 222 | \=\= return EQ_OP; 223 | \!\= return NE_OP; 224 | \&\& return AND_OP; 225 | \|\| return OR_OP; 226 | \^\^ return XOR_OP; 227 | \*\= return MUL_ASSIGN; 228 | \/\= return DIV_ASSIGN; 229 | \+\= return ADD_ASSIGN; 230 | \%\= return MOD_ASSIGN; 231 | \<\<\= return LEFT_ASSIGN; 232 | \>\>\= return RIGHT_ASSIGN; 233 | \&\= return AND_ASSIGN; 234 | \^\= return XOR_ASSIGN; 235 | \|\= return OR_ASSIGN; 236 | \-\= return SUB_ASSIGN; 237 | 238 | \+ return PLUS; 239 | \- return DASH; 240 | \% return PERCENT; 241 | \* return STAR; 242 | \/ return SLASH; 243 | \~ return TILDE; 244 | \! return BANG; 245 | \^ return CARET; 246 | \( return LEFT_PAREN; 247 | \) return RIGHT_PAREN; 248 | \{ return LEFT_BRACE; 249 | \} return RIGHT_BRACE; 250 | \; return SEMICOLON; 251 | \< return LEFT_ANGLE; 252 | \> return RIGHT_ANGLE; 253 | \. return DOT; 254 | \, return COMMA; 255 | \[ return LEFT_BRACKET; 256 | \] return RIGHT_BRACKET; 257 | \| return VERTICAL_BAR; 258 | \: return COLON; 259 | \= return EQUAL; 260 | \& return AMPERSAND; 261 | \? return QUESTION; 262 | 263 | true { return TRUE_VALUE; } 264 | false { return FALSE_VALUE; } 265 | 266 | {identifier} { (*yylval).IDENTIFIER = strdup(yytext); return IDENTIFIER; } 267 | {integer_constant} { (*yylval).INTCONSTANT = atoi(yytext); return INTCONSTANT; } 268 | {floating_constant} { (*yylval).FLOATCONSTANT = atof(yytext); return FLOATCONSTANT; } 269 | 270 | %% 271 | -------------------------------------------------------------------------------- /glsl.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "glsl_parser.h" //For context struct 12 | #include "glsl.parser.h" //For GLSL_STYPE and GLSL_LTYPE 13 | #include "glsl.lexer.h" //For glsl_lex() 14 | 15 | static void glsl_error(GLSL_LTYPE *loc, struct glsl_parse_context *c, const char *s); 16 | 17 | #define GLSL_STACK_BUFFER_SIZE (1024*1024) 18 | #define GLSL_STACK_BUFFER_PAYLOAD_SIZE (GLSL_STACK_BUFFER_SIZE - sizeof(intptr_t)) 19 | 20 | uint8_t *glsl_parse_alloc(struct glsl_parse_context *context, size_t size, int align) 21 | { 22 | uint8_t *ret; 23 | 24 | if (size + align > (context->cur_buffer_end - context->cur_buffer)) { 25 | uint8_t *next_buffer = (uint8_t *)malloc(GLSL_STACK_BUFFER_SIZE); 26 | if (context->cur_buffer) { 27 | uint8_t **pnext = (uint8_t **)context->cur_buffer_end; 28 | *pnext = next_buffer; 29 | } 30 | context->cur_buffer_start = next_buffer; 31 | context->cur_buffer = next_buffer; 32 | context->cur_buffer_end = next_buffer + GLSL_STACK_BUFFER_PAYLOAD_SIZE; 33 | if (!context->first_buffer) { 34 | context->first_buffer = context->cur_buffer; 35 | } 36 | *((uint8_t **)context->cur_buffer_end) = NULL; 37 | } 38 | 39 | ret = context->cur_buffer; 40 | 41 | uint8_t *trunc = (uint8_t *)((~((intptr_t)align - 1)) & ((intptr_t)ret)); 42 | if (trunc != ret) { 43 | ret = trunc + align; 44 | } 45 | context->cur_buffer = ret + size; 46 | return ret; 47 | } 48 | 49 | void glsl_parse_dealloc(struct glsl_parse_context *context) 50 | { 51 | uint8_t *buffer = context->first_buffer; 52 | while (buffer) { 53 | uint8_t *next = *((uint8_t **)(buffer + GLSL_STACK_BUFFER_PAYLOAD_SIZE)); 54 | free(buffer); 55 | buffer = next; 56 | } 57 | } 58 | 59 | static char *glsl_parse_strdup(struct glsl_parse_context *context, const char *c) 60 | { 61 | int len = strlen(c); 62 | char *ret = (char *)glsl_parse_alloc(context, len + 1, 1); 63 | strcpy(ret, c); 64 | return ret; 65 | } 66 | 67 | struct glsl_node *new_glsl_node(struct glsl_parse_context *context, int code, ...) 68 | { 69 | struct glsl_node *temp; 70 | int i; 71 | int n = 0; 72 | va_list vl; 73 | va_start(vl, code); 74 | while (1) { 75 | temp = va_arg(vl, struct glsl_node *); 76 | if (temp) 77 | n++; 78 | else 79 | break; 80 | } 81 | va_end(vl); 82 | struct glsl_node *g = (struct glsl_node *)glsl_parse_alloc(context, offsetof(struct glsl_node, children[n]), 8); 83 | g->code = code; 84 | g->child_count = n; 85 | va_start(vl, code); 86 | for (i = 0; i < n; i++) { 87 | temp = va_arg(vl, struct glsl_node *); 88 | g->children[i] = temp; 89 | } 90 | va_end(vl); 91 | return g; 92 | } 93 | 94 | static struct glsl_node *new_glsl_identifier(struct glsl_parse_context *context, const char *str) 95 | { 96 | struct glsl_node *n = new_glsl_node(context, IDENTIFIER, NULL); 97 | if (!str) 98 | n->data.str = NULL; 99 | else 100 | n->data.str = glsl_parse_strdup(context, str); 101 | return n; 102 | } 103 | 104 | static struct glsl_node *new_glsl_string(struct glsl_parse_context *context, int code, const char *str) 105 | { 106 | struct glsl_node *n = new_glsl_node(context, code, NULL); 107 | n->data.str = glsl_parse_strdup(context, str); 108 | return n; 109 | } 110 | 111 | #define scanner context->scanner //To allow the scanner to find it's context 112 | 113 | %} 114 | 115 | %defines 116 | 117 | %define api.prefix {glsl_} 118 | 119 | %define api.value.type union 120 | 121 | %pure-parser 122 | %parse-param { struct glsl_parse_context * context } 123 | %lex-param { void * scanner } 124 | %locations 125 | 126 | %type translation_unit 127 | 128 | %type external_declaration 129 | %type function_definition 130 | %type compound_statement_no_new_scope 131 | %type statement 132 | %type statement_list 133 | %type compound_statement 134 | %type simple_statement 135 | %type declaration 136 | %type identifier_list 137 | %type init_declarator_list 138 | %type single_declaration 139 | %type initializer 140 | %type initializer_list 141 | 142 | %type expression_statement 143 | %type selection_statement 144 | %type switch_statement 145 | %type switch_statement_list 146 | %type case_label 147 | %type iteration_statement 148 | %type statement_no_new_scope 149 | %type for_init_statement 150 | %type conditionopt 151 | 152 | %type condition 153 | %type for_rest_statement 154 | %type jump_statement 155 | %type function_prototype 156 | %type function_declarator 157 | %type parameter_declaration 158 | %type parameter_declarator 159 | %type function_header 160 | %type function_parameter_list 161 | %type fully_specified_type 162 | %type parameter_type_specifier 163 | 164 | %type primary_expression 165 | %type expression 166 | %type assignment_expression 167 | %type conditional_expression 168 | %type logical_or_expression 169 | %type logical_xor_expression 170 | %type logical_and_expression 171 | %type exclusive_or_expression 172 | %type constant_expression 173 | %type and_expression 174 | %type equality_expression 175 | %type relational_expression 176 | %type shift_expression 177 | %type additive_expression 178 | %type multiplicative_expression 179 | %type unary_expression 180 | %type postfix_expression 181 | %type integer_expression 182 | %type inclusive_or_expression 183 | 184 | %type function_call 185 | %type function_call_or_method 186 | %type function_call_generic 187 | %type function_call_parameter_list 188 | %type function_identifier 189 | 190 | %type type_specifier 191 | %type type_specifier_nonarray 192 | %type struct_specifier 193 | %type array_specifier 194 | %type array_specifier_list 195 | 196 | %type struct_declaration_list 197 | %type struct_declaration 198 | %type struct_declarator_list 199 | %type struct_declarator 200 | %type type_qualifier 201 | %type single_type_qualifier 202 | %type layout_qualifier 203 | %type layout_qualifier_id_list 204 | %type layout_qualifier_id 205 | 206 | %type precision_qualifier 207 | %type invariant_qualifier 208 | %type precise_qualifier 209 | %type storage_qualifier 210 | %type interpolation_qualifier 211 | %type type_name_list 212 | 213 | %type variable_identifier 214 | %type decl_identifier 215 | %type block_identifier 216 | %type struct_name 217 | %type type_name 218 | %type param_name 219 | %type function_name 220 | %type field_identifier 221 | %type type_specifier_identifier 222 | %type layout_identifier 223 | 224 | %type assignment_operator 225 | %type unary_operator 226 | 227 | %token CONST 228 | %token BOOL 229 | %token FLOAT 230 | %token DOUBLE 231 | %token INT 232 | %token UINT 233 | %token BREAK 234 | %token CONTINUE 235 | %token DO 236 | %token ELSE 237 | %token FOR 238 | %token IF 239 | %token DISCARD 240 | %token RETURN 241 | %token RETURN_VALUE 242 | %token SWITCH 243 | %token CASE 244 | %token DEFAULT 245 | %token SUBROUTINE 246 | %token BVEC2 247 | %token BVEC3 248 | %token BVEC4 249 | %token IVEC2 250 | %token IVEC3 251 | %token IVEC4 252 | %token UVEC2 253 | %token UVEC3 254 | %token UVEC4 255 | %token VEC2 256 | %token VEC3 257 | %token VEC4 258 | %token MAT2 259 | %token MAT3 260 | %token MAT4 261 | %token CENTROID 262 | %token IN 263 | %token OUT 264 | %token INOUT 265 | %token UNIFORM 266 | %token PATCH 267 | %token SAMPLE 268 | %token BUFFER 269 | %token SHARED 270 | %token COHERENT 271 | %token VOLATILE 272 | %token RESTRICT 273 | %token READONLY 274 | %token WRITEONLY 275 | %token DVEC2 276 | %token DVEC3 277 | %token DVEC4 278 | %token DMAT2 279 | %token DMAT3 280 | %token DMAT4 281 | %token NOPERSPECTIVE 282 | %token FLAT 283 | %token SMOOTH 284 | %token LAYOUT 285 | %token MAT2X2 286 | %token MAT2X3 287 | %token MAT2X4 288 | %token MAT3X2 289 | %token MAT3X3 290 | %token MAT3X4 291 | %token MAT4X2 292 | %token MAT4X3 293 | %token MAT4X4 294 | %token DMAT2X2 295 | %token DMAT2X3 296 | %token DMAT2X4 297 | %token DMAT3X2 298 | %token DMAT3X3 299 | %token DMAT3X4 300 | %token DMAT4X2 301 | %token DMAT4X3 302 | %token DMAT4X4 303 | %token ATOMIC_UINT 304 | %token SAMPLER1D 305 | %token SAMPLER2D 306 | %token SAMPLER3D 307 | %token SAMPLERCUBE 308 | %token SAMPLER1DSHADOW 309 | %token SAMPLER2DSHADOW 310 | %token SAMPLERCUBESHADOW 311 | %token SAMPLER1DARRAY 312 | %token SAMPLER2DARRAY 313 | %token SAMPLER1DARRAYSHADOW 314 | %token SAMPLER2DARRAYSHADOW 315 | %token ISAMPLER1D 316 | %token ISAMPLER2D 317 | %token ISAMPLER3D 318 | %token ISAMPLERCUBE 319 | %token ISAMPLER1DARRAY 320 | %token ISAMPLER2DARRAY 321 | %token USAMPLER1D 322 | %token USAMPLER2D 323 | %token USAMPLER3D 324 | %token USAMPLERCUBE 325 | %token USAMPLER1DARRAY 326 | %token USAMPLER2DARRAY 327 | %token SAMPLER2DRECT 328 | %token SAMPLER2DRECTSHADOW 329 | %token ISAMPLER2DRECT 330 | %token USAMPLER2DRECT 331 | %token SAMPLERBUFFER 332 | %token ISAMPLERBUFFER 333 | %token USAMPLERBUFFER 334 | %token SAMPLERCUBEARRAY 335 | %token SAMPLERCUBEARRAYSHADOW 336 | %token ISAMPLERCUBEARRAY 337 | %token USAMPLERCUBEARRAY 338 | %token SAMPLER2DMS 339 | %token ISAMPLER2DMS 340 | %token USAMPLER2DMS 341 | %token SAMPLER2DMSARRAY 342 | %token ISAMPLER2DMSARRAY 343 | %token USAMPLER2DMSARRAY 344 | %token IMAGE1D 345 | %token IIMAGE1D 346 | %token UIMAGE1D 347 | %token IMAGE2D 348 | %token IIMAGE2D 349 | %token UIMAGE2D 350 | %token IMAGE3D 351 | %token IIMAGE3D 352 | %token UIMAGE3D 353 | %token IMAGE2DRECT 354 | %token IIMAGE2DRECT 355 | %token UIMAGE2DRECT 356 | %token IMAGECUBE 357 | %token IIMAGECUBE 358 | %token UIMAGECUBE 359 | %token IMAGEBUFFER 360 | %token IIMAGEBUFFER 361 | %token UIMAGEBUFFER 362 | %token IMAGE1DARRAY 363 | %token IIMAGE1DARRAY 364 | %token UIMAGE1DARRAY 365 | %token IMAGE2DARRAY 366 | %token IIMAGE2DARRAY 367 | %token UIMAGE2DARRAY 368 | %token IMAGECUBEARRAY 369 | %token IIMAGECUBEARRAY 370 | %token UIMAGECUBEARRAY 371 | %token IMAGE2DMS 372 | %token IIMAGE2DMS 373 | %token UIMAGE2DMS 374 | %token IMAGE2DMSARRAY 375 | %token IIMAGE2DMSARRAY 376 | %token UIMAGE2DMSARRAY 377 | %token STRUCT 378 | %token VOID 379 | %token WHILE 380 | %token IDENTIFIER 381 | %token FLOATCONSTANT 382 | %token DOUBLECONSTANT 383 | %token INTCONSTANT 384 | %token UINTCONSTANT 385 | %token TRUE_VALUE 386 | %token FALSE_VALUE 387 | %token LEFT_OP 388 | %token RIGHT_OP 389 | %token INC_OP 390 | %token DEC_OP 391 | %token LE_OP 392 | %token GE_OP 393 | %token EQ_OP 394 | %token NE_OP 395 | %token AND_OP 396 | %token OR_OP 397 | %token XOR_OP 398 | %token MUL_ASSIGN 399 | %token DIV_ASSIGN 400 | %token ADD_ASSIGN 401 | %token MOD_ASSIGN 402 | %token LEFT_ASSIGN 403 | %token RIGHT_ASSIGN 404 | %token AND_ASSIGN 405 | %token XOR_ASSIGN 406 | %token OR_ASSIGN 407 | %token SUB_ASSIGN 408 | %token LEFT_PAREN 409 | %token RIGHT_PAREN 410 | %token LEFT_BRACKET 411 | %token RIGHT_BRACKET 412 | %token LEFT_BRACE 413 | %token RIGHT_BRACE 414 | %token DOT 415 | %token COMMA 416 | %token COLON 417 | %token EQUAL 418 | %token SEMICOLON 419 | %token BANG 420 | %token DASH 421 | %token TILDE 422 | %token PLUS 423 | %token STAR 424 | %token SLASH 425 | %token PERCENT 426 | %token LEFT_ANGLE 427 | %token RIGHT_ANGLE 428 | %token VERTICAL_BAR 429 | %token CARET 430 | %token AMPERSAND 431 | %token QUESTION 432 | %token INVARIANT 433 | %token PRECISE 434 | %token HIGHP 435 | %token MEDIUMP 436 | %token LOWP 437 | %token PRECISION 438 | %token AT 439 | 440 | %token UNARY_PLUS 441 | %token UNARY_DASH 442 | %token PRE_INC_OP 443 | %token PRE_DEC_OP 444 | %token POST_DEC_OP 445 | %token POST_INC_OP 446 | %token ARRAY_REF_OP 447 | %token FUNCTION_CALL 448 | %token TYPE_NAME_LIST 449 | %token TYPE_SPECIFIER 450 | %token POSTFIX_EXPRESSION 451 | %token TYPE_QUALIFIER_LIST 452 | %token STRUCT_DECLARATION 453 | %token STRUCT_DECLARATOR 454 | %token STRUCT_SPECIFIER 455 | %token FUNCTION_DEFINITION 456 | %token DECLARATION 457 | %token STATEMENT_LIST 458 | %token TRANSLATION_UNIT 459 | %token PRECISION_DECLARATION 460 | %token BLOCK_DECLARATION 461 | %token TYPE_QUALIFIER_DECLARATION 462 | %token IDENTIFIER_LIST 463 | %token INIT_DECLARATOR_LIST 464 | %token FULLY_SPECIFIED_TYPE 465 | %token SINGLE_DECLARATION 466 | %token SINGLE_INIT_DECLARATION 467 | %token INITIALIZER_LIST 468 | %token EXPRESSION_STATEMENT 469 | %token SELECTION_STATEMENT 470 | %token SELECTION_STATEMENT_ELSE 471 | %token SWITCH_STATEMENT 472 | %token FOR_REST_STATEMENT 473 | %token WHILE_STATEMENT 474 | %token DO_STATEMENT 475 | %token FOR_STATEMENT 476 | %token CASE_LABEL 477 | %token CONDITION_OPT 478 | %token ASSIGNMENT_CONDITION 479 | %token EXPRESSION_CONDITION 480 | %token FUNCTION_HEADER 481 | %token FUNCTION_DECLARATION 482 | %token FUNCTION_PARAMETER_LIST 483 | %token PARAMETER_DECLARATION 484 | %token PARAMETER_DECLARATOR 485 | %token UNINITIALIZED_DECLARATION 486 | %token ARRAY_SPECIFIER 487 | %token ARRAY_SPECIFIER_LIST 488 | %token STRUCT_DECLARATOR_LIST 489 | %token FUNCTION_CALL_PARAMETER_LIST 490 | %token STRUCT_DECLARATION_LIST 491 | %token LAYOUT_QUALIFIER_ID 492 | %token LAYOUT_QUALIFIER_ID_LIST 493 | %token SUBROUTINE_TYPE 494 | %token PAREN_EXPRESSION 495 | %token INIT_DECLARATOR 496 | %token INITIALIZER 497 | %token TERNARY_EXPRESSION 498 | %token FIELD_IDENTIFIER 499 | 500 | %token NUM_GLSL_TOKEN 501 | 502 | %% 503 | 504 | root : { context->root = new_glsl_node(context, TRANSLATION_UNIT, NULL); } 505 | | translation_unit { context->root = $1; } 506 | ; 507 | 508 | translation_unit : external_declaration 509 | { $$ = new_glsl_node(context, TRANSLATION_UNIT, $1, NULL); } 510 | 511 | | translation_unit external_declaration 512 | { $$ = new_glsl_node(context, TRANSLATION_UNIT, $1, $2, NULL); } 513 | ; 514 | 515 | block_identifier : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 516 | ; 517 | 518 | decl_identifier : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 519 | ; 520 | 521 | struct_name : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 522 | ; 523 | 524 | type_name : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 525 | ; 526 | 527 | param_name : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 528 | ; 529 | 530 | function_name : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 531 | ; 532 | 533 | field_identifier : IDENTIFIER { $$ = new_glsl_string(context, FIELD_IDENTIFIER, $1); } 534 | ; 535 | 536 | variable_identifier : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 537 | ; 538 | 539 | layout_identifier : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 540 | ; 541 | 542 | type_specifier_identifier : IDENTIFIER { $$ = new_glsl_identifier(context, $1); } 543 | ; 544 | 545 | external_declaration : function_definition { $$ = $1; } 546 | | declaration { $$ = $1; } 547 | ; 548 | 549 | function_definition : function_prototype compound_statement_no_new_scope 550 | { $$ = new_glsl_node(context, FUNCTION_DEFINITION, 551 | $1, 552 | $2, 553 | NULL); } 554 | | function_prototype 555 | { $$ = new_glsl_node(context, FUNCTION_DEFINITION, 556 | $1, 557 | new_glsl_node(context, STATEMENT_LIST, NULL), 558 | NULL); } 559 | ; 560 | 561 | compound_statement_no_new_scope : LEFT_BRACE RIGHT_BRACE { $$ = new_glsl_node(context, STATEMENT_LIST, NULL); } 562 | | LEFT_BRACE statement_list RIGHT_BRACE { $$ = $2; } 563 | ; 564 | 565 | statement : compound_statement { $$ = $1; } 566 | | simple_statement { $$ = $1; } 567 | ; 568 | 569 | statement_list : statement { $$ = new_glsl_node(context, STATEMENT_LIST, $1, NULL); } 570 | | statement_list statement { $$ = new_glsl_node(context, STATEMENT_LIST, $1, $2, NULL); } 571 | ; 572 | 573 | compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = new_glsl_node(context, STATEMENT_LIST, NULL); } 574 | | LEFT_BRACE statement_list RIGHT_BRACE { $$ = $2; } 575 | ; 576 | 577 | simple_statement : declaration { $$ = $1; } 578 | | expression_statement { $$ = $1; } 579 | | selection_statement { $$ = $1; } 580 | | switch_statement { $$ = $1; } 581 | | case_label { $$= $1; } 582 | | iteration_statement { $$ = $1; } 583 | | jump_statement { $$ = $1; } 584 | ; 585 | 586 | declaration : function_prototype SEMICOLON { $$ = new_glsl_node(context, DECLARATION, $1, NULL); } 587 | | init_declarator_list SEMICOLON { $$ = new_glsl_node(context, DECLARATION, $1, NULL); } 588 | | PRECISION precision_qualifier type_specifier SEMICOLON 589 | { $$ = new_glsl_node(context, DECLARATION, 590 | new_glsl_node(context, PRECISION_DECLARATION, 591 | $2, 592 | $3, 593 | NULL), 594 | NULL); } 595 | | type_qualifier block_identifier LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON 596 | { $$ = new_glsl_node(context, DECLARATION, 597 | new_glsl_node(context, BLOCK_DECLARATION, 598 | $1, 599 | $2, 600 | $4, 601 | new_glsl_identifier(context, NULL), 602 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 603 | NULL), 604 | NULL); } 605 | | type_qualifier block_identifier LEFT_BRACE struct_declaration_list RIGHT_BRACE decl_identifier SEMICOLON 606 | { $$ = new_glsl_node(context, DECLARATION, 607 | new_glsl_node(context, BLOCK_DECLARATION, 608 | $1, 609 | $2, 610 | $4, 611 | $6, 612 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 613 | NULL), 614 | NULL); } 615 | | type_qualifier block_identifier LEFT_BRACE struct_declaration_list RIGHT_BRACE decl_identifier array_specifier_list SEMICOLON 616 | { $$ = new_glsl_node(context, DECLARATION, 617 | new_glsl_node(context, BLOCK_DECLARATION, 618 | $1, 619 | $2, 620 | $4, 621 | $6, 622 | $7, 623 | NULL), 624 | NULL); } 625 | | type_qualifier SEMICOLON 626 | { $$ = new_glsl_node(context, DECLARATION, 627 | new_glsl_node(context, UNINITIALIZED_DECLARATION, 628 | $1, 629 | new_glsl_identifier(context, NULL), 630 | NULL), 631 | NULL); } 632 | | type_qualifier type_name SEMICOLON 633 | { $$ = new_glsl_node(context, DECLARATION, 634 | new_glsl_node(context, UNINITIALIZED_DECLARATION, 635 | $1, 636 | $2, 637 | new_glsl_node(context, IDENTIFIER_LIST, NULL), 638 | NULL), 639 | NULL); } 640 | | type_qualifier type_name identifier_list SEMICOLON 641 | { $$ = new_glsl_node(context, DECLARATION, 642 | new_glsl_node(context, UNINITIALIZED_DECLARATION, 643 | $1, 644 | $2, 645 | $3, 646 | NULL), 647 | NULL); } 648 | ; 649 | 650 | identifier_list : COMMA decl_identifier { $$ = new_glsl_node(context, IDENTIFIER_LIST, $2, NULL); } 651 | | identifier_list COMMA decl_identifier 652 | { $$ = new_glsl_node(context, IDENTIFIER_LIST, $1, $3, NULL); } 653 | ; 654 | 655 | init_declarator_list : single_declaration { $$ = new_glsl_node(context, INIT_DECLARATOR_LIST, $1, NULL); } 656 | | init_declarator_list COMMA decl_identifier 657 | { $$ = new_glsl_node(context, INIT_DECLARATOR_LIST, 658 | $1, 659 | new_glsl_node(context, INIT_DECLARATOR, 660 | $3, 661 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 662 | NULL), 663 | NULL); } 664 | | init_declarator_list COMMA decl_identifier array_specifier_list 665 | { $$ = new_glsl_node(context, INIT_DECLARATOR_LIST, 666 | $1, 667 | new_glsl_node(context, INIT_DECLARATOR, 668 | $3, 669 | $4, 670 | NULL), 671 | NULL); } 672 | | init_declarator_list COMMA decl_identifier array_specifier_list EQUAL initializer 673 | { $$ = new_glsl_node(context, INIT_DECLARATOR_LIST, 674 | $1, 675 | new_glsl_node(context, INIT_DECLARATOR, 676 | $3, 677 | $4, 678 | $6, 679 | NULL), 680 | NULL); } 681 | | init_declarator_list COMMA decl_identifier EQUAL initializer 682 | { $$ = new_glsl_node(context, INIT_DECLARATOR_LIST, 683 | $1, 684 | new_glsl_node(context, INIT_DECLARATOR, 685 | $3, 686 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 687 | $5, 688 | NULL), 689 | NULL); } 690 | ; 691 | 692 | single_declaration : fully_specified_type 693 | { $$ = new_glsl_node(context, SINGLE_DECLARATION, 694 | $1, 695 | new_glsl_identifier(context, NULL), 696 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 697 | NULL); } 698 | 699 | | fully_specified_type decl_identifier 700 | { $$ = new_glsl_node(context, SINGLE_DECLARATION, 701 | $1, 702 | $2, 703 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 704 | NULL); } 705 | 706 | | fully_specified_type decl_identifier array_specifier_list 707 | { $$ = new_glsl_node(context, SINGLE_DECLARATION, $1, $2, $3, NULL); } 708 | 709 | | fully_specified_type decl_identifier array_specifier_list EQUAL initializer 710 | { $$ = new_glsl_node(context, SINGLE_INIT_DECLARATION, $1, $2, $3, $5, NULL); } 711 | 712 | | fully_specified_type decl_identifier EQUAL initializer 713 | { $$ = new_glsl_node(context, SINGLE_INIT_DECLARATION, 714 | $1, 715 | $2, 716 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 717 | $4, 718 | NULL); } 719 | ; 720 | 721 | initializer : assignment_expression { $$ = new_glsl_node(context, INITIALIZER, $1, NULL); } 722 | | LEFT_BRACE initializer_list RIGHT_BRACE { $$ = new_glsl_node(context, INITIALIZER, $2, NULL); } 723 | | LEFT_BRACE initializer_list COMMA RIGHT_BRACE { $$ = new_glsl_node(context, INITIALIZER, $2, NULL); } 724 | ; 725 | 726 | initializer_list : initializer 727 | { $$ = new_glsl_node(context, INITIALIZER_LIST, $1, NULL); } 728 | | initializer_list COMMA initializer 729 | { $$ = new_glsl_node(context, INITIALIZER_LIST, $1, $3, NULL); } 730 | ; 731 | 732 | expression_statement : SEMICOLON { $$ = new_glsl_node(context, EXPRESSION_STATEMENT, NULL); } 733 | | expression SEMICOLON { $$ = new_glsl_node(context, EXPRESSION_STATEMENT, $1, NULL); } 734 | ; 735 | 736 | selection_statement : IF LEFT_PAREN expression RIGHT_PAREN statement 737 | { $$ = new_glsl_node(context, SELECTION_STATEMENT, $3, $5, NULL); } 738 | 739 | | IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement 740 | { $$ = new_glsl_node(context, SELECTION_STATEMENT_ELSE, $3, $5, $7, NULL); } 741 | ; 742 | 743 | switch_statement : SWITCH LEFT_PAREN expression RIGHT_PAREN LEFT_BRACE switch_statement_list RIGHT_BRACE 744 | { $$ = new_glsl_node(context, SWITCH_STATEMENT, $3, $6, NULL); } 745 | ; 746 | 747 | switch_statement_list : { $$ = new_glsl_node(context, STATEMENT_LIST, NULL); } 748 | | statement_list { $$ = $1; } 749 | ; 750 | 751 | case_label : CASE expression COLON { $$ = new_glsl_node(context, CASE_LABEL, $2, NULL); } 752 | | DEFAULT COLON { $$ = new_glsl_node(context, CASE_LABEL, NULL); } 753 | ; 754 | 755 | iteration_statement : WHILE LEFT_PAREN condition RIGHT_PAREN statement_no_new_scope 756 | { $$ = new_glsl_node(context, WHILE_STATEMENT, $3, $5, NULL); } 757 | 758 | | DO statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON 759 | { $$ = new_glsl_node(context, DO_STATEMENT, $2, $5, NULL); } 760 | 761 | | FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope 762 | { $$ = new_glsl_node(context, FOR_STATEMENT, $3, $4, $6, NULL); } 763 | ; 764 | 765 | statement_no_new_scope : compound_statement_no_new_scope { $$ = $1; } 766 | | simple_statement { $$ = $1; } 767 | ; 768 | 769 | for_init_statement : expression_statement { $$ = $1; } 770 | | declaration { $$ = $1; } 771 | ; 772 | 773 | conditionopt : condition { $$ = new_glsl_node(context, CONDITION_OPT, $1, NULL); } 774 | | { $$ = new_glsl_node(context, CONDITION_OPT, NULL); } 775 | ; 776 | 777 | condition : expression 778 | { $$ = new_glsl_node(context, EXPRESSION_CONDITION, $1, NULL); } 779 | 780 | | fully_specified_type variable_identifier EQUAL initializer 781 | { $$ = new_glsl_node(context, ASSIGNMENT_CONDITION, $1, $2, $4, NULL); } 782 | ; 783 | 784 | for_rest_statement : conditionopt SEMICOLON 785 | { $$ = new_glsl_node(context, FOR_REST_STATEMENT, $1, NULL); } 786 | 787 | | conditionopt SEMICOLON expression 788 | { $$ = new_glsl_node(context, FOR_REST_STATEMENT, $1, $3, NULL); } 789 | ; 790 | 791 | jump_statement : CONTINUE SEMICOLON 792 | { $$ = new_glsl_node(context, CONTINUE, NULL); } 793 | 794 | | BREAK SEMICOLON 795 | { $$ = new_glsl_node(context, BREAK, NULL); } 796 | 797 | | RETURN SEMICOLON 798 | { $$ = new_glsl_node(context, RETURN, NULL); } 799 | 800 | | RETURN expression SEMICOLON 801 | { $$ = new_glsl_node(context, RETURN_VALUE, $2, NULL); } 802 | 803 | | DISCARD SEMICOLON 804 | { $$ = new_glsl_node(context, DISCARD, NULL); } 805 | ; 806 | 807 | function_prototype : function_declarator RIGHT_PAREN { $$ = $1; } 808 | ; 809 | 810 | function_declarator : function_header 811 | { $$ = new_glsl_node(context, FUNCTION_DECLARATION, 812 | $1, 813 | new_glsl_node(context, FUNCTION_PARAMETER_LIST, NULL), 814 | NULL); } 815 | 816 | | function_header function_parameter_list 817 | { $$ = new_glsl_node(context, FUNCTION_DECLARATION, 818 | $1, 819 | $2, 820 | NULL); } 821 | ; 822 | 823 | function_parameter_list : parameter_declaration 824 | { $$ = new_glsl_node(context, FUNCTION_PARAMETER_LIST, $1, NULL); } 825 | 826 | | function_parameter_list COMMA parameter_declaration 827 | { $$ = new_glsl_node(context, FUNCTION_PARAMETER_LIST, $1, $3, NULL); } 828 | ; 829 | 830 | parameter_declaration : type_qualifier parameter_declarator 831 | { $$ = new_glsl_node(context, PARAMETER_DECLARATION, $1, $2, NULL); } 832 | 833 | | parameter_declarator 834 | { $$ = new_glsl_node(context, PARAMETER_DECLARATION, 835 | new_glsl_node(context, TYPE_QUALIFIER_LIST, NULL), 836 | $1, 837 | NULL); } 838 | 839 | | type_qualifier parameter_type_specifier 840 | { $$ = new_glsl_node(context, PARAMETER_DECLARATION, $1, $2, NULL); } 841 | 842 | | parameter_type_specifier 843 | { $$ = new_glsl_node(context, PARAMETER_DECLARATION, 844 | new_glsl_node(context, TYPE_QUALIFIER_LIST, NULL), 845 | $1, 846 | NULL); } 847 | ; 848 | 849 | parameter_declarator : type_specifier param_name 850 | { $$ = new_glsl_node(context, PARAMETER_DECLARATOR, $1, $2, NULL); } 851 | 852 | | type_specifier param_name array_specifier_list 853 | { $$ = new_glsl_node(context, PARAMETER_DECLARATOR, $1, $2, $3, NULL);} 854 | ; 855 | 856 | function_header : fully_specified_type function_name LEFT_PAREN 857 | { $$ = new_glsl_node(context, FUNCTION_HEADER, $1, $2, NULL); } 858 | ; 859 | 860 | fully_specified_type : type_specifier 861 | { $$ = new_glsl_node(context, FULLY_SPECIFIED_TYPE, 862 | new_glsl_node(context, TYPE_QUALIFIER_LIST, NULL), 863 | $1, 864 | NULL); } 865 | 866 | | type_qualifier type_specifier 867 | { $$ = new_glsl_node(context, FULLY_SPECIFIED_TYPE, $1, $2, NULL); } 868 | ; 869 | 870 | parameter_type_specifier : type_specifier 871 | { $$ = new_glsl_node(context, PARAMETER_DECLARATOR, $1, NULL); } 872 | ; 873 | 874 | type_specifier : type_specifier_nonarray 875 | { $$ = new_glsl_node(context, TYPE_SPECIFIER, 876 | $1, 877 | new_glsl_node(context, ARRAY_SPECIFIER_LIST, NULL), 878 | NULL); } 879 | 880 | | type_specifier_nonarray array_specifier_list 881 | { $$ = new_glsl_node(context, TYPE_SPECIFIER, $1, $2, NULL); } 882 | ; 883 | 884 | array_specifier_list : array_specifier 885 | { $$ = new_glsl_node(context, ARRAY_SPECIFIER_LIST, $1, NULL); } 886 | 887 | | array_specifier_list array_specifier 888 | { $$ = new_glsl_node(context, ARRAY_SPECIFIER_LIST, $1, $2, NULL); } 889 | ; 890 | 891 | array_specifier : LEFT_BRACKET RIGHT_BRACKET 892 | { $$ = new_glsl_node(context, ARRAY_SPECIFIER, NULL); } 893 | 894 | | LEFT_BRACKET constant_expression RIGHT_BRACKET 895 | { $$ = new_glsl_node(context, ARRAY_SPECIFIER, $2, NULL); } 896 | ; 897 | 898 | type_specifier_nonarray : VOID { $$ = new_glsl_node(context, VOID, NULL); } 899 | | FLOAT { $$ = new_glsl_node(context, FLOAT, NULL); } 900 | | DOUBLE { $$ = new_glsl_node(context, DOUBLE, NULL); } 901 | | INT { $$ = new_glsl_node(context, INT, NULL); } 902 | | UINT { $$ = new_glsl_node(context, UINT, NULL); } 903 | | BOOL { $$ = new_glsl_node(context, BOOL, NULL); } 904 | | VEC2 { $$ = new_glsl_node(context, VEC2, NULL); } 905 | | VEC3 { $$ = new_glsl_node(context, VEC3, NULL); } 906 | | VEC4 { $$ = new_glsl_node(context, VEC4, NULL); } 907 | | DVEC2 { $$ = new_glsl_node(context, DVEC2, NULL); } 908 | | DVEC3 { $$ = new_glsl_node(context, DVEC3, NULL); } 909 | | DVEC4 { $$ = new_glsl_node(context, DVEC4, NULL); } 910 | | BVEC2 { $$ = new_glsl_node(context, BVEC2, NULL); } 911 | | BVEC3 { $$ = new_glsl_node(context, BVEC3, NULL); } 912 | | BVEC4 { $$ = new_glsl_node(context, BVEC4, NULL); } 913 | | IVEC2 { $$ = new_glsl_node(context, IVEC2, NULL); } 914 | | IVEC3 { $$ = new_glsl_node(context, IVEC3, NULL); } 915 | | IVEC4 { $$ = new_glsl_node(context, IVEC4, NULL); } 916 | | UVEC2 { $$ = new_glsl_node(context, UVEC2, NULL); } 917 | | UVEC3 { $$ = new_glsl_node(context, UVEC3, NULL); } 918 | | UVEC4 { $$ = new_glsl_node(context, UVEC4, NULL); } 919 | | MAT2 { $$ = new_glsl_node(context, MAT2, NULL); } 920 | | MAT3 { $$ = new_glsl_node(context, MAT3, NULL); } 921 | | MAT4 { $$ = new_glsl_node(context, MAT4, NULL); } 922 | | MAT2X2 { $$ = new_glsl_node(context, MAT2X2, NULL); } 923 | | MAT2X3 { $$ = new_glsl_node(context, MAT2X3, NULL); } 924 | | MAT2X4 { $$ = new_glsl_node(context, MAT2X4, NULL); } 925 | | MAT3X2 { $$ = new_glsl_node(context, MAT3X2, NULL); } 926 | | MAT3X3 { $$ = new_glsl_node(context, MAT3X3, NULL); } 927 | | MAT3X4 { $$ = new_glsl_node(context, MAT3X4, NULL); } 928 | | MAT4X2 { $$ = new_glsl_node(context, MAT4X2, NULL); } 929 | | MAT4X3 { $$ = new_glsl_node(context, MAT4X3, NULL); } 930 | | MAT4X4 { $$ = new_glsl_node(context, MAT4X4, NULL); } 931 | | DMAT2 { $$ = new_glsl_node(context, DMAT2, NULL); } 932 | | DMAT3 { $$ = new_glsl_node(context, DMAT3, NULL); } 933 | | DMAT4 { $$ = new_glsl_node(context, DMAT4, NULL); } 934 | | DMAT2X2 { $$ = new_glsl_node(context, DMAT2X2, NULL); } 935 | | DMAT2X3 { $$ = new_glsl_node(context, DMAT2X3, NULL); } 936 | | DMAT2X4 { $$ = new_glsl_node(context, DMAT2X4, NULL); } 937 | | DMAT3X2 { $$ = new_glsl_node(context, DMAT3X2, NULL); } 938 | | DMAT3X3 { $$ = new_glsl_node(context, DMAT3X3, NULL); } 939 | | DMAT3X4 { $$ = new_glsl_node(context, DMAT3X4, NULL); } 940 | | DMAT4X2 { $$ = new_glsl_node(context, DMAT4X2, NULL); } 941 | | DMAT4X3 { $$ = new_glsl_node(context, DMAT4X3, NULL); } 942 | | DMAT4X4 { $$ = new_glsl_node(context, DMAT4X4, NULL); } 943 | | ATOMIC_UINT { $$ = new_glsl_node(context, UINT, NULL); } 944 | | SAMPLER1D { $$ = new_glsl_node(context, SAMPLER1D, NULL); } 945 | | SAMPLER2D { $$ = new_glsl_node(context, SAMPLER2D, NULL); } 946 | | SAMPLER3D { $$ = new_glsl_node(context, SAMPLER3D, NULL); } 947 | | SAMPLERCUBE { $$ = new_glsl_node(context, SAMPLERCUBE, NULL); } 948 | | SAMPLER1DSHADOW { $$ = new_glsl_node(context, SAMPLER1DSHADOW, NULL); } 949 | | SAMPLER2DSHADOW { $$ = new_glsl_node(context, SAMPLER2DSHADOW, NULL); } 950 | | SAMPLERCUBESHADOW { $$ = new_glsl_node(context, SAMPLERCUBESHADOW, NULL); } 951 | | SAMPLER1DARRAY { $$ = new_glsl_node(context, SAMPLER1DARRAY, NULL); } 952 | | SAMPLER2DARRAY { $$ = new_glsl_node(context, SAMPLER2DARRAY, NULL); } 953 | | SAMPLER1DARRAYSHADOW { $$ = new_glsl_node(context, SAMPLER1DARRAYSHADOW, NULL); } 954 | | SAMPLER2DARRAYSHADOW { $$ = new_glsl_node(context, SAMPLER2DARRAYSHADOW, NULL); } 955 | | SAMPLERCUBEARRAY { $$ = new_glsl_node(context, SAMPLERCUBEARRAY, NULL); } 956 | | SAMPLERCUBEARRAYSHADOW { $$ = new_glsl_node(context, SAMPLERCUBEARRAYSHADOW, NULL); } 957 | | ISAMPLER1D { $$ = new_glsl_node(context, ISAMPLER1D, NULL); } 958 | | ISAMPLER2D { $$ = new_glsl_node(context, ISAMPLER2D, NULL); } 959 | | ISAMPLER3D { $$ = new_glsl_node(context, ISAMPLER3D, NULL); } 960 | | ISAMPLERCUBE { $$ = new_glsl_node(context, ISAMPLERCUBE, NULL); } 961 | | ISAMPLER1DARRAY { $$ = new_glsl_node(context, ISAMPLER1DARRAY, NULL); } 962 | | ISAMPLER2DARRAY { $$ = new_glsl_node(context, ISAMPLER2DARRAY, NULL); } 963 | | ISAMPLERCUBEARRAY { $$ = new_glsl_node(context, ISAMPLERCUBEARRAY, NULL); } 964 | | USAMPLER1D { $$ = new_glsl_node(context, USAMPLER1D, NULL); } 965 | | USAMPLER2D { $$ = new_glsl_node(context, USAMPLER2D, NULL); } 966 | | USAMPLER3D { $$ = new_glsl_node(context, USAMPLER3D, NULL); } 967 | | USAMPLERCUBE { $$ = new_glsl_node(context, USAMPLERCUBE, NULL); } 968 | | USAMPLER1DARRAY { $$ = new_glsl_node(context, USAMPLER1DARRAY, NULL); } 969 | | USAMPLER2DARRAY { $$ = new_glsl_node(context, USAMPLER2DARRAY, NULL); } 970 | | USAMPLERCUBEARRAY { $$ = new_glsl_node(context, USAMPLERCUBEARRAY, NULL); } 971 | | SAMPLER2DRECT { $$ = new_glsl_node(context, SAMPLER2DRECT, NULL); } 972 | | SAMPLER2DRECTSHADOW { $$ = new_glsl_node(context, SAMPLER2DRECTSHADOW, NULL); } 973 | | ISAMPLER2DRECT { $$ = new_glsl_node(context, ISAMPLER2DRECT, NULL); } 974 | | USAMPLER2DRECT { $$ = new_glsl_node(context, USAMPLER2DRECT, NULL); } 975 | | SAMPLERBUFFER { $$ = new_glsl_node(context, SAMPLERBUFFER, NULL); } 976 | | ISAMPLERBUFFER { $$ = new_glsl_node(context, ISAMPLERBUFFER, NULL); } 977 | | USAMPLERBUFFER { $$ = new_glsl_node(context, USAMPLERBUFFER, NULL); } 978 | | SAMPLER2DMS { $$ = new_glsl_node(context, SAMPLER2DMS, NULL); } 979 | | ISAMPLER2DMS { $$ = new_glsl_node(context, ISAMPLER2DMS, NULL); } 980 | | USAMPLER2DMS { $$ = new_glsl_node(context, USAMPLER2DMS, NULL); } 981 | | SAMPLER2DMSARRAY { $$ = new_glsl_node(context, SAMPLER2DMSARRAY, NULL); } 982 | | ISAMPLER2DMSARRAY { $$ = new_glsl_node(context, ISAMPLER2DMSARRAY, NULL); } 983 | | USAMPLER2DMSARRAY { $$ = new_glsl_node(context, USAMPLER2DMSARRAY, NULL); } 984 | | IMAGE1D { $$ = new_glsl_node(context, IMAGE1D, NULL); } 985 | | IIMAGE1D { $$ = new_glsl_node(context, IIMAGE1D, NULL); } 986 | | UIMAGE1D { $$ = new_glsl_node(context, UIMAGE1D, NULL); } 987 | | IMAGE2D { $$ = new_glsl_node(context, IMAGE2D, NULL); } 988 | | IIMAGE2D { $$ = new_glsl_node(context, IIMAGE2D, NULL); } 989 | | UIMAGE2D { $$ = new_glsl_node(context, UIMAGE2D, NULL); } 990 | | IMAGE3D { $$ = new_glsl_node(context, IMAGE3D, NULL); } 991 | | IIMAGE3D { $$ = new_glsl_node(context, IIMAGE3D, NULL); } 992 | | UIMAGE3D { $$ = new_glsl_node(context, UIMAGE3D, NULL); } 993 | | IMAGE2DRECT { $$ = new_glsl_node(context, IMAGE2DRECT, NULL); } 994 | | IIMAGE2DRECT { $$ = new_glsl_node(context, IIMAGE2DRECT, NULL); } 995 | | UIMAGE2DRECT { $$ = new_glsl_node(context, UIMAGE2DRECT, NULL); } 996 | | IMAGECUBE { $$ = new_glsl_node(context, IMAGECUBE, NULL); } 997 | | IIMAGECUBE { $$ = new_glsl_node(context, IIMAGECUBE, NULL); } 998 | | UIMAGECUBE { $$ = new_glsl_node(context, UIMAGECUBE, NULL); } 999 | | IMAGEBUFFER { $$ = new_glsl_node(context, IMAGEBUFFER, NULL); } 1000 | | IIMAGEBUFFER { $$ = new_glsl_node(context, IIMAGEBUFFER, NULL); } 1001 | | UIMAGEBUFFER { $$ = new_glsl_node(context, UIMAGEBUFFER, NULL); } 1002 | | IMAGE1DARRAY { $$ = new_glsl_node(context, IMAGE1DARRAY, NULL); } 1003 | | IIMAGE1DARRAY { $$ = new_glsl_node(context, IIMAGE1DARRAY, NULL); } 1004 | | UIMAGE1DARRAY { $$ = new_glsl_node(context, UIMAGE1DARRAY, NULL); } 1005 | | IMAGE2DARRAY { $$ = new_glsl_node(context, IMAGE2DARRAY, NULL); } 1006 | | IIMAGE2DARRAY { $$ = new_glsl_node(context, IIMAGE2DARRAY, NULL); } 1007 | | UIMAGE2DARRAY { $$ = new_glsl_node(context, UIMAGE2DARRAY, NULL); } 1008 | | IMAGECUBEARRAY { $$ = new_glsl_node(context, IMAGECUBEARRAY, NULL); } 1009 | | IIMAGECUBEARRAY { $$ = new_glsl_node(context, IIMAGECUBEARRAY, NULL); } 1010 | | UIMAGECUBEARRAY { $$ = new_glsl_node(context, UIMAGECUBEARRAY, NULL); } 1011 | | IMAGE2DMS { $$ = new_glsl_node(context, IMAGE2DMS, NULL); } 1012 | | IIMAGE2DMS { $$ = new_glsl_node(context, IIMAGE2DMS, NULL); } 1013 | | UIMAGE2DMS { $$ = new_glsl_node(context, UIMAGE2DMS, NULL); } 1014 | | IMAGE2DMSARRAY { $$ = new_glsl_node(context, IMAGE2DMSARRAY, NULL); } 1015 | | IIMAGE2DMSARRAY { $$ = new_glsl_node(context, IIMAGE2DMSARRAY, NULL); } 1016 | | UIMAGE2DMSARRAY { $$ = new_glsl_node(context, UIMAGE2DMSARRAY, NULL); } 1017 | | struct_specifier { $$ = $1; } 1018 | | type_specifier_identifier { $$ = $1; } 1019 | ; 1020 | 1021 | struct_specifier : STRUCT struct_name LEFT_BRACE struct_declaration_list RIGHT_BRACE 1022 | { $$ = new_glsl_node(context, STRUCT_SPECIFIER, $2, $4, NULL);} 1023 | 1024 | | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE 1025 | { $$ = new_glsl_node(context, STRUCT_SPECIFIER, 1026 | new_glsl_identifier(context, NULL), 1027 | $3, 1028 | NULL); } 1029 | ; 1030 | 1031 | struct_declaration_list : struct_declaration 1032 | { $$ = new_glsl_node(context, STRUCT_DECLARATION_LIST, $1, NULL); } 1033 | | struct_declaration_list struct_declaration 1034 | { $$ = new_glsl_node(context, STRUCT_DECLARATION_LIST, $1, $2, NULL); } 1035 | ; 1036 | 1037 | struct_declaration : type_specifier struct_declarator_list SEMICOLON 1038 | { $$ = new_glsl_node(context, STRUCT_DECLARATION, 1039 | new_glsl_node(context, TYPE_QUALIFIER_LIST, NULL), 1040 | $1, 1041 | $2, 1042 | NULL); } 1043 | 1044 | | type_qualifier type_specifier struct_declarator_list SEMICOLON 1045 | { $$ = new_glsl_node(context, STRUCT_DECLARATION, $1, $2, $3, NULL); } 1046 | ; 1047 | 1048 | struct_declarator_list : struct_declarator 1049 | { $$ = new_glsl_node(context, STRUCT_DECLARATOR_LIST, $1, NULL); } 1050 | 1051 | | struct_declarator_list COMMA struct_declarator 1052 | { $$ = new_glsl_node(context, STRUCT_DECLARATOR_LIST, $1, $3, NULL); } 1053 | ; 1054 | 1055 | struct_declarator : field_identifier 1056 | { $$ = new_glsl_node(context, STRUCT_DECLARATOR, $1, NULL); } 1057 | 1058 | | field_identifier array_specifier_list 1059 | { $$ = new_glsl_node(context, STRUCT_DECLARATOR, $1, $2, NULL); } 1060 | ; 1061 | 1062 | type_qualifier : single_type_qualifier 1063 | { $$ = new_glsl_node(context, TYPE_QUALIFIER_LIST, $1, NULL); } 1064 | | type_qualifier single_type_qualifier 1065 | { $$ = new_glsl_node(context, TYPE_QUALIFIER_LIST, $1, $2, NULL); } 1066 | ; 1067 | 1068 | single_type_qualifier : storage_qualifier { $$ = $1; } 1069 | | layout_qualifier { $$ = $1; } 1070 | | precision_qualifier { $$ = $1; } 1071 | | interpolation_qualifier { $$ = $1; } 1072 | | invariant_qualifier { $$ = $1; } 1073 | | precise_qualifier { $$ = $1; } 1074 | ; 1075 | 1076 | layout_qualifier : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { $$ = $3; } 1077 | ; 1078 | 1079 | layout_qualifier_id_list: layout_qualifier_id { $$ = $1; } 1080 | 1081 | | layout_qualifier_id_list COMMA layout_qualifier_id 1082 | { $$ = new_glsl_node(context, LAYOUT_QUALIFIER_ID_LIST, $1, $3, NULL); } 1083 | ; 1084 | 1085 | layout_qualifier_id : layout_identifier 1086 | { $$ = new_glsl_node(context, LAYOUT_QUALIFIER_ID, $1, NULL); } 1087 | 1088 | | layout_identifier EQUAL constant_expression 1089 | { $$ = new_glsl_node(context, LAYOUT_QUALIFIER_ID, $1, $3, NULL);} 1090 | 1091 | | SHARED 1092 | { $$ = new_glsl_node(context, SHARED, NULL); } 1093 | ; 1094 | 1095 | precision_qualifier : HIGHP { $$ = new_glsl_node(context, HIGHP, NULL); } 1096 | | MEDIUMP { $$ = new_glsl_node(context, MEDIUMP, NULL); } 1097 | | LOWP { $$ = new_glsl_node(context, LOWP, NULL); } 1098 | ; 1099 | 1100 | interpolation_qualifier : SMOOTH { $$ = new_glsl_node(context, SMOOTH, NULL); } 1101 | | FLAT { $$ = new_glsl_node(context, FLAT, NULL); } 1102 | | NOPERSPECTIVE { $$ = new_glsl_node(context, NOPERSPECTIVE, NULL); } 1103 | ; 1104 | 1105 | invariant_qualifier : INVARIANT { $$ = new_glsl_node(context, INVARIANT, NULL); } 1106 | ; 1107 | 1108 | precise_qualifier : PRECISE { $$ = new_glsl_node(context, PRECISE, NULL); } 1109 | ; 1110 | 1111 | storage_qualifier : CONST { $$ = new_glsl_node(context, CONST, NULL); } 1112 | | INOUT { $$ = new_glsl_node(context, INOUT, NULL); } 1113 | | IN { $$ = new_glsl_node(context, IN, NULL); } 1114 | | OUT { $$ = new_glsl_node(context, OUT, NULL); } 1115 | | CENTROID { $$ = new_glsl_node(context, CENTROID, NULL); } 1116 | | PATCH { $$ = new_glsl_node(context, PATCH, NULL); } 1117 | | SAMPLE { $$ = new_glsl_node(context, SAMPLE, NULL); } 1118 | | UNIFORM { $$ = new_glsl_node(context, UNIFORM, NULL); } 1119 | | BUFFER { $$ = new_glsl_node(context, BUFFER, NULL); } 1120 | | SHARED { $$ = new_glsl_node(context, SHARED, NULL); } 1121 | | COHERENT { $$ = new_glsl_node(context, COHERENT, NULL); } 1122 | | VOLATILE { $$ = new_glsl_node(context, VOLATILE, NULL); } 1123 | | RESTRICT { $$ = new_glsl_node(context, RESTRICT, NULL); } 1124 | | READONLY { $$ = new_glsl_node(context, READONLY, NULL); } 1125 | | WRITEONLY { $$ = new_glsl_node(context, WRITEONLY, NULL); } 1126 | | SUBROUTINE { $$ = new_glsl_node(context, SUBROUTINE, NULL); } 1127 | | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN 1128 | { $$ = new_glsl_node(context, SUBROUTINE_TYPE, 1129 | new_glsl_node(context, TYPE_NAME_LIST, $3, NULL), 1130 | NULL); } 1131 | ; 1132 | 1133 | type_name_list : type_name { $$ = $1; } 1134 | | type_name_list COMMA type_name 1135 | { $$ = new_glsl_node(context, TYPE_NAME_LIST, $1, $3, NULL); } 1136 | ; 1137 | 1138 | expression : assignment_expression { $$ = $1; } 1139 | | expression COMMA assignment_expression 1140 | { $$ = new_glsl_node(context, COMMA, $1, $3, NULL); } 1141 | ; 1142 | 1143 | assignment_expression : conditional_expression { $$ = $1; } 1144 | | unary_expression assignment_operator assignment_expression 1145 | { $$ = new_glsl_node(context,$2, $1, $3, NULL); } 1146 | ; 1147 | 1148 | assignment_operator : EQUAL { $$ = EQUAL; } 1149 | | MUL_ASSIGN { $$ = MUL_ASSIGN; } 1150 | | DIV_ASSIGN { $$ = DIV_ASSIGN; } 1151 | | MOD_ASSIGN { $$ = MOD_ASSIGN; } 1152 | | ADD_ASSIGN { $$ = ADD_ASSIGN; } 1153 | | SUB_ASSIGN { $$ = SUB_ASSIGN; } 1154 | | LEFT_ASSIGN { $$ = LEFT_ASSIGN; } 1155 | | RIGHT_ASSIGN { $$ = RIGHT_ASSIGN; } 1156 | | AND_ASSIGN { $$ = AND_ASSIGN; } 1157 | | XOR_ASSIGN { $$ = XOR_ASSIGN; } 1158 | | OR_ASSIGN { $$ = OR_ASSIGN; } 1159 | ; 1160 | 1161 | constant_expression : conditional_expression { $$ = $1; } 1162 | ; 1163 | 1164 | conditional_expression : logical_or_expression { $$ = $1; } 1165 | | logical_or_expression QUESTION expression COLON assignment_expression 1166 | { $$ = new_glsl_node(context, TERNARY_EXPRESSION, $1, $3, $5, NULL); } 1167 | ; 1168 | 1169 | logical_or_expression : logical_xor_expression { $$ = $1; } 1170 | | logical_or_expression OR_OP logical_xor_expression 1171 | { $$ = new_glsl_node(context, OR_OP, $1, $3, NULL); } 1172 | ; 1173 | 1174 | logical_xor_expression : logical_and_expression { $$ = $1; } 1175 | | logical_xor_expression XOR_OP logical_and_expression 1176 | { $$ = new_glsl_node(context, XOR_OP, $1, $3, NULL); } 1177 | ; 1178 | 1179 | logical_and_expression : inclusive_or_expression { $$ = $1; } 1180 | | logical_and_expression AND_OP inclusive_or_expression 1181 | { $$ = new_glsl_node(context, AND_OP, $1, $3, NULL); } 1182 | ; 1183 | 1184 | inclusive_or_expression : exclusive_or_expression { $$ = $1; } 1185 | | inclusive_or_expression VERTICAL_BAR exclusive_or_expression 1186 | { $$ = new_glsl_node(context, VERTICAL_BAR, $1, $3, NULL); } 1187 | ; 1188 | 1189 | exclusive_or_expression : and_expression { $$ = $1; } 1190 | | exclusive_or_expression CARET and_expression 1191 | { $$ = new_glsl_node(context, CARET, $1, $3, NULL); } 1192 | ; 1193 | 1194 | and_expression : equality_expression { $$ = $1; } 1195 | | and_expression AMPERSAND equality_expression 1196 | { $$ = new_glsl_node(context, AMPERSAND, $1, $3, NULL); } 1197 | ; 1198 | 1199 | equality_expression : relational_expression { $$ = $1; } 1200 | 1201 | | equality_expression EQ_OP relational_expression 1202 | { $$ = new_glsl_node(context, EQ_OP, $1, $3, NULL); } 1203 | 1204 | | equality_expression NE_OP relational_expression 1205 | { $$ = new_glsl_node(context, NE_OP, $1, $3, NULL); } 1206 | ; 1207 | 1208 | relational_expression : shift_expression { $$ = $1; } 1209 | 1210 | | relational_expression LEFT_ANGLE shift_expression 1211 | { $$ = new_glsl_node(context, LEFT_ANGLE, $1, $3, NULL); } 1212 | 1213 | | relational_expression RIGHT_ANGLE shift_expression 1214 | { $$ = new_glsl_node(context, RIGHT_ANGLE, $1, $3, NULL); } 1215 | 1216 | | relational_expression LE_OP shift_expression 1217 | { $$ = new_glsl_node(context, LE_OP, $1, $3, NULL); } 1218 | 1219 | | relational_expression GE_OP shift_expression 1220 | { $$ = new_glsl_node(context, GE_OP, $1, $3, NULL); } 1221 | ; 1222 | 1223 | shift_expression : additive_expression { $$ = $1; } 1224 | 1225 | | shift_expression LEFT_OP additive_expression 1226 | { $$ = new_glsl_node(context, LEFT_OP, $1, $3, NULL); } 1227 | 1228 | | shift_expression RIGHT_OP additive_expression 1229 | { $$ = new_glsl_node(context, RIGHT_OP, $1, $3, NULL); } 1230 | ; 1231 | 1232 | additive_expression : multiplicative_expression { $$ = $1; } 1233 | 1234 | | additive_expression PLUS multiplicative_expression 1235 | { $$ = new_glsl_node(context, PLUS, $1, $3, NULL); } 1236 | 1237 | | additive_expression DASH multiplicative_expression 1238 | { $$ = new_glsl_node(context, DASH, $1, $3, NULL); } 1239 | ; 1240 | 1241 | multiplicative_expression : unary_expression { $$ = $1; } 1242 | 1243 | | multiplicative_expression STAR unary_expression 1244 | { $$ = new_glsl_node(context, STAR, $1, $3, NULL); } 1245 | 1246 | | multiplicative_expression SLASH unary_expression 1247 | { $$ = new_glsl_node(context, SLASH, $1, $3, NULL); } 1248 | 1249 | | multiplicative_expression PERCENT unary_expression 1250 | { $$ = new_glsl_node(context, PERCENT, $1, $3, NULL); } 1251 | ; 1252 | 1253 | unary_expression : postfix_expression { $$ = $1; } 1254 | 1255 | | INC_OP unary_expression 1256 | { $$ = new_glsl_node(context, PRE_INC_OP, $2, NULL); } 1257 | 1258 | | DEC_OP unary_expression 1259 | { $$ = new_glsl_node(context, PRE_DEC_OP, $2, NULL); } 1260 | 1261 | | unary_operator unary_expression 1262 | { $$ = new_glsl_node(context,$1, $2, NULL); } 1263 | ; 1264 | 1265 | unary_operator : PLUS { $$ = UNARY_PLUS; } 1266 | | DASH { $$ = UNARY_DASH; } 1267 | | BANG { $$ = BANG; } 1268 | | TILDE { $$ = TILDE; } 1269 | ; 1270 | 1271 | postfix_expression : primary_expression { $$ = $1; } 1272 | 1273 | | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET 1274 | { $$ = new_glsl_node(context, ARRAY_REF_OP, $1, $3, NULL); } 1275 | 1276 | | function_call { $$ = $1; } 1277 | 1278 | | postfix_expression DOT field_identifier 1279 | { $$ = new_glsl_node(context, DOT, $1, $3, NULL);} 1280 | 1281 | | postfix_expression INC_OP 1282 | { $$ = new_glsl_node(context, POST_INC_OP, $1, NULL); } 1283 | 1284 | | postfix_expression DEC_OP 1285 | { $$ = new_glsl_node(context, POST_DEC_OP, $1, NULL); } 1286 | ; 1287 | 1288 | integer_expression : expression { $$ = $1; } 1289 | ; 1290 | 1291 | function_call : function_call_or_method { $$ = $1; } 1292 | ; 1293 | 1294 | function_call_or_method : function_call_generic { $$ = $1; } 1295 | ; 1296 | 1297 | function_call_generic : function_identifier LEFT_PAREN function_call_parameter_list RIGHT_PAREN 1298 | { $$ = new_glsl_node(context, FUNCTION_CALL, $1, $3, NULL); } 1299 | 1300 | | function_identifier LEFT_PAREN LEFT_PAREN 1301 | { $$ = new_glsl_node(context, FUNCTION_CALL, 1302 | $1, 1303 | new_glsl_node(context, FUNCTION_CALL_PARAMETER_LIST, NULL), 1304 | NULL); } 1305 | 1306 | | function_identifier LEFT_PAREN VOID RIGHT_PAREN 1307 | { $$ = new_glsl_node(context, FUNCTION_CALL, 1308 | $1, 1309 | new_glsl_node(context, FUNCTION_CALL_PARAMETER_LIST, NULL), 1310 | NULL); } 1311 | ; 1312 | 1313 | function_call_parameter_list : assignment_expression 1314 | { $$ = new_glsl_node(context, FUNCTION_CALL_PARAMETER_LIST, $1, NULL); } 1315 | 1316 | | function_call_parameter_list COMMA assignment_expression 1317 | { $$ = new_glsl_node(context, FUNCTION_CALL_PARAMETER_LIST, $1, $3, NULL); } 1318 | ; 1319 | 1320 | function_identifier : type_specifier { $$ = $1; } 1321 | 1322 | | postfix_expression 1323 | { $$ = new_glsl_node(context, POSTFIX_EXPRESSION, $1, NULL); } 1324 | ; 1325 | 1326 | primary_expression : variable_identifier { $$ = $1; } 1327 | 1328 | | INTCONSTANT 1329 | { $$ = new_glsl_node(context, INTCONSTANT, NULL); $$->data.i = $1; } 1330 | 1331 | | UINTCONSTANT 1332 | { $$ = new_glsl_node(context, UINTCONSTANT, NULL); $$->data.ui = $1; } 1333 | 1334 | | FLOATCONSTANT 1335 | { $$ = new_glsl_node(context, FLOATCONSTANT, NULL); $$->data.f = $1; } 1336 | 1337 | | TRUE_VALUE 1338 | { $$ = new_glsl_node(context, TRUE_VALUE, NULL); } 1339 | 1340 | | FALSE_VALUE 1341 | { $$ = new_glsl_node(context, FALSE_VALUE, NULL); } 1342 | 1343 | | DOUBLECONSTANT 1344 | { $$ = new_glsl_node(context, DOUBLECONSTANT, NULL); $$->data.d = $1; } 1345 | 1346 | | LEFT_PAREN expression RIGHT_PAREN 1347 | { $$ = new_glsl_node(context, PAREN_EXPRESSION, $2, NULL); } 1348 | ; 1349 | 1350 | %% 1351 | 1352 | #include "glsl_ast.h" 1353 | 1354 | //The scanner macro, needed for integration with flex, causes problems below 1355 | #undef scanner 1356 | 1357 | static void glsl_error(GLSL_LTYPE *loc, struct glsl_parse_context *c, const char *s) 1358 | { 1359 | c->error = true; 1360 | if (c->error_cb) 1361 | c->error_cb(s, loc->first_line, loc->first_column, loc->last_column); 1362 | } 1363 | 1364 | int list_length(struct glsl_node *n, int list_token) 1365 | { 1366 | if (n->code != list_token) { 1367 | return 1; 1368 | } else { 1369 | int i; 1370 | int count = 0; 1371 | for (i = 0; i < n->child_count; i++) { 1372 | count += list_length(n->children[i], list_token); 1373 | } 1374 | return count; 1375 | } 1376 | } 1377 | 1378 | static void list_gather(struct glsl_node *n, struct glsl_node *new_list, int list_token) 1379 | { 1380 | int i; 1381 | for (i = 0; i < n->child_count; i++) { 1382 | struct glsl_node *child = n->children[i]; 1383 | if (child->code != list_token) 1384 | new_list->children[new_list->child_count++] = child; 1385 | else 1386 | list_gather(child, new_list, list_token); 1387 | } 1388 | } 1389 | 1390 | static void list_collapse(struct glsl_parse_context *context, struct glsl_node *n) 1391 | { 1392 | int i; 1393 | for (i = 0; i < n->child_count; i++) { 1394 | struct glsl_node *child = n->children[i]; 1395 | if (glsl_ast_is_list_node(child)) { 1396 | int list_token = child->code; 1397 | int length = list_length(child, list_token); 1398 | struct glsl_node *g = (struct glsl_node *)glsl_parse_alloc(context, offsetof(struct glsl_node, children[length]), 8); 1399 | g->code = list_token; 1400 | g->child_count = 0; 1401 | list_gather(child, g, list_token); 1402 | n->children[i] = g; 1403 | child = g; 1404 | } 1405 | list_collapse(context, child); 1406 | } 1407 | } 1408 | 1409 | static bool parse_internal(struct glsl_parse_context *context) 1410 | { 1411 | context->error = false; 1412 | glsl_parse(context); 1413 | if (context->root) { 1414 | if (glsl_ast_is_list_node(context->root)) { 1415 | // 1416 | // list_collapse() can't combine all the TRANSLATION_UNIT nodes 1417 | // since it would need to replace g_glsl_node_root so we combine 1418 | // the TRANSLATION_UNIT nodes here. 1419 | // 1420 | int list_code = context->root->code; 1421 | int length = list_length(context->root, list_code); 1422 | struct glsl_node *new_root = (struct glsl_node *)glsl_parse_alloc(context, offsetof(struct glsl_node, children[length]), 8); 1423 | new_root->code = TRANSLATION_UNIT; 1424 | new_root->child_count = 0; 1425 | list_gather(context->root, new_root, list_code); 1426 | assert(new_root->child_count == length); 1427 | context->root = new_root; 1428 | } 1429 | // 1430 | // Collapse other list nodes 1431 | // 1432 | list_collapse(context, context->root); 1433 | } 1434 | return context->error; 1435 | } 1436 | 1437 | bool glsl_parse_file(struct glsl_parse_context *context, FILE *file) 1438 | { 1439 | glsl_lex_init(&(context->scanner)); 1440 | 1441 | glsl_set_in(file, context->scanner); 1442 | 1443 | bool error; 1444 | 1445 | error = parse_internal(context); 1446 | 1447 | glsl_lex_destroy(context->scanner); 1448 | context->scanner = NULL; 1449 | return error; 1450 | } 1451 | 1452 | bool glsl_parse_string(struct glsl_parse_context *context, const char *str) 1453 | { 1454 | char *text; 1455 | size_t sz; 1456 | bool error; 1457 | 1458 | glsl_lex_init(&(context->scanner)); 1459 | 1460 | sz = strlen(str); 1461 | text = malloc(sz + 2); 1462 | strcpy(text, str); 1463 | text[sz + 1] = 0; 1464 | glsl__scan_buffer(text, sz + 2, context->scanner); 1465 | 1466 | error = parse_internal(context); 1467 | 1468 | free(text); 1469 | glsl_lex_destroy(context->scanner); 1470 | context->scanner = NULL; 1471 | return error; 1472 | } 1473 | 1474 | void glsl_parse_context_init(struct glsl_parse_context *context) 1475 | { 1476 | context->root = NULL; 1477 | context->scanner = NULL; 1478 | context->first_buffer = NULL; 1479 | context->cur_buffer_start = NULL; 1480 | context->cur_buffer = NULL; 1481 | context->cur_buffer_end = NULL; 1482 | context->error_cb = NULL; 1483 | context->error = false; 1484 | } 1485 | 1486 | void glsl_parse_set_error_cb(struct glsl_parse_context *context, glsl_parse_error_cb_t error_cb) 1487 | { 1488 | context->error_cb = error_cb; 1489 | } 1490 | 1491 | 1492 | void glsl_parse_context_destroy(struct glsl_parse_context *context) 1493 | { 1494 | glsl_parse_dealloc(context); 1495 | } 1496 | -------------------------------------------------------------------------------- /glsl_ast.c: -------------------------------------------------------------------------------- 1 | #include "glsl_ast.h" 2 | #include "glsl_parser.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static const char *token_to_str[4096] = { 10 | [CONST] = "const", 11 | [BOOL] = "bool", 12 | [FLOAT] = "float", 13 | [DOUBLE] = "double", 14 | [INT] = "int", 15 | [UINT] = "uint", 16 | [BREAK] = "break", 17 | [CONTINUE] = "continue", 18 | [DO] = "do", 19 | [ELSE] = "else", 20 | [FOR] = "for", 21 | [IF] = "if", 22 | [DISCARD] = "discard", 23 | [RETURN] = "return", 24 | [TRUE_VALUE] = "true", 25 | [FALSE_VALUE] = "false", 26 | [SWITCH] = "switch", 27 | [CASE] = "case", 28 | [DEFAULT] = "default", 29 | [SUBROUTINE] = "subroutine", 30 | [BVEC2] = "bvec2", 31 | [BVEC3] = "bvec3", 32 | [BVEC4] = "bvec4", 33 | [IVEC2] = "ivec2", 34 | [IVEC3] = "ivec3", 35 | [IVEC4] = "ivec4", 36 | [UVEC2] = "uvec2", 37 | [UVEC3] = "uvec3", 38 | [UVEC4] = "uvec4", 39 | [VEC2] = "vec2", 40 | [VEC3] = "vec3", 41 | [VEC4] = "vec4", 42 | [MAT2] = "mat2", 43 | [MAT3] = "mat3", 44 | [MAT4] = "mat4", 45 | [CENTROID] = "centroid", 46 | [IN] = "in", 47 | [OUT] = "out", 48 | [INOUT] = "inout", 49 | [UNIFORM] = "uniform", 50 | [PATCH] = "patch", 51 | [SAMPLE] = "sample", 52 | [BUFFER] = "buffer", 53 | [SHARED] = "shared", 54 | [COHERENT] = "coherent", 55 | [VOLATILE] = "volatile", 56 | [RESTRICT] = "restrict", 57 | [READONLY] = "readonly", 58 | [WRITEONLY] = "writeonly", 59 | [DVEC2] = "dvec2", 60 | [DVEC3] = "dvec3", 61 | [DVEC4] = "dvec4", 62 | [DMAT2] = "dmat2", 63 | [DMAT3] = "dmat3", 64 | [DMAT4] = "dmat4", 65 | [NOPERSPECTIVE] = "noperspective", 66 | [FLAT] = "flat", 67 | [SMOOTH] = "smooth", 68 | [LAYOUT] = "layout", 69 | [MAT2X2] = "mat2x2", 70 | [MAT2X3] = "mat2x3", 71 | [MAT2X4] = "mat2x4", 72 | [MAT3X2] = "mat3x2", 73 | [MAT3X3] = "mat3x3", 74 | [MAT3X4] = "mat3x4", 75 | [MAT4X2] = "mat4x2", 76 | [MAT4X3] = "mat4x3", 77 | [MAT4X4] = "mat4x4", 78 | [DMAT2X2] = "dmat2x2", 79 | [DMAT2X3] = "dmat2x3", 80 | [DMAT2X4] = "dmat2x4", 81 | [DMAT3X2] = "dmat3x2", 82 | [DMAT3X3] = "dmat3x3", 83 | [DMAT3X4] = "dmat3x4", 84 | [DMAT4X2] = "dmat4x2", 85 | [DMAT4X3] = "dmat4x3", 86 | [DMAT4X4] = "dmat4x4", 87 | [ATOMIC_UINT] = "atomic_uint", 88 | [SAMPLER1D] = "sampler1D", 89 | [SAMPLER2D] = "sampler2D", 90 | [SAMPLER3D] = "sampler3D", 91 | [SAMPLERCUBE] = "samplercube", 92 | [SAMPLER1DSHADOW] = "sampler1Dshadow", 93 | [SAMPLER2DSHADOW] = "sampler2Dshadow", 94 | [SAMPLERCUBESHADOW] = "samplercubeshadow", 95 | [SAMPLER1DARRAY] = "sampler1Darray", 96 | [SAMPLER2DARRAY] = "sampler2Darray", 97 | [SAMPLER1DARRAYSHADOW] = "sampler1Darrayshadow", 98 | [SAMPLER2DARRAYSHADOW] = "sampler2Darrayshadow", 99 | [ISAMPLER1D] = "isampler1D", 100 | [ISAMPLER2D] = "isampler2D", 101 | [ISAMPLER3D] = "isampler3D", 102 | [ISAMPLERCUBE] = "isamplercube", 103 | [ISAMPLER1DARRAY] = "isampler1Darray", 104 | [ISAMPLER2DARRAY] = "isampler2Darray", 105 | [USAMPLER1D] = "usampler1D", 106 | [USAMPLER2D] = "usampler2D", 107 | [USAMPLER3D] = "usampler3D", 108 | [USAMPLERCUBE] = "usamplercube", 109 | [USAMPLER1DARRAY] = "usampler1Darray", 110 | [USAMPLER2DARRAY] = "usampler2Darray", 111 | [SAMPLER2DRECT] = "sampler2Drect", 112 | [SAMPLER2DRECTSHADOW] = "sampler2Drectshadow", 113 | [ISAMPLER2DRECT] = "isampler2Drect", 114 | [USAMPLER2DRECT] = "usampler2Drect", 115 | [SAMPLERBUFFER] = "samplerbuffer", 116 | [ISAMPLERBUFFER] = "isamplerbuffer", 117 | [USAMPLERBUFFER] = "usamplerbuffer", 118 | [SAMPLERCUBEARRAY] = "samplercubearray", 119 | [SAMPLERCUBEARRAYSHADOW] = "samplercubearrayshadow", 120 | [ISAMPLERCUBEARRAY] = "isamplercubearray", 121 | [USAMPLERCUBEARRAY] = "usamplercubearray", 122 | [SAMPLER2DMS] = "sampler2Dms", 123 | [ISAMPLER2DMS] = "isampler2Dms", 124 | [USAMPLER2DMS] = "usampler2Dms", 125 | [SAMPLER2DMSARRAY] = "sampler2Dmsarray", 126 | [ISAMPLER2DMSARRAY] = "isampler2Dmsarray", 127 | [USAMPLER2DMSARRAY] = "usampler2Dmsarray", 128 | [IMAGE1D] = "image1D", 129 | [IIMAGE1D] = "iimage1D", 130 | [UIMAGE1D] = "uimage1D", 131 | [IMAGE2D] = "image2D", 132 | [IIMAGE2D] = "iimage2D", 133 | [UIMAGE2D] = "uimage2D", 134 | [IMAGE3D] = "image3D", 135 | [IIMAGE3D] = "iimage3D", 136 | [UIMAGE3D] = "uimage3D", 137 | [IMAGE2DRECT] = "image2Drect", 138 | [IIMAGE2DRECT] = "iimage2Drect", 139 | [UIMAGE2DRECT] = "uimage2Drect", 140 | [IMAGECUBE] = "imagecube", 141 | [IIMAGECUBE] = "iimagecube", 142 | [UIMAGECUBE] = "uimagecube", 143 | [IMAGEBUFFER] = "imagebuffer", 144 | [IIMAGEBUFFER] = "iimagebuffer", 145 | [UIMAGEBUFFER] = "uimagebuffer", 146 | [IMAGE1DARRAY] = "image1Darray", 147 | [IIMAGE1DARRAY] = "iimage1Darray", 148 | [UIMAGE1DARRAY] = "uimage1Darray", 149 | [IMAGE2DARRAY] = "image2Darray", 150 | [IIMAGE2DARRAY] = "iimage2Darray", 151 | [UIMAGE2DARRAY] = "uimage2Darray", 152 | [IMAGECUBEARRAY] = "imagecubearray", 153 | [IIMAGECUBEARRAY] = "iimagecubearray", 154 | [UIMAGECUBEARRAY] = "uimagecubearray", 155 | [IMAGE2DMS] = "image2Dms", 156 | [IIMAGE2DMS] = "iimage2Dms", 157 | [UIMAGE2DMS] = "uimage2Dms", 158 | [IMAGE2DMSARRAY] = "image2Dmsarray", 159 | [IIMAGE2DMSARRAY] = "iimage2Dmsarray", 160 | [UIMAGE2DMSARRAY] = "uimage2Dmsarray", 161 | [STRUCT] = "struct", 162 | [VOID] = "void", 163 | [WHILE] = "while", 164 | [LEFT_OP] = "<<", 165 | [RIGHT_OP] = ">>", 166 | [PRE_INC_OP] = "++", 167 | [PRE_DEC_OP] = "--", 168 | [POST_INC_OP] = "++", 169 | [POST_DEC_OP] = "--", 170 | [LE_OP] = "<=", 171 | [GE_OP] = ">=", 172 | [EQ_OP] = "==", 173 | [NE_OP] = "!=", 174 | [AND_OP] = "&&", 175 | [OR_OP] = "||", 176 | [XOR_OP] = "^^", 177 | [MUL_ASSIGN] = "*=", 178 | [DIV_ASSIGN] = "/=", 179 | [ADD_ASSIGN] = "+=", 180 | [MOD_ASSIGN] = "%=", 181 | [LEFT_ASSIGN] = "<<=", 182 | [RIGHT_ASSIGN] = ">>=", 183 | [AND_ASSIGN] = "&=", 184 | [XOR_ASSIGN] = "^=", 185 | [OR_ASSIGN] = "|=", 186 | [SUB_ASSIGN] = "-=", 187 | [LEFT_PAREN] = "(", 188 | [RIGHT_PAREN] = ")", 189 | [LEFT_BRACKET] = "[", 190 | [RIGHT_BRACKET] = "]", 191 | [LEFT_BRACE] = "{", 192 | [RIGHT_BRACE] = "}", 193 | [DOT] = ".", 194 | [COMMA] = ",", 195 | [COLON] = ":", 196 | [EQUAL] = "=", 197 | [SEMICOLON] = ";", 198 | [BANG] = "!", 199 | [DASH] = "-", 200 | [TILDE] = "~", 201 | [PLUS] = "+", 202 | [STAR] = "*", 203 | [SLASH] = "/", 204 | [PERCENT] = "%", 205 | [LEFT_ANGLE] = "<", 206 | [RIGHT_ANGLE] = ">", 207 | [VERTICAL_BAR] = "|", 208 | [CARET] = "^", 209 | [AMPERSAND] = "&", 210 | [QUESTION] = "?", 211 | [INVARIANT] = "invariant", 212 | [PRECISE] = "precise", 213 | [HIGHP] = "highp", 214 | [MEDIUMP] = "mediump", 215 | [LOWP] = "lowp", 216 | [PRECISION] = "precision", 217 | [UNARY_PLUS] = "+", 218 | [UNARY_DASH] = "-", 219 | [NUM_GLSL_TOKEN] = "" 220 | }; 221 | 222 | static const char *code_to_str[4096] = { 223 | [CONST] = "CONST", 224 | [BOOL] = "BOOL", 225 | [FLOAT] = "FLOAT", 226 | [DOUBLE] = "DOUBLE", 227 | [INT] = "INT", 228 | [UINT] = "UINT", 229 | [BREAK] = "BREAK", 230 | [CONTINUE] = "CONTINUE", 231 | [DO] = "DO", 232 | [ELSE] = "ELSE", 233 | [FOR] = "FOR", 234 | [IF] = "IF", 235 | [DISCARD] = "DISCARD", 236 | [RETURN] = "RETURN", 237 | [RETURN_VALUE] = "RETURN_VALUE", 238 | [SWITCH] = "SWITCH", 239 | [CASE] = "CASE", 240 | [DEFAULT] = "DEFAULT", 241 | [SUBROUTINE] = "SUBROUTINE", 242 | [BVEC2] = "BVEC2", 243 | [BVEC3] = "BVEC3", 244 | [BVEC4] = "BVEC4", 245 | [IVEC2] = "IVEC2", 246 | [IVEC3] = "IVEC3", 247 | [IVEC4] = "IVEC4", 248 | [UVEC2] = "UVEC2", 249 | [UVEC3] = "UVEC3", 250 | [UVEC4] = "UVEC4", 251 | [VEC2] = "VEC2", 252 | [VEC3] = "VEC3", 253 | [VEC4] = "VEC4", 254 | [MAT2] = "MAT2", 255 | [MAT3] = "MAT3", 256 | [MAT4] = "MAT4", 257 | [CENTROID] = "CENTROID", 258 | [IN] = "IN", 259 | [OUT] = "OUT", 260 | [INOUT] = "INOUT", 261 | [UNIFORM] = "UNIFORM", 262 | [PATCH] = "PATCH", 263 | [SAMPLE] = "SAMPLE", 264 | [BUFFER] = "BUFFER", 265 | [SHARED] = "SHARED", 266 | [COHERENT] = "COHERENT", 267 | [VOLATILE] = "VOLATILE", 268 | [RESTRICT] = "RESTRICT", 269 | [READONLY] = "READONLY", 270 | [WRITEONLY] = "WRITEONLY", 271 | [DVEC2] = "DVEC2", 272 | [DVEC3] = "DVEC3", 273 | [DVEC4] = "DVEC4", 274 | [DMAT2] = "DMAT2", 275 | [DMAT3] = "DMAT3", 276 | [DMAT4] = "DMAT4", 277 | [NOPERSPECTIVE] = "NOPERSPECTIVE", 278 | [FLAT] = "FLAT", 279 | [SMOOTH] = "SMOOTH", 280 | [LAYOUT] = "LAYOUT", 281 | [MAT2X2] = "MAT2X2", 282 | [MAT2X3] = "MAT2X3", 283 | [MAT2X4] = "MAT2X4", 284 | [MAT3X2] = "MAT3X2", 285 | [MAT3X3] = "MAT3X3", 286 | [MAT3X4] = "MAT3X4", 287 | [MAT4X2] = "MAT4X2", 288 | [MAT4X3] = "MAT4X3", 289 | [MAT4X4] = "MAT4X4", 290 | [DMAT2X2] = "DMAT2X2", 291 | [DMAT2X3] = "DMAT2X3", 292 | [DMAT2X4] = "DMAT2X4", 293 | [DMAT3X2] = "DMAT3X2", 294 | [DMAT3X3] = "DMAT3X3", 295 | [DMAT3X4] = "DMAT3X4", 296 | [DMAT4X2] = "DMAT4X2", 297 | [DMAT4X3] = "DMAT4X3", 298 | [DMAT4X4] = "DMAT4X4", 299 | [ATOMIC_UINT] = "ATOMIC_UINT", 300 | [SAMPLER1D] = "SAMPLER1D", 301 | [SAMPLER2D] = "SAMPLER2D", 302 | [SAMPLER3D] = "SAMPLER3D", 303 | [SAMPLERCUBE] = "SAMPLERCUBE", 304 | [SAMPLER1DSHADOW] = "SAMPLER1DSHADOW", 305 | [SAMPLER2DSHADOW] = "SAMPLER2DSHADOW", 306 | [SAMPLERCUBESHADOW] = "SAMPLERCUBESHADOW", 307 | [SAMPLER1DARRAY] = "SAMPLER1DARRAY", 308 | [SAMPLER2DARRAY] = "SAMPLER2DARRAY", 309 | [SAMPLER1DARRAYSHADOW] = "SAMPLER1DARRAYSHADOW", 310 | [SAMPLER2DARRAYSHADOW] = "SAMPLER2DARRAYSHADOW", 311 | [ISAMPLER1D] = "ISAMPLER1D", 312 | [ISAMPLER2D] = "ISAMPLER2D", 313 | [ISAMPLER3D] = "ISAMPLER3D", 314 | [ISAMPLERCUBE] = "ISAMPLERCUBE", 315 | [ISAMPLER1DARRAY] = "ISAMPLER1DARRAY", 316 | [ISAMPLER2DARRAY] = "ISAMPLER2DARRAY", 317 | [USAMPLER1D] = "USAMPLER1D", 318 | [USAMPLER2D] = "USAMPLER2D", 319 | [USAMPLER3D] = "USAMPLER3D", 320 | [USAMPLERCUBE] = "USAMPLERCUBE", 321 | [USAMPLER1DARRAY] = "USAMPLER1DARRAY", 322 | [USAMPLER2DARRAY] = "USAMPLER2DARRAY", 323 | [SAMPLER2DRECT] = "SAMPLER2DRECT", 324 | [SAMPLER2DRECTSHADOW] = "SAMPLER2DRECTSHADOW", 325 | [ISAMPLER2DRECT] = "ISAMPLER2DRECT", 326 | [USAMPLER2DRECT] = "USAMPLER2DRECT", 327 | [SAMPLERBUFFER] = "SAMPLERBUFFER", 328 | [ISAMPLERBUFFER] = "ISAMPLERBUFFER", 329 | [USAMPLERBUFFER] = "USAMPLERBUFFER", 330 | [SAMPLERCUBEARRAY] = "SAMPLERCUBEARRAY", 331 | [SAMPLERCUBEARRAYSHADOW] = "SAMPLERCUBEARRAYSHADOW", 332 | [ISAMPLERCUBEARRAY] = "ISAMPLERCUBEARRAY", 333 | [USAMPLERCUBEARRAY] = "USAMPLERCUBEARRAY", 334 | [SAMPLER2DMS] = "SAMPLER2DMS", 335 | [ISAMPLER2DMS] = "ISAMPLER2DMS", 336 | [USAMPLER2DMS] = "USAMPLER2DMS", 337 | [SAMPLER2DMSARRAY] = "SAMPLER2DMSARRAY", 338 | [ISAMPLER2DMSARRAY] = "ISAMPLER2DMSARRAY", 339 | [USAMPLER2DMSARRAY] = "USAMPLER2DMSARRAY", 340 | [IMAGE1D] = "IMAGE1D", 341 | [IIMAGE1D] = "IIMAGE1D", 342 | [UIMAGE1D] = "UIMAGE1D", 343 | [IMAGE2D] = "IMAGE2D", 344 | [IIMAGE2D] = "IIMAGE2D", 345 | [UIMAGE2D] = "UIMAGE2D", 346 | [IMAGE3D] = "IMAGE3D", 347 | [IIMAGE3D] = "IIMAGE3D", 348 | [UIMAGE3D] = "UIMAGE3D", 349 | [IMAGE2DRECT] = "IMAGE2DRECT", 350 | [IIMAGE2DRECT] = "IIMAGE2DRECT", 351 | [UIMAGE2DRECT] = "UIMAGE2DRECT", 352 | [IMAGECUBE] = "IMAGECUBE", 353 | [IIMAGECUBE] = "IIMAGECUBE", 354 | [UIMAGECUBE] = "UIMAGECUBE", 355 | [IMAGEBUFFER] = "IMAGEBUFFER", 356 | [IIMAGEBUFFER] = "IIMAGEBUFFER", 357 | [UIMAGEBUFFER] = "UIMAGEBUFFER", 358 | [IMAGE1DARRAY] = "IMAGE1DARRAY", 359 | [IIMAGE1DARRAY] = "IIMAGE1DARRAY", 360 | [UIMAGE1DARRAY] = "UIMAGE1DARRAY", 361 | [IMAGE2DARRAY] = "IMAGE2DARRAY", 362 | [IIMAGE2DARRAY] = "IIMAGE2DARRAY", 363 | [UIMAGE2DARRAY] = "UIMAGE2DARRAY", 364 | [IMAGECUBEARRAY] = "IMAGECUBEARRAY", 365 | [IIMAGECUBEARRAY] = "IIMAGECUBEARRAY", 366 | [UIMAGECUBEARRAY] = "UIMAGECUBEARRAY", 367 | [IMAGE2DMS] = "IMAGE2DMS", 368 | [IIMAGE2DMS] = "IIMAGE2DMS", 369 | [UIMAGE2DMS] = "UIMAGE2DMS", 370 | [IMAGE2DMSARRAY] = "IMAGE2DMSARRAY", 371 | [IIMAGE2DMSARRAY] = "IIMAGE2DMSARRAY", 372 | [UIMAGE2DMSARRAY] = "UIMAGE2DMSARRAY", 373 | [STRUCT] = "STRUCT", 374 | [VOID] = "VOID", 375 | [WHILE] = "WHILE", 376 | [TRUE_VALUE] = "TRUE_VALUE", 377 | [FALSE_VALUE] = "FALSE_VALUE", 378 | [LEFT_OP] = "LEFT_OP", 379 | [RIGHT_OP] = "RIGHT_OP", 380 | [INC_OP] = "INC_OP", 381 | [DEC_OP] = "DEC_OP", 382 | [LE_OP] = "LE_OP", 383 | [GE_OP] = "GE_OP", 384 | [EQ_OP] = "EQ_OP", 385 | [NE_OP] = "NE_OP", 386 | [AND_OP] = "AND_OP", 387 | [OR_OP] = "OR_OP", 388 | [XOR_OP] = "XOR_OP", 389 | [MUL_ASSIGN] = "MUL_ASSIGN", 390 | [DIV_ASSIGN] = "DIV_ASSIGN", 391 | [ADD_ASSIGN] = "ADD_ASSIGN", 392 | [MOD_ASSIGN] = "MOD_ASSIGN", 393 | [LEFT_ASSIGN] = "LEFT_ASSIGN", 394 | [RIGHT_ASSIGN] = "RIGHT_ASSIGN", 395 | [AND_ASSIGN] = "AND_ASSIGN", 396 | [XOR_ASSIGN] = "XOR_ASSIGN", 397 | [OR_ASSIGN] = "OR_ASSIGN", 398 | [SUB_ASSIGN] = "SUB_ASSIGN", 399 | [LEFT_PAREN] = "LEFT_PAREN", 400 | [RIGHT_PAREN] = "RIGHT_PAREN", 401 | [LEFT_BRACKET] = "LEFT_BRACKET", 402 | [RIGHT_BRACKET] = "RIGHT_BRACKET", 403 | [LEFT_BRACE] = "LEFT_BRACE", 404 | [RIGHT_BRACE] = "RIGHT_BRACE", 405 | [DOT] = "DOT", 406 | [COMMA] = "COMMA", 407 | [COLON] = "COLON", 408 | [EQUAL] = "EQUAL", 409 | [SEMICOLON] = "SEMICOLON", 410 | [BANG] = "BANG", 411 | [DASH] = "DASH", 412 | [TILDE] = "TILDE", 413 | [PLUS] = "PLUS", 414 | [STAR] = "STAR", 415 | [SLASH] = "SLASH", 416 | [PERCENT] = "PERCENT", 417 | [LEFT_ANGLE] = "LEFT_ANGLE", 418 | [RIGHT_ANGLE] = "RIGHT_ANGLE", 419 | [VERTICAL_BAR] = "VERTICAL_BAR", 420 | [CARET] = "CARET", 421 | [AMPERSAND] = "AMPERSAND", 422 | [QUESTION] = "QUESTION", 423 | [INVARIANT] = "INVARIANT", 424 | [PRECISE] = "PRECISE", 425 | [HIGHP] = "HIGHP", 426 | [MEDIUMP] = "MEDIUMP", 427 | [LOWP] = "LOWP", 428 | [PRECISION] = "PRECISION", 429 | [AT] = "AT", 430 | 431 | [UNARY_PLUS] = "UNARY_PLUS", 432 | [UNARY_DASH] = "UNARY_DASH", 433 | [PRE_INC_OP] = "PRE_INC_OP", 434 | [PRE_DEC_OP] = "PRE_DEC_OP", 435 | [POST_DEC_OP] = "POST_DEC_OP", 436 | [POST_INC_OP] = "POST_INC_OP", 437 | [ARRAY_REF_OP] = "ARRAY_REF_OP", 438 | [FUNCTION_CALL] = "FUNCTION_CALL", 439 | [TYPE_NAME_LIST] = "TYPE_NAME_LIST", 440 | [TYPE_SPECIFIER] = "TYPE_SPECIFIER", 441 | [POSTFIX_EXPRESSION] = "POSTFIX_EXPRESSION", 442 | [TYPE_QUALIFIER_LIST] = "TYPE_QUALIFIER_LIST", 443 | [STRUCT_DECLARATION] = "STRUCT_DECLARATION", 444 | [STRUCT_DECLARATOR] = "STRUCT_DECLARATOR", 445 | [STRUCT_SPECIFIER] = "STRUCT_SPECIFIER", 446 | [FUNCTION_DEFINITION] = "FUNCTION_DEFINITION", 447 | [DECLARATION] = "DECLARATION", 448 | [STATEMENT_LIST] = "STATEMENT_LIST", 449 | [TRANSLATION_UNIT] = "TRANSLATION_UNIT", 450 | [PRECISION_DECLARATION] = "PRECISION_DECLARATION", 451 | [BLOCK_DECLARATION] = "BLOCK_DECLARATION", 452 | [TYPE_QUALIFIER_DECLARATION] = "TYPE_QUALIFIER_DECLARATION", 453 | [IDENTIFIER_LIST] = "IDENTIFIER_LIST", 454 | [INIT_DECLARATOR_LIST] = "INIT_DECLARATOR_LIST", 455 | [FULLY_SPECIFIED_TYPE] = "FULLY_SPECIFIED_TYPE", 456 | [SINGLE_DECLARATION] = "SINGLE_DECLARATION", 457 | [SINGLE_INIT_DECLARATION] = "SINGLE_INIT_DECLARATION", 458 | [INITIALIZER_LIST] = "INITIALIZER_LIST", 459 | [EXPRESSION_STATEMENT] = "EXPRESSION_STATEMENT", 460 | [SELECTION_STATEMENT] = "SELECTION_STATEMENT", 461 | [SELECTION_STATEMENT_ELSE] = "SELECTION_STATEMENT_ELSE", 462 | [SWITCH_STATEMENT] = "SWITCH_STATEMENT", 463 | [FOR_REST_STATEMENT] = "FOR_REST_STATEMENT", 464 | [WHILE_STATEMENT] = "WHILE_STATEMENT", 465 | [DO_STATEMENT] = "DO_STATEMENT", 466 | [FOR_STATEMENT] = "FOR_STATEMENT", 467 | [CASE_LABEL] = "CASE_LABEL", 468 | [CONDITION_OPT] = "CONDITION_OPT", 469 | [ASSIGNMENT_CONDITION] = "ASSIGNMENT_CONDITION", 470 | [EXPRESSION_CONDITION] = "EXPRESSION_CONDITION", 471 | [FUNCTION_HEADER] = "FUNCTION_HEADER", 472 | [FUNCTION_DECLARATION] = "FUNCTION_DECLARATION", 473 | [FUNCTION_PARAMETER_LIST] = "FUNCTION_PARAMETER_LIST", 474 | [PARAMETER_DECLARATION] = "PARAMETER_DECLARATION", 475 | [PARAMETER_DECLARATOR] = "PARAMETER_DECLARATOR", 476 | [UNINITIALIZED_DECLARATION] = "UNINITIALIZED_DECLARATION", 477 | [ARRAY_SPECIFIER] = "ARRAY_SPECIFIER", 478 | [ARRAY_SPECIFIER_LIST] = "ARRAY_SPECIFIER_LIST", 479 | [STRUCT_DECLARATOR_LIST] = "STRUCT_DECLARATOR_LIST", 480 | [FUNCTION_CALL_PARAMETER_LIST] = "FUNCTION_CALL_PARAMETER_LIST", 481 | [STRUCT_DECLARATION_LIST] = "STRUCT_DECLARATION_LIST", 482 | [LAYOUT_QUALIFIER_ID] = "LAYOUT_QUALIFIER_ID", 483 | [LAYOUT_QUALIFIER_ID_LIST] = "LAYOUT_QUALIFIER_ID_LIST", 484 | [SUBROUTINE_TYPE] = "SUBROUTINE_TYPE", 485 | [PAREN_EXPRESSION] = "PAREN_EXPRESSION", 486 | [INIT_DECLARATOR] = "INIT_DECLARATOR", 487 | [INITIALIZER] = "INITIALIZER", 488 | [TERNARY_EXPRESSION] = "TERNARY_EXPRESSION", 489 | [FIELD_IDENTIFIER] = "FIELD_IDENTIFIER", 490 | [NUM_GLSL_TOKEN] = "" 491 | }; 492 | 493 | bool glsl_ast_is_list_node(struct glsl_node *n) 494 | { 495 | switch(n->code) { 496 | case TYPE_NAME_LIST: 497 | case TYPE_QUALIFIER_LIST: 498 | case STATEMENT_LIST: 499 | case IDENTIFIER_LIST: 500 | case INIT_DECLARATOR_LIST: 501 | case INITIALIZER_LIST: 502 | case FUNCTION_PARAMETER_LIST: 503 | case ARRAY_SPECIFIER_LIST: 504 | case STRUCT_DECLARATOR_LIST: 505 | case STRUCT_DECLARATION_LIST: 506 | case TRANSLATION_UNIT: 507 | case FUNCTION_CALL_PARAMETER_LIST: 508 | return true; 509 | default: 510 | return false; 511 | } 512 | } 513 | 514 | void glsl_ast_print(struct glsl_node *n, int depth) 515 | { 516 | int i; 517 | 518 | for (i = 0; i < depth; i++) { 519 | printf("\t"); 520 | } 521 | 522 | if (code_to_str[n->code]) 523 | printf("%s", code_to_str[n->code]); 524 | 525 | switch(n->code) { 526 | case IDENTIFIER: 527 | if (n->data.str) { 528 | if (code_to_str[n->code]) 529 | printf(": "); 530 | printf("%s", n->data.str); 531 | } 532 | break; 533 | case FLOATCONSTANT: 534 | if (code_to_str[n->code]) 535 | printf(": "); 536 | printf("%f", n->data.f); 537 | break; 538 | case DOUBLECONSTANT: 539 | if (code_to_str[n->code]) 540 | printf(": "); 541 | printf("%f", n->data.d); 542 | break; 543 | case INTCONSTANT: 544 | if (code_to_str[n->code]) 545 | printf(": "); 546 | printf("%d", n->data.i); 547 | break; 548 | case UINTCONSTANT: 549 | if (code_to_str[n->code]) 550 | printf(": "); 551 | printf("%u", n->data.ui); 552 | break; 553 | } 554 | printf("\n"); 555 | 556 | for (i = 0; i < n->child_count; i++) { 557 | glsl_ast_print((struct glsl_node *)n->children[i], depth + 1); 558 | } 559 | } 560 | 561 | static bool is_optional_list(struct glsl_node *n) 562 | { 563 | switch(n->code) { 564 | case ARRAY_SPECIFIER_LIST: 565 | case TYPE_QUALIFIER_LIST: 566 | return true; 567 | } 568 | return false; 569 | } 570 | 571 | struct string { 572 | char *s; 573 | int len; 574 | int capacity; 575 | }; 576 | 577 | static void _glsl_ast_gen_glsl(struct glsl_node *n, struct string *out, int depth); 578 | 579 | static void string_cat(struct string *str, const char *format, ...) 580 | { 581 | int n; 582 | va_list vl; 583 | do { 584 | int left = str->capacity - str->len; 585 | va_start(vl, format); 586 | n = vsnprintf(str->s + str->len, left, format, vl); 587 | va_end(vl); 588 | if (n < left) { 589 | break; 590 | } else { 591 | str->capacity *= 2; 592 | str->s = realloc(str->s, str->capacity); 593 | } 594 | } while (1); 595 | str->len += n; 596 | } 597 | 598 | static void print_list_as_glsl(struct glsl_node *n, const char *prefix, const char *delim, const char *postfix, struct string *out, int depth) 599 | { 600 | int i, c = 0; 601 | string_cat(out,"%s", prefix); 602 | for (i = 0; i < n->child_count; i++) { 603 | if (!n->children[i]->child_count && is_optional_list(n->children[i])) 604 | continue; 605 | if (c) 606 | string_cat(out,"%s", delim); 607 | c++; 608 | _glsl_ast_gen_glsl(n->children[i], out, depth); 609 | } 610 | string_cat(out,"%s", postfix); 611 | } 612 | 613 | static void _glsl_ast_gen_glsl(struct glsl_node *n, struct string *out, int depth) 614 | { 615 | int i; 616 | int j; 617 | switch(n->code) { 618 | case FIELD_IDENTIFIER: 619 | case IDENTIFIER: 620 | if (n->data.str) { 621 | string_cat(out,"%s", n->data.str); 622 | } 623 | break; 624 | case FLOATCONSTANT: 625 | string_cat(out,"%f", n->data.f); 626 | break; 627 | case DOUBLECONSTANT: 628 | string_cat(out,"%f", n->data.d); 629 | break; 630 | case INTCONSTANT: 631 | string_cat(out,"%d", n->data.i); 632 | break; 633 | case UINTCONSTANT: 634 | string_cat(out,"%u", n->data.ui); 635 | break; 636 | case TRANSLATION_UNIT: 637 | print_list_as_glsl(n, "", "\n", "\n", out, depth); 638 | break; 639 | case ARRAY_SPECIFIER_LIST: 640 | print_list_as_glsl(n, "", "", "", out, depth); 641 | break; 642 | case ARRAY_SPECIFIER: 643 | print_list_as_glsl(n, "[", "", "]", out, depth); 644 | break; 645 | case EQUAL: 646 | case MUL_ASSIGN: 647 | case DIV_ASSIGN: 648 | case MOD_ASSIGN: 649 | case ADD_ASSIGN: 650 | case SUB_ASSIGN: 651 | case LEFT_ASSIGN: 652 | case RIGHT_ASSIGN: 653 | case AND_ASSIGN: 654 | case XOR_ASSIGN: 655 | case OR_ASSIGN: 656 | case PLUS: 657 | case DASH: 658 | case STAR: 659 | case SLASH: 660 | case PERCENT: 661 | case AMPERSAND: 662 | case EQ_OP: 663 | case NE_OP: 664 | case LEFT_ANGLE: 665 | case RIGHT_ANGLE: 666 | case LE_OP: 667 | case GE_OP: 668 | case LEFT_OP: 669 | case RIGHT_OP: 670 | case CARET: 671 | case VERTICAL_BAR: 672 | case AND_OP: 673 | case OR_OP: 674 | case XOR_OP: 675 | _glsl_ast_gen_glsl(n->children[0], out, depth); 676 | if (token_to_str[n->code]) { 677 | string_cat(out," %s ", token_to_str[n->code]); 678 | } else { 679 | string_cat(out," ", n->code); 680 | } 681 | _glsl_ast_gen_glsl(n->children[1], out, depth); 682 | break; 683 | case DOT: 684 | _glsl_ast_gen_glsl(n->children[0], out, depth); 685 | string_cat(out,"."); 686 | _glsl_ast_gen_glsl(n->children[1], out, depth); 687 | break; 688 | case PRE_INC_OP: 689 | case PRE_DEC_OP: 690 | case UNARY_PLUS: 691 | case UNARY_DASH: 692 | case TILDE: 693 | case BANG: 694 | print_list_as_glsl(n, token_to_str[n->code], "", "", out, depth); 695 | break; 696 | case PAREN_EXPRESSION: 697 | print_list_as_glsl(n, "(", "", ")", out, depth); 698 | break; 699 | case POST_INC_OP: 700 | case POST_DEC_OP: 701 | print_list_as_glsl(n, "", "", token_to_str[n->code], out, depth); 702 | break; 703 | case FUNCTION_DECLARATION: 704 | case FUNCTION_HEADER: 705 | case FULLY_SPECIFIED_TYPE: 706 | case PARAMETER_DECLARATION: 707 | case PARAMETER_DECLARATOR: 708 | case TYPE_QUALIFIER_LIST: 709 | print_list_as_glsl(n, "", " ", "", out, depth); 710 | break; 711 | case FUNCTION_DEFINITION: 712 | print_list_as_glsl(n, "", " ", "\n", out, depth); 713 | break; 714 | case FUNCTION_CALL: 715 | _glsl_ast_gen_glsl(n->children[0], out, depth); 716 | _glsl_ast_gen_glsl(n->children[1], out, depth); 717 | break; 718 | case SELECTION_STATEMENT: 719 | string_cat(out,"if ("); 720 | _glsl_ast_gen_glsl(n->children[0], out, depth); 721 | string_cat(out,") "); 722 | _glsl_ast_gen_glsl(n->children[1], out, depth); 723 | break; 724 | case ARRAY_REF_OP: 725 | _glsl_ast_gen_glsl(n->children[0], out, depth); 726 | string_cat(out,"["); 727 | _glsl_ast_gen_glsl(n->children[1], out, depth); 728 | string_cat(out,"]"); 729 | break; 730 | case RETURN: 731 | string_cat(out,"return;\n"); 732 | break; 733 | case RETURN_VALUE: 734 | string_cat(out,"return "); 735 | _glsl_ast_gen_glsl(n->children[0], out, depth); 736 | string_cat(out,";"); 737 | break; 738 | case SELECTION_STATEMENT_ELSE: 739 | string_cat(out,"if ("); 740 | _glsl_ast_gen_glsl(n->children[0], out, depth); 741 | string_cat(out,") "); 742 | _glsl_ast_gen_glsl(n->children[1], out, depth); 743 | string_cat(out," else "); 744 | _glsl_ast_gen_glsl(n->children[2], out, depth); 745 | string_cat(out,"\n"); 746 | break; 747 | case SINGLE_DECLARATION: 748 | print_list_as_glsl(n, "", " ", "", out, depth); 749 | break; 750 | case SINGLE_INIT_DECLARATION: 751 | _glsl_ast_gen_glsl(n->children[0], out, depth); 752 | string_cat(out," "); 753 | _glsl_ast_gen_glsl(n->children[1], out, depth); 754 | string_cat(out," = "); 755 | _glsl_ast_gen_glsl(n->children[3], out, depth); 756 | break; 757 | case WHILE_STATEMENT: 758 | string_cat(out,"while ("); 759 | _glsl_ast_gen_glsl(n->children[0], out, depth); 760 | string_cat(out,") "); 761 | _glsl_ast_gen_glsl(n->children[1], out, depth); 762 | break; 763 | case DO_STATEMENT: 764 | string_cat(out,"do "); 765 | _glsl_ast_gen_glsl(n->children[0], out, depth); 766 | string_cat(out," while ( "); 767 | _glsl_ast_gen_glsl(n->children[1], out, depth); 768 | string_cat(out," );"); 769 | break; 770 | case FOR_STATEMENT: 771 | string_cat(out,"for ("); 772 | _glsl_ast_gen_glsl(n->children[0], out, depth); 773 | string_cat(out," "); 774 | _glsl_ast_gen_glsl(n->children[1], out, depth); 775 | string_cat(out,") "); 776 | _glsl_ast_gen_glsl(n->children[2], out, depth); 777 | break; 778 | case ASSIGNMENT_CONDITION: 779 | _glsl_ast_gen_glsl(n->children[0], out, depth); 780 | string_cat(out," "); 781 | _glsl_ast_gen_glsl(n->children[1], out, depth); 782 | string_cat(out," = "); 783 | _glsl_ast_gen_glsl(n->children[2], out, depth); 784 | break; 785 | case STATEMENT_LIST: 786 | string_cat(out,"{\n"); 787 | for (i = 0; i < n->child_count; i++) { 788 | for (j = 0; j < depth + 1; j++) string_cat(out,"\t"); 789 | _glsl_ast_gen_glsl(n->children[i], out, depth + 1); 790 | string_cat(out,"\n"); 791 | } 792 | for (j = 0; j < depth; j++) string_cat(out,"\t"); 793 | string_cat(out,"}"); 794 | break; 795 | case STRUCT_DECLARATION_LIST: 796 | for (i = 0; i < n->child_count; i++) { 797 | for (j = 0; j < depth + 1; j++) string_cat(out,"\t"); 798 | _glsl_ast_gen_glsl(n->children[i], out, depth + 1); 799 | string_cat(out,"\n"); 800 | } 801 | for (j = 0; j < depth; j++) string_cat(out,"\t"); 802 | break; 803 | case BLOCK_DECLARATION: 804 | _glsl_ast_gen_glsl(n->children[0], out, depth); 805 | string_cat(out," "); 806 | _glsl_ast_gen_glsl(n->children[1], out, depth); 807 | string_cat(out," {\n"); 808 | _glsl_ast_gen_glsl(n->children[2], out, depth); 809 | string_cat(out,"} "); 810 | _glsl_ast_gen_glsl(n->children[3], out, depth); 811 | if (n->children[4]->child_count) { 812 | string_cat(out," "); 813 | _glsl_ast_gen_glsl(n->children[4], out, depth); 814 | } 815 | break; 816 | case DECLARATION: 817 | _glsl_ast_gen_glsl(n->children[0], out, depth); 818 | string_cat(out,";"); 819 | break; 820 | case BREAK: 821 | string_cat(out,"break;"); 822 | break; 823 | case STRUCT_SPECIFIER: 824 | string_cat(out, "struct "); 825 | _glsl_ast_gen_glsl(n->children[0], out, depth); 826 | string_cat(out, " {\n"); 827 | _glsl_ast_gen_glsl(n->children[1], out, depth); 828 | string_cat(out, "}"); 829 | break; 830 | case STRUCT_DECLARATOR: 831 | print_list_as_glsl(n, "", " ", "", out, depth); 832 | break; 833 | case STRUCT_DECLARATOR_LIST: 834 | print_list_as_glsl(n, "", ",", "", out, depth); 835 | break; 836 | case STRUCT_DECLARATION: 837 | print_list_as_glsl(n, "", " ", ";", out, depth); 838 | break; 839 | case FUNCTION_PARAMETER_LIST: 840 | case FUNCTION_CALL_PARAMETER_LIST: 841 | print_list_as_glsl(n, "(", ", ", ")", out, depth); 842 | break; 843 | case FOR_REST_STATEMENT: 844 | _glsl_ast_gen_glsl(n->children[0], out, depth); 845 | string_cat(out,"; "); 846 | if (n->child_count == 2) { 847 | _glsl_ast_gen_glsl(n->children[1], out, depth); 848 | } 849 | break; 850 | case INIT_DECLARATOR: 851 | _glsl_ast_gen_glsl(n->children[0], out, depth); 852 | if (n->children[1]->child_count) { 853 | _glsl_ast_gen_glsl(n->children[1], out, depth); 854 | } 855 | if (n->child_count > 2) { 856 | string_cat(out," = "); 857 | _glsl_ast_gen_glsl(n->children[2], out, depth); 858 | } 859 | break; 860 | case INIT_DECLARATOR_LIST: 861 | print_list_as_glsl(n, "", ", ", "", out, depth); 862 | break; 863 | case INITIALIZER_LIST: 864 | print_list_as_glsl(n, "{", ", ", "}", out, depth); 865 | break; 866 | case TERNARY_EXPRESSION: 867 | _glsl_ast_gen_glsl(n->children[0], out, depth); 868 | string_cat(out," ? "); 869 | _glsl_ast_gen_glsl(n->children[1], out, depth); 870 | string_cat(out," : "); 871 | _glsl_ast_gen_glsl(n->children[2], out, depth); 872 | break; 873 | case TYPE_SPECIFIER: 874 | case POSTFIX_EXPRESSION: 875 | case INITIALIZER: 876 | case CONDITION_OPT: 877 | case EXPRESSION_CONDITION: 878 | print_list_as_glsl(n, "", "", "", out, depth); 879 | break; 880 | case EXPRESSION_STATEMENT: 881 | print_list_as_glsl(n, "", "", ";", out, depth); 882 | break; 883 | default: 884 | if (token_to_str[n->code]) 885 | string_cat(out,"%s", token_to_str[n->code]); 886 | else 887 | string_cat(out,"", n->code); 888 | break; 889 | } 890 | } 891 | 892 | char *glsl_ast_generate_glsl(struct glsl_node *n) 893 | { 894 | struct string s; 895 | s.s = malloc(1024); 896 | s.len = 0; 897 | s.capacity = 1024; 898 | _glsl_ast_gen_glsl(n, &s, 0); 899 | return s.s; 900 | } 901 | -------------------------------------------------------------------------------- /glsl_ast.h: -------------------------------------------------------------------------------- 1 | #ifndef GLSL_AST_H 2 | #define GLSL_AST_H 3 | 4 | #include "glsl_parser.h" 5 | 6 | // 7 | // glsl_is_list_node() 8 | // 9 | // Returns true if the children of this node form 10 | // a list 11 | // 12 | bool glsl_ast_is_list_node(struct glsl_node *n); 13 | 14 | // 15 | // glsl_ast_print() 16 | // 17 | // Print the AST tree as text for debugging purposes. 18 | // The 'depth' parameter represents amount to indent the 19 | // the printed text. 20 | // 21 | void glsl_ast_print(struct glsl_node *n, int depth); 22 | 23 | // 24 | // glsl_ast_generate_glsl() 25 | // 26 | // Translate AST into GLSL 27 | // 28 | // Returns a string containing the GLSL corresponding to 29 | // the AST or NULL on error. The returned string must be 30 | // deallocataed with free() 31 | // 32 | char *glsl_ast_generate_glsl(struct glsl_node *n); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /glsl_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef GLSL_PARSER_H 2 | #define GLSL_PARSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct glsl_node { 10 | //Type of this node. These values are all members of the enum 11 | int code:16; 12 | 13 | //Number of child nodes 14 | int child_count:16; 15 | 16 | //Meta data for this node. Only uses for some nodes. The 17 | //field in this unions that should be read (if any) 18 | //is determined by 'code' 19 | union { 20 | double d; 21 | float f; 22 | int i; 23 | unsigned int ui; 24 | bool b; 25 | const char *str; 26 | } data; 27 | 28 | // 29 | // Child nodes. Extra data will be allocated past the end 30 | // of the structure to hold the child nodes. 31 | // 32 | struct glsl_node *children[]; 33 | }; 34 | 35 | typedef void (*glsl_parse_error_cb_t)(const char *error_str, int lineno, int start_col, int end_col); 36 | 37 | struct glsl_parse_context { 38 | struct glsl_node *root; 39 | glsl_parse_error_cb_t error_cb; 40 | 41 | void *scanner; //Opaque handle to lexer context 42 | 43 | /* Internal state of the parser's stack allocator */ 44 | uint8_t *first_buffer; 45 | uint8_t *cur_buffer_start; 46 | uint8_t *cur_buffer; 47 | uint8_t *cur_buffer_end; 48 | bool error; 49 | }; 50 | 51 | // 52 | // Create a new node for the AST. All values following 'code' will be 53 | // placed in the node's child array. 54 | // 55 | struct glsl_node *new_glsl_node(struct glsl_parse_context *context, int code, ...) __attribute__ ((sentinel)); 56 | 57 | // 58 | // Allocate memory in the parser's stack allocator 59 | // 60 | uint8_t *glsl_parse_alloc(struct glsl_parse_context *context, size_t size, int align); 61 | 62 | // 63 | // Deallocate all memory previously allocated by glsl_parse_alloc() 64 | // The parser internally uses this allocator so any generated 65 | // AST data will become invalid when glsl_parse_dealloc() is called. 66 | // 67 | void glsl_parse_dealloc(struct glsl_parse_context *context); 68 | 69 | // 70 | // Initialize a parsing context 71 | // 72 | void glsl_parse_context_init(struct glsl_parse_context *context); 73 | 74 | 75 | // 76 | // Set the callback to invoke when a parsing error occurs 77 | // 78 | void glsl_parse_set_error_cb(struct glsl_parse_context *context, glsl_parse_error_cb_t error_cb); 79 | 80 | 81 | // 82 | // Destroy a parsing context. 83 | // 84 | void glsl_parse_context_destroy(struct glsl_parse_context *context); 85 | 86 | // 87 | // Parse the supplied file and generate an AST in context->root. 88 | // 89 | // Returns false if a parsing error occured 90 | // 91 | bool glsl_parse_file(struct glsl_parse_context *context, FILE *file); 92 | 93 | // 94 | // Parse the supplied string and generate an AST in context->root. 95 | // 96 | // Returns false if a parsing error occured 97 | // 98 | bool glsl_parse_string(struct glsl_parse_context *context, const char *str); 99 | 100 | // 101 | // Include glsl.parse.h to get the enum values that are stored in the 'code' 102 | // field of glsl_node. 103 | // 104 | #include "glsl.parser.h" 105 | #endif 106 | -------------------------------------------------------------------------------- /glsl_parser_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "glsl_parser.h" 6 | #include "glsl_ast.h" 7 | 8 | void error_cb(const char *str, int lineno, int first_col, int last_col) 9 | { 10 | fprintf(stderr, "GLSL parse error line %d(%d-%d): %s\n", lineno, first_col, last_col, str); 11 | } 12 | 13 | void parse_file(struct glsl_parse_context *context, FILE *f) 14 | { 15 | bool error = glsl_parse_file(context, f); 16 | 17 | if (!error && context->root) { 18 | printf("\nAST tree:\n\n"); 19 | glsl_ast_print(context->root, 0); 20 | 21 | printf("\nRegenerated GLSL:\n\n"); 22 | char *out = glsl_ast_generate_glsl(context->root); 23 | printf("%s", out); 24 | free(out); 25 | } 26 | } 27 | 28 | int main(int argc, char **argv, char **envp) 29 | { 30 | struct glsl_parse_context context; 31 | 32 | glsl_parse_context_init(&context); 33 | 34 | glsl_parse_set_error_cb(&context, error_cb); 35 | 36 | if (argc == 1) { 37 | parse_file(&context, stdin); 38 | } 39 | else { 40 | int i; 41 | for (i = 1; i < argc; i++) { 42 | FILE *f = fopen(argv[i], "rt"); 43 | if (!f) { 44 | fprintf(stderr, "Couldn't open file %s: %s\n", argv[i], strerror(errno)); 45 | continue; 46 | } 47 | printf("Input file: %s\n", argv[i]); 48 | parse_file(&context, f); 49 | fclose(f); 50 | } 51 | } 52 | 53 | glsl_parse_context_destroy(&context); 54 | } 55 | --------------------------------------------------------------------------------