T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof GLSLPreParserVisitor ) return ((GLSLPreParserVisitor extends T>)visitor).visitVersion_directive(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final Version_directiveContext version_directive() throws RecognitionException {
+ Version_directiveContext _localctx = new Version_directiveContext(_ctx, getState());
+ enterRule(_localctx, 66, RULE_version_directive);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(236);
+ match(NUMBER_SIGN);
+ setState(237);
+ match(VERSION_DIRECTIVE);
+ setState(238);
+ number();
+ setState(240);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==PROFILE) {
+ {
+ setState(239);
+ profile();
+ }
+ }
+
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static final String _serializedATN =
+ "\u0004\u0001\u0133\u00f3\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001"+
+ "\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004"+
+ "\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007"+
+ "\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b"+
+ "\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007"+
+ "\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007"+
+ "\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007"+
+ "\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002\u0018\u0007"+
+ "\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002\u001b\u0007"+
+ "\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002\u001e\u0007"+
+ "\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007!\u0001\u0000"+
+ "\u0005\u0000F\b\u0000\n\u0000\f\u0000I\t\u0000\u0001\u0001\u0001\u0001"+
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001"+
+ "X\b\u0001\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004"+
+ "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005"+
+ "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006"+
+ "\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001"+
+ "\b\u0001\b\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
+ "\n\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0005\f\u007f\b\f\n\f\f\f\u0082"+
+ "\t\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0005\r\u0089\b\r\n\r\f\r"+
+ "\u008c\t\r\u0001\r\u0003\r\u008f\b\r\u0001\r\u0001\r\u0001\u000e\u0001"+
+ "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0005\u000e\u0098\b\u000e\n"+
+ "\u000e\f\u000e\u009b\t\u000e\u0001\u000e\u0003\u000e\u009e\b\u000e\u0001"+
+ "\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
+ "\u000f\u0005\u000f\u00a7\b\u000f\n\u000f\f\u000f\u00aa\t\u000f\u0001\u000f"+
+ "\u0003\u000f\u00ad\b\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010"+
+ "\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012"+
+ "\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015"+
+ "\u0005\u0015\u00bf\b\u0015\n\u0015\f\u0015\u00c2\t\u0015\u0001\u0016\u0001"+
+ "\u0016\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0019\u0001"+
+ "\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0003\u001a\u00d0"+
+ "\b\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
+ "\u001b\u0001\u001b\u0003\u001b\u00d9\b\u001b\u0001\u001c\u0001\u001c\u0001"+
+ "\u001c\u0001\u001c\u0003\u001c\u00df\b\u001c\u0001\u001c\u0001\u001c\u0001"+
+ "\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001"+
+ " \u0001 \u0001 \u0001 \u0001!\u0001!\u0001!\u0001!\u0003!\u00f1\b!\u0001"+
+ "!\u0000\u0000\"\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014"+
+ "\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@B\u0000\u0000\u00ec\u0000"+
+ "G\u0001\u0000\u0000\u0000\u0002W\u0001\u0000\u0000\u0000\u0004Y\u0001"+
+ "\u0000\u0000\u0000\u0006[\u0001\u0000\u0000\u0000\b]\u0001\u0000\u0000"+
+ "\u0000\nb\u0001\u0000\u0000\u0000\fg\u0001\u0000\u0000\u0000\u000ek\u0001"+
+ "\u0000\u0000\u0000\u0010n\u0001\u0000\u0000\u0000\u0012r\u0001\u0000\u0000"+
+ "\u0000\u0014t\u0001\u0000\u0000\u0000\u0016z\u0001\u0000\u0000\u0000\u0018"+
+ "\u0080\u0001\u0000\u0000\u0000\u001a\u0083\u0001\u0000\u0000\u0000\u001c"+
+ "\u0092\u0001\u0000\u0000\u0000\u001e\u00a1\u0001\u0000\u0000\u0000 \u00b0"+
+ "\u0001\u0000\u0000\u0000\"\u00b4\u0001\u0000\u0000\u0000$\u00b6\u0001"+
+ "\u0000\u0000\u0000&\u00b8\u0001\u0000\u0000\u0000(\u00ba\u0001\u0000\u0000"+
+ "\u0000*\u00c0\u0001\u0000\u0000\u0000,\u00c3\u0001\u0000\u0000\u0000."+
+ "\u00c5\u0001\u0000\u0000\u00000\u00c7\u0001\u0000\u0000\u00002\u00c9\u0001"+
+ "\u0000\u0000\u00004\u00cb\u0001\u0000\u0000\u00006\u00d3\u0001\u0000\u0000"+
+ "\u00008\u00da\u0001\u0000\u0000\u0000:\u00e2\u0001\u0000\u0000\u0000<"+
+ "\u00e4\u0001\u0000\u0000\u0000>\u00e6\u0001\u0000\u0000\u0000@\u00e8\u0001"+
+ "\u0000\u0000\u0000B\u00ec\u0001\u0000\u0000\u0000DF\u0003\u0002\u0001"+
+ "\u0000ED\u0001\u0000\u0000\u0000FI\u0001\u0000\u0000\u0000GE\u0001\u0000"+
+ "\u0000\u0000GH\u0001\u0000\u0000\u0000H\u0001\u0001\u0000\u0000\u0000"+
+ "IG\u0001\u0000\u0000\u0000JX\u0003\b\u0004\u0000KX\u0003\n\u0005\u0000"+
+ "LX\u0003\f\u0006\u0000MX\u0003\u000e\u0007\u0000NX\u0003\u0010\b\u0000"+
+ "OX\u0003\u0014\n\u0000PX\u0003\u001a\r\u0000QX\u0003\u001c\u000e\u0000"+
+ "RX\u0003\u001e\u000f\u0000SX\u0003 \u0010\u0000TX\u00036\u001b\u0000U"+
+ "X\u0003@ \u0000VX\u0003B!\u0000WJ\u0001\u0000\u0000\u0000WK\u0001\u0000"+
+ "\u0000\u0000WL\u0001\u0000\u0000\u0000WM\u0001\u0000\u0000\u0000WN\u0001"+
+ "\u0000\u0000\u0000WO\u0001\u0000\u0000\u0000WP\u0001\u0000\u0000\u0000"+
+ "WQ\u0001\u0000\u0000\u0000WR\u0001\u0000\u0000\u0000WS\u0001\u0000\u0000"+
+ "\u0000WT\u0001\u0000\u0000\u0000WU\u0001\u0000\u0000\u0000WV\u0001\u0000"+
+ "\u0000\u0000X\u0003\u0001\u0000\u0000\u0000YZ\u0005\u0119\u0000\u0000"+
+ "Z\u0005\u0001\u0000\u0000\u0000[\\\u0005\u0115\u0000\u0000\\\u0007\u0001"+
+ "\u0000\u0000\u0000]^\u0005\u00e6\u0000\u0000^_\u0005\u0103\u0000\u0000"+
+ "_`\u0003(\u0014\u0000`a\u0003*\u0015\u0000a\t\u0001\u0000\u0000\u0000"+
+ "bc\u0005\u00e6\u0000\u0000cd\u0005\u0104\u0000\u0000de\u0003\u0006\u0003"+
+ "\u0000ef\u0003\u0018\f\u0000f\u000b\u0001\u0000\u0000\u0000gh\u0005\u00e6"+
+ "\u0000\u0000hi\u0005\u0105\u0000\u0000ij\u0003\u0018\f\u0000j\r\u0001"+
+ "\u0000\u0000\u0000kl\u0005\u00e6\u0000\u0000lm\u0005\u0106\u0000\u0000"+
+ "m\u000f\u0001\u0000\u0000\u0000no\u0005\u00e6\u0000\u0000op\u0005\u0107"+
+ "\u0000\u0000pq\u0003\u0012\t\u0000q\u0011\u0001\u0000\u0000\u0000rs\u0005"+
+ "\u0117\u0000\u0000s\u0013\u0001\u0000\u0000\u0000tu\u0005\u00e6\u0000"+
+ "\u0000uv\u0005\u0108\u0000\u0000vw\u0003\u0016\u000b\u0000wx\u0005\u00d2"+
+ "\u0000\u0000xy\u0003\u0004\u0002\u0000y\u0015\u0001\u0000\u0000\u0000"+
+ "z{\u0005\u011a\u0000\u0000{\u0017\u0001\u0000\u0000\u0000|\u007f\u0003"+
+ "<\u001e\u0000}\u007f\u0003\u0002\u0001\u0000~|\u0001\u0000\u0000\u0000"+
+ "~}\u0001\u0000\u0000\u0000\u007f\u0082\u0001\u0000\u0000\u0000\u0080~"+
+ "\u0001\u0000\u0000\u0000\u0080\u0081\u0001\u0000\u0000\u0000\u0081\u0019"+
+ "\u0001\u0000\u0000\u0000\u0082\u0080\u0001\u0000\u0000\u0000\u0083\u0084"+
+ "\u0005\u00e6\u0000\u0000\u0084\u0085\u0005\u0109\u0000\u0000\u0085\u0086"+
+ "\u0003\u0006\u0003\u0000\u0086\u008a\u0003\u0018\f\u0000\u0087\u0089\u0003"+
+ "\n\u0005\u0000\u0088\u0087\u0001\u0000\u0000\u0000\u0089\u008c\u0001\u0000"+
+ "\u0000\u0000\u008a\u0088\u0001\u0000\u0000\u0000\u008a\u008b\u0001\u0000"+
+ "\u0000\u0000\u008b\u008e\u0001\u0000\u0000\u0000\u008c\u008a\u0001\u0000"+
+ "\u0000\u0000\u008d\u008f\u0003\f\u0006\u0000\u008e\u008d\u0001\u0000\u0000"+
+ "\u0000\u008e\u008f\u0001\u0000\u0000\u0000\u008f\u0090\u0001\u0000\u0000"+
+ "\u0000\u0090\u0091\u0003\u000e\u0007\u0000\u0091\u001b\u0001\u0000\u0000"+
+ "\u0000\u0092\u0093\u0005\u00e6\u0000\u0000\u0093\u0094\u0005\u010a\u0000"+
+ "\u0000\u0094\u0095\u0003&\u0013\u0000\u0095\u0099\u0003\u0018\f\u0000"+
+ "\u0096\u0098\u0003\n\u0005\u0000\u0097\u0096\u0001\u0000\u0000\u0000\u0098"+
+ "\u009b\u0001\u0000\u0000\u0000\u0099\u0097\u0001\u0000\u0000\u0000\u0099"+
+ "\u009a\u0001\u0000\u0000\u0000\u009a\u009d\u0001\u0000\u0000\u0000\u009b"+
+ "\u0099\u0001\u0000\u0000\u0000\u009c\u009e\u0003\f\u0006\u0000\u009d\u009c"+
+ "\u0001\u0000\u0000\u0000\u009d\u009e\u0001\u0000\u0000\u0000\u009e\u009f"+
+ "\u0001\u0000\u0000\u0000\u009f\u00a0\u0003\u000e\u0007\u0000\u00a0\u001d"+
+ "\u0001\u0000\u0000\u0000\u00a1\u00a2\u0005\u00e6\u0000\u0000\u00a2\u00a3"+
+ "\u0005\u010b\u0000\u0000\u00a3\u00a4\u0003&\u0013\u0000\u00a4\u00a8\u0003"+
+ "\u0018\f\u0000\u00a5\u00a7\u0003\n\u0005\u0000\u00a6\u00a5\u0001\u0000"+
+ "\u0000\u0000\u00a7\u00aa\u0001\u0000\u0000\u0000\u00a8\u00a6\u0001\u0000"+
+ "\u0000\u0000\u00a8\u00a9\u0001\u0000\u0000\u0000\u00a9\u00ac\u0001\u0000"+
+ "\u0000\u0000\u00aa\u00a8\u0001\u0000\u0000\u0000\u00ab\u00ad\u0003\f\u0006"+
+ "\u0000\u00ac\u00ab\u0001\u0000\u0000\u0000\u00ac\u00ad\u0001\u0000\u0000"+
+ "\u0000\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u00af\u0003\u000e\u0007"+
+ "\u0000\u00af\u001f\u0001\u0000\u0000\u0000\u00b0\u00b1\u0005\u00e6\u0000"+
+ "\u0000\u00b1\u00b2\u0005\u010c\u0000\u0000\u00b2\u00b3\u0003\"\u0011\u0000"+
+ "\u00b3!\u0001\u0000\u0000\u0000\u00b4\u00b5\u0005\u0121\u0000\u0000\u00b5"+
+ "#\u0001\u0000\u0000\u0000\u00b6\u00b7\u0005\u0123\u0000\u0000\u00b7%\u0001"+
+ "\u0000\u0000\u0000\u00b8\u00b9\u0005\u011e\u0000\u0000\u00b9\'\u0001\u0000"+
+ "\u0000\u0000\u00ba\u00bb\u0005\u0112\u0000\u0000\u00bb)\u0001\u0000\u0000"+
+ "\u0000\u00bc\u00bf\u0003,\u0016\u0000\u00bd\u00bf\u0003$\u0012\u0000\u00be"+
+ "\u00bc\u0001\u0000\u0000\u0000\u00be\u00bd\u0001\u0000\u0000\u0000\u00bf"+
+ "\u00c2\u0001\u0000\u0000\u0000\u00c0\u00be\u0001\u0000\u0000\u0000\u00c0"+
+ "\u00c1\u0001\u0000\u0000\u0000\u00c1+\u0001\u0000\u0000\u0000\u00c2\u00c0"+
+ "\u0001\u0000\u0000\u0000\u00c3\u00c4\u0005\u0124\u0000\u0000\u00c4-\u0001"+
+ "\u0000\u0000\u0000\u00c5\u00c6\u0005\u0131\u0000\u0000\u00c6/\u0001\u0000"+
+ "\u0000\u0000\u00c7\u00c8\u0005\u0128\u0000\u0000\u00c81\u0001\u0000\u0000"+
+ "\u0000\u00c9\u00ca\u0005\u0129\u0000\u0000\u00ca3\u0001\u0000\u0000\u0000"+
+ "\u00cb\u00cc\u0005\u0126\u0000\u0000\u00cc\u00cf\u0005\u00e2\u0000\u0000"+
+ "\u00cd\u00d0\u00032\u0019\u0000\u00ce\u00d0\u00030\u0018\u0000\u00cf\u00cd"+
+ "\u0001\u0000\u0000\u0000\u00cf\u00ce\u0001\u0000\u0000\u0000\u00d0\u00d1"+
+ "\u0001\u0000\u0000\u0000\u00d1\u00d2\u0005\u00f1\u0000\u0000\u00d25\u0001"+
+ "\u0000\u0000\u0000\u00d3\u00d4\u0005\u00e6\u0000\u0000\u00d4\u00d8\u0005"+
+ "\u010d\u0000\u0000\u00d5\u00d9\u0003>\u001f\u0000\u00d6\u00d9\u00034\u001a"+
+ "\u0000\u00d7\u00d9\u00038\u001c\u0000\u00d8\u00d5\u0001\u0000\u0000\u0000"+
+ "\u00d8\u00d6\u0001\u0000\u0000\u0000\u00d8\u00d7\u0001\u0000\u0000\u0000"+
+ "\u00d97\u0001\u0000\u0000\u0000\u00da\u00db\u0005\u012a\u0000\u0000\u00db"+
+ "\u00de\u0005\u00e2\u0000\u0000\u00dc\u00df\u00032\u0019\u0000\u00dd\u00df"+
+ "\u00030\u0018\u0000\u00de\u00dc\u0001\u0000\u0000\u0000\u00de\u00dd\u0001"+
+ "\u0000\u0000\u0000\u00df\u00e0\u0001\u0000\u0000\u0000\u00e0\u00e1\u0005"+
+ "\u00f1\u0000\u0000\u00e19\u0001\u0000\u0000\u0000\u00e2\u00e3\u0005\u0132"+
+ "\u0000\u0000\u00e3;\u0001\u0000\u0000\u0000\u00e4\u00e5\u0005\u012d\u0000"+
+ "\u0000\u00e5=\u0001\u0000\u0000\u0000\u00e6\u00e7\u0005\u012c\u0000\u0000"+
+ "\u00e7?\u0001\u0000\u0000\u0000\u00e8\u00e9\u0005\u00e6\u0000\u0000\u00e9"+
+ "\u00ea\u0005\u010e\u0000\u0000\u00ea\u00eb\u0003&\u0013\u0000\u00ebA\u0001"+
+ "\u0000\u0000\u0000\u00ec\u00ed\u0005\u00e6\u0000\u0000\u00ed\u00ee\u0005"+
+ "\u010f\u0000\u0000\u00ee\u00f0\u0003.\u0017\u0000\u00ef\u00f1\u0003:\u001d"+
+ "\u0000\u00f0\u00ef\u0001\u0000\u0000\u0000\u00f0\u00f1\u0001\u0000\u0000"+
+ "\u0000\u00f1C\u0001\u0000\u0000\u0000\u0010GW~\u0080\u008a\u008e\u0099"+
+ "\u009d\u00a8\u00ac\u00be\u00c0\u00cf\u00d8\u00de\u00f0";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/gen/GLSLPreParser.tokens b/src/main/gen/GLSLPreParser.tokens
new file mode 100644
index 0000000..ee3ec77
--- /dev/null
+++ b/src/main/gen/GLSLPreParser.tokens
@@ -0,0 +1,560 @@
+ATOMIC_UINT=1
+ATTRIBUTE=2
+BOOL=3
+BREAK=4
+BUFFER=5
+BVEC2=6
+BVEC3=7
+BVEC4=8
+CASE=9
+CENTROID=10
+COHERENT=11
+CONST=12
+CONTINUE=13
+DEFAULT=14
+DISCARD=15
+DMAT2=16
+DMAT2X2=17
+DMAT2X3=18
+DMAT2X4=19
+DMAT3=20
+DMAT3X2=21
+DMAT3X3=22
+DMAT3X4=23
+DMAT4=24
+DMAT4X2=25
+DMAT4X3=26
+DMAT4X4=27
+DO=28
+DOUBLE=29
+DVEC2=30
+DVEC3=31
+DVEC4=32
+ELSE=33
+FALSE=34
+FLAT=35
+FLOAT=36
+FOR=37
+HIGHP=38
+IF=39
+IIMAGE1D=40
+IIMAGE1DARRAY=41
+IIMAGE2D=42
+IIMAGE2DARRAY=43
+IIMAGE2DMS=44
+IIMAGE2DMSARRAY=45
+IIMAGE2DRECT=46
+IIMAGE3D=47
+IIMAGEBUFFER=48
+IIMAGECUBE=49
+IIMAGECUBEARRAY=50
+IMAGE1D=51
+IMAGE1DARRAY=52
+IMAGE2D=53
+IMAGE2DARRAY=54
+IMAGE2DMS=55
+IMAGE2DMSARRAY=56
+IMAGE2DRECT=57
+IMAGE3D=58
+IMAGEBUFFER=59
+IMAGECUBE=60
+IMAGECUBEARRAY=61
+IN=62
+INOUT=63
+INT=64
+INVARIANT=65
+ISAMPLER1D=66
+ISAMPLER1DARRAY=67
+ISAMPLER2D=68
+ISAMPLER2DARRAY=69
+ISAMPLER2DMS=70
+ISAMPLER2DMSARRAY=71
+ISAMPLER2DRECT=72
+ISAMPLER3D=73
+ISAMPLERBUFFER=74
+ISAMPLERCUBE=75
+ISAMPLERCUBEARRAY=76
+ISUBPASSINPUT=77
+ISUBPASSINPUTMS=78
+ITEXTURE1D=79
+ITEXTURE1DARRAY=80
+ITEXTURE2D=81
+ITEXTURE2DARRAY=82
+ITEXTURE2DMS=83
+ITEXTURE2DMSARRAY=84
+ITEXTURE2DRECT=85
+ITEXTURE3D=86
+ITEXTUREBUFFER=87
+ITEXTURECUBE=88
+ITEXTURECUBEARRAY=89
+IVEC2=90
+IVEC3=91
+IVEC4=92
+LAYOUT=93
+LOWP=94
+MAT2=95
+MAT2X2=96
+MAT2X3=97
+MAT2X4=98
+MAT3=99
+MAT3X2=100
+MAT3X3=101
+MAT3X4=102
+MAT4=103
+MAT4X2=104
+MAT4X3=105
+MAT4X4=106
+MEDIUMP=107
+NOPERSPECTIVE=108
+OUT=109
+PATCH=110
+PRECISE=111
+PRECISION=112
+READONLY=113
+RESTRICT=114
+RETURN=115
+SAMPLE=116
+SAMPLER=117
+SAMPLER1D=118
+SAMPLER1DARRAY=119
+SAMPLER1DARRAYSHADOW=120
+SAMPLER1DSHADOW=121
+SAMPLER2D=122
+SAMPLER2DARRAY=123
+SAMPLER2DARRAYSHADOW=124
+SAMPLER2DMS=125
+SAMPLER2DMSARRAY=126
+SAMPLER2DRECT=127
+SAMPLER2DRECTSHADOW=128
+SAMPLER2DSHADOW=129
+SAMPLER3D=130
+SAMPLERBUFFER=131
+SAMPLERCUBE=132
+SAMPLERCUBEARRAY=133
+SAMPLERCUBEARRAYSHADOW=134
+SAMPLERCUBESHADOW=135
+SAMPLERSHADOW=136
+SHARED=137
+SMOOTH=138
+STRUCT=139
+SUBPASSINPUT=140
+SUBPASSINPUTMS=141
+SUBROUTINE=142
+SWITCH=143
+TEXTURE1D=144
+TEXTURE1DARRAY=145
+TEXTURE2D=146
+TEXTURE2DARRAY=147
+TEXTURE2DMS=148
+TEXTURE2DMSARRAY=149
+TEXTURE2DRECT=150
+TEXTURE3D=151
+TEXTUREBUFFER=152
+TEXTURECUBE=153
+TEXTURECUBEARRAY=154
+TRUE=155
+UIMAGE1D=156
+UIMAGE1DARRAY=157
+UIMAGE2D=158
+UIMAGE2DARRAY=159
+UIMAGE2DMS=160
+UIMAGE2DMSARRAY=161
+UIMAGE2DRECT=162
+UIMAGE3D=163
+UIMAGEBUFFER=164
+UIMAGECUBE=165
+UIMAGECUBEARRAY=166
+UINT=167
+UNIFORM=168
+USAMPLER1D=169
+USAMPLER1DARRAY=170
+USAMPLER2D=171
+USAMPLER2DARRAY=172
+USAMPLER2DMS=173
+USAMPLER2DMSARRAY=174
+USAMPLER2DRECT=175
+USAMPLER3D=176
+USAMPLERBUFFER=177
+USAMPLERCUBE=178
+USAMPLERCUBEARRAY=179
+USUBPASSINPUT=180
+USUBPASSINPUTMS=181
+UTEXTURE1D=182
+UTEXTURE1DARRAY=183
+UTEXTURE2D=184
+UTEXTURE2DARRAY=185
+UTEXTURE2DMS=186
+UTEXTURE2DMSARRAY=187
+UTEXTURE2DRECT=188
+UTEXTURE3D=189
+UTEXTUREBUFFER=190
+UTEXTURECUBE=191
+UTEXTURECUBEARRAY=192
+UVEC2=193
+UVEC3=194
+UVEC4=195
+VARYING=196
+VEC2=197
+VEC3=198
+VEC4=199
+VOID=200
+VOLATILE=201
+WHILE=202
+WRITEONLY=203
+ADD_ASSIGN=204
+AMPERSAND=205
+AND_ASSIGN=206
+AND_OP=207
+BANG=208
+CARET=209
+COLON=210
+COMMA=211
+DASH=212
+DEC_OP=213
+DIV_ASSIGN=214
+DOT=215
+EQ_OP=216
+EQUAL=217
+GE_OP=218
+INC_OP=219
+LE_OP=220
+LEFT_ANGLE=221
+LEFT_ASSIGN=222
+LEFT_BRACE=223
+LEFT_BRACKET=224
+LEFT_OP=225
+LEFT_PAREN=226
+MOD_ASSIGN=227
+MUL_ASSIGN=228
+NE_OP=229
+NUMBER_SIGN=230
+OR_ASSIGN=231
+OR_OP=232
+PERCENT=233
+PLUS=234
+QUESTION=235
+RIGHT_ANGLE=236
+RIGHT_ASSIGN=237
+RIGHT_BRACE=238
+RIGHT_BRACKET=239
+RIGHT_OP=240
+RIGHT_PAREN=241
+SEMICOLON=242
+SLASH=243
+STAR=244
+SUB_ASSIGN=245
+TILDE=246
+VERTICAL_BAR=247
+XOR_ASSIGN=248
+XOR_OP=249
+DOUBLECONSTANT=250
+FLOATCONSTANT=251
+INTCONSTANT=252
+UINTCONSTANT=253
+BLOCK_COMMENT=254
+LINE_COMMENT=255
+LINE_CONTINUATION=256
+IDENTIFIER=257
+WHITE_SPACE=258
+DEFINE_DIRECTIVE=259
+ELIF_DIRECTIVE=260
+ELSE_DIRECTIVE=261
+ENDIF_DIRECTIVE=262
+ERROR_DIRECTIVE=263
+EXTENSION_DIRECTIVE=264
+IF_DIRECTIVE=265
+IFDEF_DIRECTIVE=266
+IFNDEF_DIRECTIVE=267
+LINE_DIRECTIVE=268
+PRAGMA_DIRECTIVE=269
+UNDEF_DIRECTIVE=270
+VERSION_DIRECTIVE=271
+SPACE_TAB_0=272
+NEWLINE_0=273
+MACRO_NAME=274
+NEWLINE_1=275
+SPACE_TAB_1=276
+CONSTANT_EXPRESSION=277
+NEWLINE_2=278
+ERROR_MESSAGE=279
+NEWLINE_3=280
+BEHAVIOR=281
+EXTENSION_NAME=282
+NEWLINE_4=283
+SPACE_TAB_2=284
+NEWLINE_5=285
+MACRO_IDENTIFIER=286
+NEWLINE_6=287
+SPACE_TAB_3=288
+LINE_EXPRESSION=289
+NEWLINE_7=290
+MACRO_ESC_NEWLINE=291
+MACRO_TEXT=292
+NEWLINE_8=293
+DEBUG=294
+NEWLINE_9=295
+OFF=296
+ON=297
+OPTIMIZE=298
+SPACE_TAB_5=299
+STDGL=300
+PROGRAM_TEXT=301
+NEWLINE_10=302
+SPACE_TAB_6=303
+NEWLINE_11=304
+NUMBER=305
+PROFILE=306
+SPACE_TAB_7=307
+'atomic_uint'=1
+'attribute'=2
+'bool'=3
+'break'=4
+'buffer'=5
+'bvec2'=6
+'bvec3'=7
+'bvec4'=8
+'case'=9
+'centroid'=10
+'coherent'=11
+'const'=12
+'continue'=13
+'default'=14
+'discard'=15
+'dmat2'=16
+'dmat2x2'=17
+'dmat2x3'=18
+'dmat2x4'=19
+'dmat3'=20
+'dmat3x2'=21
+'dmat3x3'=22
+'dmat3x4'=23
+'dmat4'=24
+'dmat4x2'=25
+'dmat4x3'=26
+'dmat4x4'=27
+'do'=28
+'double'=29
+'dvec2'=30
+'dvec3'=31
+'dvec4'=32
+'else'=33
+'false'=34
+'flat'=35
+'float'=36
+'for'=37
+'highp'=38
+'if'=39
+'iimage1D'=40
+'iimage1DArray'=41
+'iimage2D'=42
+'iimage2DArray'=43
+'iimage2DMS'=44
+'iimage2DMSArray'=45
+'iimage2DRect'=46
+'iimage3D'=47
+'iimageBuffer'=48
+'iimageCube'=49
+'iimageCubeArray'=50
+'image1D'=51
+'image1DArray'=52
+'image2D'=53
+'image2DArray'=54
+'image2DMS'=55
+'image2DMSArray'=56
+'image2DRect'=57
+'image3D'=58
+'imageBuffer'=59
+'imageCube'=60
+'imageCubeArray'=61
+'in'=62
+'inout'=63
+'int'=64
+'invariant'=65
+'isampler1D'=66
+'isampler1DArray'=67
+'isampler2D'=68
+'isampler2DArray'=69
+'isampler2DMS'=70
+'isampler2DMSArray'=71
+'isampler2DRect'=72
+'isampler3D'=73
+'isamplerBuffer'=74
+'isamplerCube'=75
+'isamplerCubeArray'=76
+'isubpassInput'=77
+'isubpassInputMS'=78
+'itexture1D'=79
+'itexture1DArray'=80
+'itexture2D'=81
+'itexture2DArray'=82
+'itexture2DMS'=83
+'itexture2DMSArray'=84
+'itexture2DRect'=85
+'itexture3D'=86
+'itextureBuffer'=87
+'itextureCube'=88
+'itextureCubeArray'=89
+'ivec2'=90
+'ivec3'=91
+'ivec4'=92
+'layout'=93
+'lowp'=94
+'mat2'=95
+'mat2x2'=96
+'mat2x3'=97
+'mat2x4'=98
+'mat3'=99
+'mat3x2'=100
+'mat3x3'=101
+'mat3x4'=102
+'mat4'=103
+'mat4x2'=104
+'mat4x3'=105
+'mat4x4'=106
+'mediump'=107
+'noperspective'=108
+'out'=109
+'patch'=110
+'precise'=111
+'precision'=112
+'readonly'=113
+'restrict'=114
+'return'=115
+'sample'=116
+'sampler'=117
+'sampler1D'=118
+'sampler1DArray'=119
+'sampler1DArrayShadow'=120
+'sampler1DShadow'=121
+'sampler2D'=122
+'sampler2DArray'=123
+'sampler2DArrayShadow'=124
+'sampler2DMS'=125
+'sampler2DMSArray'=126
+'sampler2DRect'=127
+'sampler2DRectShadow'=128
+'sampler2DShadow'=129
+'sampler3D'=130
+'samplerBuffer'=131
+'samplerCube'=132
+'samplerCubeArray'=133
+'samplerCubeArrayShadow'=134
+'samplerCubeShadow'=135
+'samplerShadow'=136
+'shared'=137
+'smooth'=138
+'struct'=139
+'subpassInput'=140
+'subpassInputMS'=141
+'subroutine'=142
+'switch'=143
+'texture1D'=144
+'texture1DArray'=145
+'texture2D'=146
+'texture2DArray'=147
+'texture2DMS'=148
+'texture2DMSArray'=149
+'texture2DRect'=150
+'texture3D'=151
+'textureBuffer'=152
+'textureCube'=153
+'textureCubeArray'=154
+'true'=155
+'uimage1D'=156
+'uimage1DArray'=157
+'uimage2D'=158
+'uimage2DArray'=159
+'uimage2DMS'=160
+'uimage2DMSArray'=161
+'uimage2DRect'=162
+'uimage3D'=163
+'uimageBuffer'=164
+'uimageCube'=165
+'uimageCubeArray'=166
+'uint'=167
+'uniform'=168
+'usampler1D'=169
+'usampler1DArray'=170
+'usampler2D'=171
+'usampler2DArray'=172
+'usampler2DMS'=173
+'usampler2DMSArray'=174
+'usampler2DRect'=175
+'usampler3D'=176
+'usamplerBuffer'=177
+'usamplerCube'=178
+'usamplerCubeArray'=179
+'usubpassInput'=180
+'usubpassInputMS'=181
+'utexture1D'=182
+'utexture1DArray'=183
+'utexture2D'=184
+'utexture2DArray'=185
+'utexture2DMS'=186
+'utexture2DMSArray'=187
+'utexture2DRect'=188
+'utexture3D'=189
+'utextureBuffer'=190
+'utextureCube'=191
+'utextureCubeArray'=192
+'uvec2'=193
+'uvec3'=194
+'uvec4'=195
+'varying'=196
+'vec2'=197
+'vec3'=198
+'vec4'=199
+'void'=200
+'volatile'=201
+'while'=202
+'writeonly'=203
+'+='=204
+'&'=205
+'&='=206
+'&&'=207
+'!'=208
+'^'=209
+':'=210
+','=211
+'-'=212
+'--'=213
+'/='=214
+'.'=215
+'=='=216
+'='=217
+'>='=218
+'++'=219
+'<='=220
+'<'=221
+'<<='=222
+'{'=223
+'['=224
+'<<'=225
+'('=226
+'%='=227
+'*='=228
+'!='=229
+'|='=231
+'||'=232
+'%'=233
+'+'=234
+'?'=235
+'>'=236
+'>>='=237
+'}'=238
+']'=239
+'>>'=240
+')'=241
+';'=242
+'/'=243
+'*'=244
+'-='=245
+'~'=246
+'|'=247
+'^='=248
+'^^'=249
+'debug'=294
+'off'=296
+'on'=297
+'optimize'=298
+'STDGL'=300
diff --git a/src/main/gen/GLSLPreParserBaseListener.java b/src/main/gen/GLSLPreParserBaseListener.java
new file mode 100644
index 0000000..d45aaf0
--- /dev/null
+++ b/src/main/gen/GLSLPreParserBaseListener.java
@@ -0,0 +1,450 @@
+// Generated from D:/git/glsl-transformation-lib/src/main/antlr/GLSLPreParser.g4 by ANTLR 4.13.1
+
+ package org.taumc.glsl.grammar;
+
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+/**
+ * This class provides an empty implementation of {@link GLSLPreParserListener},
+ * which can be extended to create a listener which only needs to handle a subset
+ * of the available methods.
+ */
+@SuppressWarnings("CheckReturnValue")
+public class GLSLPreParserBaseListener implements GLSLPreParserListener {
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterTranslation_unit(GLSLPreParser.Translation_unitContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitTranslation_unit(GLSLPreParser.Translation_unitContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterBehavior(GLSLPreParser.BehaviorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitBehavior(GLSLPreParser.BehaviorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterConstant_expression(GLSLPreParser.Constant_expressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitConstant_expression(GLSLPreParser.Constant_expressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterDefine_directive(GLSLPreParser.Define_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitDefine_directive(GLSLPreParser.Define_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterElif_directive(GLSLPreParser.Elif_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitElif_directive(GLSLPreParser.Elif_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterElse_directive(GLSLPreParser.Else_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitElse_directive(GLSLPreParser.Else_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterEndif_directive(GLSLPreParser.Endif_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitEndif_directive(GLSLPreParser.Endif_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterError_directive(GLSLPreParser.Error_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitError_directive(GLSLPreParser.Error_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterError_message(GLSLPreParser.Error_messageContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitError_message(GLSLPreParser.Error_messageContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterExtension_directive(GLSLPreParser.Extension_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitExtension_directive(GLSLPreParser.Extension_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterExtension_name(GLSLPreParser.Extension_nameContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitExtension_name(GLSLPreParser.Extension_nameContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterIf_directive(GLSLPreParser.If_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitIf_directive(GLSLPreParser.If_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterLine_directive(GLSLPreParser.Line_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitLine_directive(GLSLPreParser.Line_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterLine_expression(GLSLPreParser.Line_expressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitLine_expression(GLSLPreParser.Line_expressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacro_identifier(GLSLPreParser.Macro_identifierContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacro_identifier(GLSLPreParser.Macro_identifierContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacro_name(GLSLPreParser.Macro_nameContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacro_name(GLSLPreParser.Macro_nameContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacro_text(GLSLPreParser.Macro_textContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacro_text(GLSLPreParser.Macro_textContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacro_text_(GLSLPreParser.Macro_text_Context ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacro_text_(GLSLPreParser.Macro_text_Context ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterNumber(GLSLPreParser.NumberContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitNumber(GLSLPreParser.NumberContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterOff(GLSLPreParser.OffContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitOff(GLSLPreParser.OffContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterOn(GLSLPreParser.OnContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitOn(GLSLPreParser.OnContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterPragma_debug(GLSLPreParser.Pragma_debugContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitPragma_debug(GLSLPreParser.Pragma_debugContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterPragma_directive(GLSLPreParser.Pragma_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitPragma_directive(GLSLPreParser.Pragma_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterProfile(GLSLPreParser.ProfileContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitProfile(GLSLPreParser.ProfileContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterProgram_text(GLSLPreParser.Program_textContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitProgram_text(GLSLPreParser.Program_textContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterStdgl(GLSLPreParser.StdglContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitStdgl(GLSLPreParser.StdglContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterUndef_directive(GLSLPreParser.Undef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitUndef_directive(GLSLPreParser.Undef_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterVersion_directive(GLSLPreParser.Version_directiveContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitVersion_directive(GLSLPreParser.Version_directiveContext ctx) { }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void visitTerminal(TerminalNode node) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void visitErrorNode(ErrorNode node) { }
+}
\ No newline at end of file
diff --git a/src/main/gen/GLSLPreParserBaseVisitor.java b/src/main/gen/GLSLPreParserBaseVisitor.java
new file mode 100644
index 0000000..cae8d93
--- /dev/null
+++ b/src/main/gen/GLSLPreParserBaseVisitor.java
@@ -0,0 +1,255 @@
+// Generated from D:/git/glsl-transformation-lib/src/main/antlr/GLSLPreParser.g4 by ANTLR 4.13.1
+
+ package org.taumc.glsl.grammar;
+
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+/**
+ * This class provides an empty implementation of {@link GLSLPreParserVisitor},
+ * which can be extended to create a visitor which only needs to handle a subset
+ * of the available methods.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+@SuppressWarnings("CheckReturnValue")
+public class GLSLPreParserBaseVisitor extends AbstractParseTreeVisitor implements GLSLPreParserVisitor {
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitTranslation_unit(GLSLPreParser.Translation_unitContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitBehavior(GLSLPreParser.BehaviorContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitConstant_expression(GLSLPreParser.Constant_expressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitDefine_directive(GLSLPreParser.Define_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitElif_directive(GLSLPreParser.Elif_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitElse_directive(GLSLPreParser.Else_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitEndif_directive(GLSLPreParser.Endif_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitError_directive(GLSLPreParser.Error_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitError_message(GLSLPreParser.Error_messageContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitExtension_directive(GLSLPreParser.Extension_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitExtension_name(GLSLPreParser.Extension_nameContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIf_directive(GLSLPreParser.If_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitLine_directive(GLSLPreParser.Line_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitLine_expression(GLSLPreParser.Line_expressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacro_identifier(GLSLPreParser.Macro_identifierContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacro_name(GLSLPreParser.Macro_nameContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacro_text(GLSLPreParser.Macro_textContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacro_text_(GLSLPreParser.Macro_text_Context ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitNumber(GLSLPreParser.NumberContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitOff(GLSLPreParser.OffContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitOn(GLSLPreParser.OnContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitPragma_debug(GLSLPreParser.Pragma_debugContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitPragma_directive(GLSLPreParser.Pragma_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitProfile(GLSLPreParser.ProfileContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitProgram_text(GLSLPreParser.Program_textContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitStdgl(GLSLPreParser.StdglContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitUndef_directive(GLSLPreParser.Undef_directiveContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitVersion_directive(GLSLPreParser.Version_directiveContext ctx) { return visitChildren(ctx); }
+}
\ No newline at end of file
diff --git a/src/main/gen/GLSLPreParserListener.java b/src/main/gen/GLSLPreParserListener.java
new file mode 100644
index 0000000..083b968
--- /dev/null
+++ b/src/main/gen/GLSLPreParserListener.java
@@ -0,0 +1,352 @@
+// Generated from D:/git/glsl-transformation-lib/src/main/antlr/GLSLPreParser.g4 by ANTLR 4.13.1
+
+ package org.taumc.glsl.grammar;
+
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+
+/**
+ * This interface defines a complete listener for a parse tree produced by
+ * {@link GLSLPreParser}.
+ */
+public interface GLSLPreParserListener extends ParseTreeListener {
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#translation_unit}.
+ * @param ctx the parse tree
+ */
+ void enterTranslation_unit(GLSLPreParser.Translation_unitContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#translation_unit}.
+ * @param ctx the parse tree
+ */
+ void exitTranslation_unit(GLSLPreParser.Translation_unitContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#compiler_directive}.
+ * @param ctx the parse tree
+ */
+ void enterCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#compiler_directive}.
+ * @param ctx the parse tree
+ */
+ void exitCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#behavior}.
+ * @param ctx the parse tree
+ */
+ void enterBehavior(GLSLPreParser.BehaviorContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#behavior}.
+ * @param ctx the parse tree
+ */
+ void exitBehavior(GLSLPreParser.BehaviorContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#constant_expression}.
+ * @param ctx the parse tree
+ */
+ void enterConstant_expression(GLSLPreParser.Constant_expressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#constant_expression}.
+ * @param ctx the parse tree
+ */
+ void exitConstant_expression(GLSLPreParser.Constant_expressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#define_directive}.
+ * @param ctx the parse tree
+ */
+ void enterDefine_directive(GLSLPreParser.Define_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#define_directive}.
+ * @param ctx the parse tree
+ */
+ void exitDefine_directive(GLSLPreParser.Define_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#elif_directive}.
+ * @param ctx the parse tree
+ */
+ void enterElif_directive(GLSLPreParser.Elif_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#elif_directive}.
+ * @param ctx the parse tree
+ */
+ void exitElif_directive(GLSLPreParser.Elif_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#else_directive}.
+ * @param ctx the parse tree
+ */
+ void enterElse_directive(GLSLPreParser.Else_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#else_directive}.
+ * @param ctx the parse tree
+ */
+ void exitElse_directive(GLSLPreParser.Else_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#endif_directive}.
+ * @param ctx the parse tree
+ */
+ void enterEndif_directive(GLSLPreParser.Endif_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#endif_directive}.
+ * @param ctx the parse tree
+ */
+ void exitEndif_directive(GLSLPreParser.Endif_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#error_directive}.
+ * @param ctx the parse tree
+ */
+ void enterError_directive(GLSLPreParser.Error_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#error_directive}.
+ * @param ctx the parse tree
+ */
+ void exitError_directive(GLSLPreParser.Error_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#error_message}.
+ * @param ctx the parse tree
+ */
+ void enterError_message(GLSLPreParser.Error_messageContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#error_message}.
+ * @param ctx the parse tree
+ */
+ void exitError_message(GLSLPreParser.Error_messageContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#extension_directive}.
+ * @param ctx the parse tree
+ */
+ void enterExtension_directive(GLSLPreParser.Extension_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#extension_directive}.
+ * @param ctx the parse tree
+ */
+ void exitExtension_directive(GLSLPreParser.Extension_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#extension_name}.
+ * @param ctx the parse tree
+ */
+ void enterExtension_name(GLSLPreParser.Extension_nameContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#extension_name}.
+ * @param ctx the parse tree
+ */
+ void exitExtension_name(GLSLPreParser.Extension_nameContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#group_of_lines}.
+ * @param ctx the parse tree
+ */
+ void enterGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#group_of_lines}.
+ * @param ctx the parse tree
+ */
+ void exitGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#if_directive}.
+ * @param ctx the parse tree
+ */
+ void enterIf_directive(GLSLPreParser.If_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#if_directive}.
+ * @param ctx the parse tree
+ */
+ void exitIf_directive(GLSLPreParser.If_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#ifdef_directive}.
+ * @param ctx the parse tree
+ */
+ void enterIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#ifdef_directive}.
+ * @param ctx the parse tree
+ */
+ void exitIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#ifndef_directive}.
+ * @param ctx the parse tree
+ */
+ void enterIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#ifndef_directive}.
+ * @param ctx the parse tree
+ */
+ void exitIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#line_directive}.
+ * @param ctx the parse tree
+ */
+ void enterLine_directive(GLSLPreParser.Line_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#line_directive}.
+ * @param ctx the parse tree
+ */
+ void exitLine_directive(GLSLPreParser.Line_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#line_expression}.
+ * @param ctx the parse tree
+ */
+ void enterLine_expression(GLSLPreParser.Line_expressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#line_expression}.
+ * @param ctx the parse tree
+ */
+ void exitLine_expression(GLSLPreParser.Line_expressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#macro_esc_newline}.
+ * @param ctx the parse tree
+ */
+ void enterMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#macro_esc_newline}.
+ * @param ctx the parse tree
+ */
+ void exitMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#macro_identifier}.
+ * @param ctx the parse tree
+ */
+ void enterMacro_identifier(GLSLPreParser.Macro_identifierContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#macro_identifier}.
+ * @param ctx the parse tree
+ */
+ void exitMacro_identifier(GLSLPreParser.Macro_identifierContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#macro_name}.
+ * @param ctx the parse tree
+ */
+ void enterMacro_name(GLSLPreParser.Macro_nameContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#macro_name}.
+ * @param ctx the parse tree
+ */
+ void exitMacro_name(GLSLPreParser.Macro_nameContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#macro_text}.
+ * @param ctx the parse tree
+ */
+ void enterMacro_text(GLSLPreParser.Macro_textContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#macro_text}.
+ * @param ctx the parse tree
+ */
+ void exitMacro_text(GLSLPreParser.Macro_textContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#macro_text_}.
+ * @param ctx the parse tree
+ */
+ void enterMacro_text_(GLSLPreParser.Macro_text_Context ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#macro_text_}.
+ * @param ctx the parse tree
+ */
+ void exitMacro_text_(GLSLPreParser.Macro_text_Context ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#number}.
+ * @param ctx the parse tree
+ */
+ void enterNumber(GLSLPreParser.NumberContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#number}.
+ * @param ctx the parse tree
+ */
+ void exitNumber(GLSLPreParser.NumberContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#off}.
+ * @param ctx the parse tree
+ */
+ void enterOff(GLSLPreParser.OffContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#off}.
+ * @param ctx the parse tree
+ */
+ void exitOff(GLSLPreParser.OffContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#on}.
+ * @param ctx the parse tree
+ */
+ void enterOn(GLSLPreParser.OnContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#on}.
+ * @param ctx the parse tree
+ */
+ void exitOn(GLSLPreParser.OnContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#pragma_debug}.
+ * @param ctx the parse tree
+ */
+ void enterPragma_debug(GLSLPreParser.Pragma_debugContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#pragma_debug}.
+ * @param ctx the parse tree
+ */
+ void exitPragma_debug(GLSLPreParser.Pragma_debugContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#pragma_directive}.
+ * @param ctx the parse tree
+ */
+ void enterPragma_directive(GLSLPreParser.Pragma_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#pragma_directive}.
+ * @param ctx the parse tree
+ */
+ void exitPragma_directive(GLSLPreParser.Pragma_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#pragma_optimize}.
+ * @param ctx the parse tree
+ */
+ void enterPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#pragma_optimize}.
+ * @param ctx the parse tree
+ */
+ void exitPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#profile}.
+ * @param ctx the parse tree
+ */
+ void enterProfile(GLSLPreParser.ProfileContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#profile}.
+ * @param ctx the parse tree
+ */
+ void exitProfile(GLSLPreParser.ProfileContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#program_text}.
+ * @param ctx the parse tree
+ */
+ void enterProgram_text(GLSLPreParser.Program_textContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#program_text}.
+ * @param ctx the parse tree
+ */
+ void exitProgram_text(GLSLPreParser.Program_textContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#stdgl}.
+ * @param ctx the parse tree
+ */
+ void enterStdgl(GLSLPreParser.StdglContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#stdgl}.
+ * @param ctx the parse tree
+ */
+ void exitStdgl(GLSLPreParser.StdglContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#undef_directive}.
+ * @param ctx the parse tree
+ */
+ void enterUndef_directive(GLSLPreParser.Undef_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#undef_directive}.
+ * @param ctx the parse tree
+ */
+ void exitUndef_directive(GLSLPreParser.Undef_directiveContext ctx);
+ /**
+ * Enter a parse tree produced by {@link GLSLPreParser#version_directive}.
+ * @param ctx the parse tree
+ */
+ void enterVersion_directive(GLSLPreParser.Version_directiveContext ctx);
+ /**
+ * Exit a parse tree produced by {@link GLSLPreParser#version_directive}.
+ * @param ctx the parse tree
+ */
+ void exitVersion_directive(GLSLPreParser.Version_directiveContext ctx);
+}
\ No newline at end of file
diff --git a/src/main/gen/GLSLPreParserVisitor.java b/src/main/gen/GLSLPreParserVisitor.java
new file mode 100644
index 0000000..b496973
--- /dev/null
+++ b/src/main/gen/GLSLPreParserVisitor.java
@@ -0,0 +1,219 @@
+// Generated from D:/git/glsl-transformation-lib/src/main/antlr/GLSLPreParser.g4 by ANTLR 4.13.1
+
+ package org.taumc.glsl.grammar;
+
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+
+/**
+ * This interface defines a complete generic visitor for a parse tree produced
+ * by {@link GLSLPreParser}.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public interface GLSLPreParserVisitor extends ParseTreeVisitor {
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#translation_unit}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitTranslation_unit(GLSLPreParser.Translation_unitContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#compiler_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitCompiler_directive(GLSLPreParser.Compiler_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#behavior}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitBehavior(GLSLPreParser.BehaviorContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#constant_expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitConstant_expression(GLSLPreParser.Constant_expressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#define_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitDefine_directive(GLSLPreParser.Define_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#elif_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitElif_directive(GLSLPreParser.Elif_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#else_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitElse_directive(GLSLPreParser.Else_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#endif_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitEndif_directive(GLSLPreParser.Endif_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#error_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitError_directive(GLSLPreParser.Error_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#error_message}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitError_message(GLSLPreParser.Error_messageContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#extension_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitExtension_directive(GLSLPreParser.Extension_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#extension_name}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitExtension_name(GLSLPreParser.Extension_nameContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#group_of_lines}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGroup_of_lines(GLSLPreParser.Group_of_linesContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#if_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIf_directive(GLSLPreParser.If_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#ifdef_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIfdef_directive(GLSLPreParser.Ifdef_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#ifndef_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIfndef_directive(GLSLPreParser.Ifndef_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#line_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLine_directive(GLSLPreParser.Line_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#line_expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLine_expression(GLSLPreParser.Line_expressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#macro_esc_newline}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacro_esc_newline(GLSLPreParser.Macro_esc_newlineContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#macro_identifier}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacro_identifier(GLSLPreParser.Macro_identifierContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#macro_name}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacro_name(GLSLPreParser.Macro_nameContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#macro_text}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacro_text(GLSLPreParser.Macro_textContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#macro_text_}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacro_text_(GLSLPreParser.Macro_text_Context ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#number}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitNumber(GLSLPreParser.NumberContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#off}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitOff(GLSLPreParser.OffContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#on}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitOn(GLSLPreParser.OnContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#pragma_debug}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitPragma_debug(GLSLPreParser.Pragma_debugContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#pragma_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitPragma_directive(GLSLPreParser.Pragma_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#pragma_optimize}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitPragma_optimize(GLSLPreParser.Pragma_optimizeContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#profile}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitProfile(GLSLPreParser.ProfileContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#program_text}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitProgram_text(GLSLPreParser.Program_textContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#stdgl}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitStdgl(GLSLPreParser.StdglContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#undef_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitUndef_directive(GLSLPreParser.Undef_directiveContext ctx);
+ /**
+ * Visit a parse tree produced by {@link GLSLPreParser#version_directive}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitVersion_directive(GLSLPreParser.Version_directiveContext ctx);
+}
\ No newline at end of file
diff --git a/src/main/java/org/taumc/glsl/AppendFunction.java b/src/main/java/org/taumc/glsl/AppendFunction.java
new file mode 100644
index 0000000..a7a154f
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/AppendFunction.java
@@ -0,0 +1,27 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.taumc.glsl.grammar.GLSLLexer;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+public class AppendFunction extends GLSLParserBaseListener {
+
+ private final String name;
+ private final GLSLParser.StatementContext insert;
+
+ public AppendFunction(String name, String code) {
+ this.name = name;
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(code));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ this.insert = parser.statement();
+ }
+
+ @Override
+ public void enterFunction_definition(GLSLParser.Function_definitionContext ctx) {
+ if (ctx.function_prototype().IDENTIFIER().getText().equals(name)) {
+ ctx.compound_statement_no_new_scope().statement_list().children.add(insert);
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/ArrayExpressionRewriteListener.java b/src/main/java/org/taumc/glsl/ArrayExpressionRewriteListener.java
new file mode 100644
index 0000000..e75f13d
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ArrayExpressionRewriteListener.java
@@ -0,0 +1,44 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ArrayExpressionRewriteListener extends GLSLParserBaseListener {
+
+ private final Map replacements;
+ private final Set found;
+
+ public ArrayExpressionRewriteListener(Map replacements, Set found) {
+ this.replacements = replacements;
+ this.found = found;
+ }
+
+ @Override
+ public void enterPostfix_expression(GLSLParser.Postfix_expressionContext ctx) {
+ if (ctx.postfix_expression() == null) {
+ return;
+ }
+ if (ctx.postfix_expression().primary_expression() == null) {
+ return;
+ }
+ if (ctx.postfix_expression().primary_expression().variable_identifier() == null) {
+ return;
+ }
+ if (ctx.postfix_expression().primary_expression().variable_identifier().IDENTIFIER().getSymbol() instanceof CommonToken cToken) {
+ String replacement = replacements.get(cToken.getText());
+ if(replacement != null && ctx.integer_expression() != null) {
+ String i = ctx.integer_expression().getText();
+ found.add(Integer.parseInt(i));
+ cToken.setText(replacement + i);
+ ctx.removeLastChild();
+ ctx.removeLastChild();
+ ctx.removeLastChild();
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/AssigmentChecker.java b/src/main/java/org/taumc/glsl/AssigmentChecker.java
new file mode 100644
index 0000000..4987615
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/AssigmentChecker.java
@@ -0,0 +1,24 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class AssigmentChecker extends GLSLParserBaseListener {
+
+ private final String name;
+ private final AtomicBoolean atomicBoolean;
+
+ public AssigmentChecker(String name, AtomicBoolean atomicBoolean) {
+ this.name = name;
+ this.atomicBoolean = atomicBoolean;
+ }
+
+ @Override
+ public void enterAssignment_expression(GLSLParser.Assignment_expressionContext ctx) {
+ if (ctx.unary_expression() != null && (ctx.unary_expression().getText().startsWith(this.name) || ctx.unary_expression().getText().startsWith(this.name + "."))) {
+ atomicBoolean.set(true);
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/BuiltinFunction.java b/src/main/java/org/taumc/glsl/BuiltinFunction.java
new file mode 100644
index 0000000..40ab675
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/BuiltinFunction.java
@@ -0,0 +1,82 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLLexer;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.IntFunction;
+import java.util.stream.Collectors;
+
+public enum BuiltinFunction {
+
+ BOOL(GLSLLexer.BOOL, "false"),
+ BVEC2(GLSLLexer.BVEC2, "bvec2(false)"),
+ BVEC3(GLSLLexer.BVEC3, "bvec3(false)"),
+ BVEC4(GLSLLexer.BVEC4, "bvec4(false)"),
+
+ DOUBLE(GLSLLexer.DOUBLE, "0.0d"),
+ DVEC2(GLSLLexer.DVEC2, "dvec2(0.0d)"),
+ DVEC3(GLSLLexer.DVEC3, "dvec3(0.0d)"),
+ DVEC4(GLSLLexer.DVEC4, "dvec4(0.0d)"),
+ DMAT2(GLSLLexer.DMAT2, "dmat2(0.0d)"),
+ DMAT2X2(GLSLLexer.DMAT2X2, "dmat2x2(0.0d)"),
+ DMAT2X3(GLSLLexer.DMAT2X3, "dmat2x3(0.0d)"),
+ DMAT2X4(GLSLLexer.DMAT2X4, "dmat2x4(0.0d)"),
+ DMAT3(GLSLLexer.DMAT3, "dmat3(0.0d)"),
+ DMAT3X2(GLSLLexer.DMAT3X2, "dmat3x2(0.0d)"),
+ DMAT3X3(GLSLLexer.DMAT3X3, "dmat3x3(0.0d)"),
+ DMAT3X4(GLSLLexer.DMAT3X4, "dmat3x4(0.0d)"),
+ DMAT4(GLSLLexer.DMAT4, "dmat4(0.0d)"),
+ DMAT4X2(GLSLLexer.DMAT4X2, "dmat4x2(0.0d)"),
+ DMAT4X3(GLSLLexer.DMAT4X3, "dmat4x3(0.0d)"),
+ DMAT4X4(GLSLLexer.DMAT4X4, "dmat4x4(0.0d)"),
+
+ FLOAT(GLSLLexer.FLOAT, "0.0f"),
+ VEC2(GLSLLexer.VEC2, "vec2(0.0f)"),
+ VEC3(GLSLLexer.VEC3, "vec3(0.0f)"),
+ VEC4(GLSLLexer.VEC4, "vec4(0.0f)"),
+ MAT2(GLSLLexer.MAT2, "mat2(0.0f)"),
+ MAT2X2(GLSLLexer.MAT2X2, "mat2x2(0.0f)"),
+ MAT2X3(GLSLLexer.MAT2X3, "mat2x3(0.0f)"),
+ MAT2X4(GLSLLexer.MAT2X4, "mat2x4(0.0f)"),
+ MAT3(GLSLLexer.MAT3, "mat3(0.0f)"),
+ MAT3X2(GLSLLexer.MAT3X2, "mat3x2(0.0f)"),
+ MAT3X3(GLSLLexer.MAT3X3, "mat3x3(0.0f)"),
+ MAT3X4(GLSLLexer.MAT3X4, "mat3x4(0.0f)"),
+ MAT4(GLSLLexer.MAT4, "mat4(0.0f)"),
+ MAT4X2(GLSLLexer.MAT4X2, "mat4x2(0.0f)"),
+ MAT4X3(GLSLLexer.MAT4X3, "mat4x3(0.0f)"),
+ MAT4X4(GLSLLexer.MAT4X4, "mat4x4(0.0f)"),
+
+ INT(GLSLLexer.INT, "0"),
+ IVEC2(GLSLLexer.IVEC2, "ivec2(0)"),
+ IVEC3(GLSLLexer.IVEC3, "ivec3(0)"),
+ IVEC4(GLSLLexer.IVEC4, "ivec4(0)"),
+
+ UINT(GLSLLexer.UINT, "0u"),
+ UVEC2(GLSLLexer.UVEC2, "uvec2(0u)"),
+ UVEC3(GLSLLexer.UVEC3, "uvec3(0u)"),
+ UVEC4(GLSLLexer.UVEC4, "uvec4(0u)");
+
+ private final String initializer;
+ private final int type;
+ private static final Map BY_TYPE = Arrays.stream(values()).collect(Collectors.toMap(BuiltinFunction::getType, b-> b));
+
+ BuiltinFunction(int type, String initializer) {
+ this.type = type;
+ this.initializer = initializer;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getInitializer() {
+ return initializer;
+ }
+
+ public static BuiltinFunction getByType(int type) {
+ return BY_TYPE.get(type);
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/ConstAssignmentRemover.java b/src/main/java/org/taumc/glsl/ConstAssignmentRemover.java
new file mode 100644
index 0000000..230294e
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ConstAssignmentRemover.java
@@ -0,0 +1,51 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.List;
+
+public class ConstAssignmentRemover extends GLSLParserBaseListener {
+
+ private final String function;
+ private final List variables;
+
+ public ConstAssignmentRemover(String function, List variables) {
+ this.function = function;
+ this.variables = variables;
+ }
+
+ @Override
+ public void enterVariable_identifier(GLSLParser.Variable_identifierContext ctx) {
+ if (variables.contains(ctx.IDENTIFIER().getText())) {
+ var parent = ctx.getParent();
+ while (!(parent instanceof GLSLParser.Function_definitionContext definitionContext)) {
+ parent = parent.getParent();
+ if (parent == null) {
+ return;
+ }
+ }
+
+ if (definitionContext.function_prototype().IDENTIFIER().getText().equals(this.function)) {
+ parent = ctx.getParent();
+ while (!(parent instanceof GLSLParser.Single_declarationContext declarationContext)) {
+ parent = parent.getParent();
+ if (parent == null) {
+ return;
+ }
+ }
+
+ variables.add(declarationContext.typeless_declaration().IDENTIFIER().getText());
+
+ GLSLParser.Type_qualifierContext typeQualifierContext = declarationContext.fully_specified_type().type_qualifier();
+ if (typeQualifierContext == null || typeQualifierContext.single_type_qualifier(0) == null) {
+ return;
+ }
+ GLSLParser.Storage_qualifierContext storageQualifierContext = typeQualifierContext.single_type_qualifier(0).storage_qualifier();
+ if (storageQualifierContext != null && storageQualifierContext.CONST() != null) {
+ declarationContext.fully_specified_type().children.remove(typeQualifierContext);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/ConstParameterFinder.java b/src/main/java/org/taumc/glsl/ConstParameterFinder.java
new file mode 100644
index 0000000..5564d57
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ConstParameterFinder.java
@@ -0,0 +1,42 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class ConstParameterFinder extends GLSLParserBaseListener {
+
+ private final Map> functions;
+
+ public ConstParameterFinder(Map> functions) {
+ this.functions = functions;
+ }
+
+ @Override
+ public void enterParameter_declaration(GLSLParser.Parameter_declarationContext ctx) {
+ GLSLParser.Type_qualifierContext typeQualifierContext = ctx.type_qualifier();
+ if (typeQualifierContext == null) {
+ return;
+ }
+ GLSLParser.Single_type_qualifierContext singleTypeQualifierContext = typeQualifierContext.single_type_qualifier(0);
+ if (singleTypeQualifierContext == null) {
+ return;
+ }
+ GLSLParser.Storage_qualifierContext storageQualifierContext = singleTypeQualifierContext.storage_qualifier();
+ if (storageQualifierContext != null && storageQualifierContext.CONST() != null) {
+ if (ctx.getParent().getParent() instanceof GLSLParser.Function_prototypeContext proto) {
+ if (this.functions.containsKey(proto.IDENTIFIER().getText())) {
+ this.functions.get(proto.IDENTIFIER().getText()).add(ctx.parameter_declarator().IDENTIFIER().getText());
+
+ } else {
+ List params = new ArrayList<>();
+ params.add(ctx.parameter_declarator().IDENTIFIER().getText());
+ this.functions.put(proto.IDENTIFIER().getText(), params);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/ExpressionRenamer.java b/src/main/java/org/taumc/glsl/ExpressionRenamer.java
new file mode 100644
index 0000000..edabfab
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ExpressionRenamer.java
@@ -0,0 +1,41 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.Map;
+
+public class ExpressionRenamer extends GLSLParserBaseListener {
+ private final Map replacements;
+
+ public ExpressionRenamer(Map replacements) {
+ this.replacements = replacements;
+ }
+
+ private void handleIdentifier(TerminalNode node) {
+ Token token = node.getSymbol();
+ if(token instanceof CommonToken cToken) {
+ String replacement = replacements.get(cToken.getText());
+ if(replacement != null) {
+ cToken.setText(replacement);
+ }
+ }
+ }
+
+ @Override
+ public void enterVariable_identifier(GLSLParser.Variable_identifierContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+
+ @Override
+ public void enterFunction_prototype(GLSLParser.Function_prototypeContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/FastTreeWalker.java b/src/main/java/org/taumc/glsl/FastTreeWalker.java
new file mode 100644
index 0000000..2669b07
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/FastTreeWalker.java
@@ -0,0 +1,50 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+import org.antlr.v4.runtime.tree.RuleNode;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+/**
+ * Extended version of ANTLR's {@link org.antlr.v4.runtime.tree.ParseTreeWalker} that can
+ * exit the walk early.
+ */
+public class FastTreeWalker {
+ public static void walk(GLSLCancelableBaseListener listener, ParseTree t) {
+ if(!listener.shouldKeepWalking()) {
+ return;
+ }
+ if (t instanceof ErrorNode error) {
+ listener.visitErrorNode(error);
+ } else if (t instanceof TerminalNode terminal) {
+ listener.visitTerminal(terminal);
+ } else {
+ RuleNode r = (RuleNode)t;
+ enterRule(listener, r);
+ if(listener.shouldKeepWalking()) {
+ int n = r.getChildCount();
+ for (int i = 0; i functions;
+
+ FunctionCollector(List functions) {
+ this.functions = functions;
+ }
+
+ @Override
+ public void enterFunction_prototype(GLSLParser.Function_prototypeContext ctx) {
+ this.functions.add(ctx.IDENTIFIER().getText());
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/FunctionInjector.java b/src/main/java/org/taumc/glsl/FunctionInjector.java
new file mode 100644
index 0000000..2f36930
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/FunctionInjector.java
@@ -0,0 +1,23 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+public class FunctionInjector extends GLSLParserBaseListener {
+ private final AtomicReference atomic;
+
+ public FunctionInjector(AtomicReference atomic) {
+ this.atomic = atomic;
+ }
+
+ @Override
+ public void enterFunction_definition(GLSLParser.Function_definitionContext ctx) {
+ if (ctx.getParent() instanceof GLSLParser.External_declarationContext list) {
+ if (atomic.get() == null) {
+ atomic.set(list);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/FunctionRemover.java b/src/main/java/org/taumc/glsl/FunctionRemover.java
new file mode 100644
index 0000000..270052c
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/FunctionRemover.java
@@ -0,0 +1,28 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class FunctionRemover extends GLSLCancelableBaseListener {
+
+ private final String name;
+ private final AtomicReference function;
+
+ public FunctionRemover(String name, AtomicReference function) {
+ this.name = name;
+ this.function = function;
+ }
+
+ @Override
+ public void enterFunction_prototype(GLSLParser.Function_prototypeContext ctx) {
+ if (ctx.IDENTIFIER().getText().equals(this.name)) {
+ if (ctx.getParent().getParent() instanceof GLSLParser.External_declarationContext declarationContext) {
+ function.set(declarationContext);
+ keepWalking = false;
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/GLSLCancelableBaseListener.java b/src/main/java/org/taumc/glsl/GLSLCancelableBaseListener.java
new file mode 100644
index 0000000..238cae0
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/GLSLCancelableBaseListener.java
@@ -0,0 +1,11 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+public class GLSLCancelableBaseListener extends GLSLParserBaseListener {
+ protected boolean keepWalking = true;
+
+ public final boolean shouldKeepWalking() {
+ return keepWalking;
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/HasVariable.java b/src/main/java/org/taumc/glsl/HasVariable.java
new file mode 100644
index 0000000..5f8de3c
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/HasVariable.java
@@ -0,0 +1,43 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class HasVariable extends GLSLParserBaseListener {
+
+ private final String name;
+ private AtomicBoolean atomicBoolean;
+
+ public HasVariable(String name, AtomicBoolean atomicBoolean) {
+ this.name = name;
+ this.atomicBoolean = atomicBoolean;
+ }
+
+ private void handleIdentifier(TerminalNode node) {
+ Token token = node.getSymbol();
+ if(token instanceof CommonToken cToken) {
+ if (name.equals(cToken.getText())) {
+ atomicBoolean.set(true);
+ }
+ }
+ }
+
+ @Override
+ public void enterTypeless_declaration(GLSLParser.Typeless_declarationContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+
+ @Override
+ public void enterFunction_prototype(GLSLParser.Function_prototypeContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/IdentifierCollector.java b/src/main/java/org/taumc/glsl/IdentifierCollector.java
new file mode 100644
index 0000000..3fbef4c
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/IdentifierCollector.java
@@ -0,0 +1,39 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public class IdentifierCollector extends GLSLCancelableBaseListener {
+ private final Predicate identifierConsumer;
+
+ /**
+ * Construct a new identifier collector.
+ * @param identifierConsumer Called with each identifier, return false to stop walking the tree
+ */
+ public IdentifierCollector(Predicate identifierConsumer) {
+ this.identifierConsumer = identifierConsumer;
+ }
+
+ private void handleIdentifier(TerminalNode node) {
+ Token token = node.getSymbol();
+ if(token instanceof CommonToken cToken) {
+ if(!identifierConsumer.test(cToken.getText())) {
+ keepWalking = false;
+ }
+ }
+ }
+
+ @Override
+ public void enterVariable_identifier(GLSLParser.Variable_identifierContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/Main.java b/src/main/java/org/taumc/glsl/Main.java
new file mode 100644
index 0000000..649e33c
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/Main.java
@@ -0,0 +1,75 @@
+package org.taumc.glsl;
+
+import org.anarres.cpp.CppReader;
+import org.anarres.cpp.Preprocessor;
+import org.antlr.v4.runtime.BufferedTokenStream;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLLexer;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLPreParser;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class Main {
+ public static String tab = "";
+
+ public static void main(String[] args) throws Exception {
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromReader(new CppReader(new Preprocessor(new File("test.glsl")))));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ GLSLPreParser preParser = new GLSLPreParser(new BufferedTokenStream(lexer));
+ System.out.println(getFormattedShader(preParser.translation_unit()));
+
+ parser.setBuildParseTree(true);
+ var translationUnit = parser.translation_unit();
+
+ Util.injectVariable(translationUnit, "in ivec2 a_LightCoord2;");
+ Util.rename(translationUnit, "a_Color", "rewritten_Color");
+ Set found = new HashSet<>();
+ Util.renameArray(translationUnit, "test", "replaced", found);
+ Util.removeVariable(translationUnit, "_vert_tex_diffuse_coord");
+ Util.removeConstAssignment(translationUnit);
+ Util.renameFunctionCall(translationUnit, "_vert_init", "newCall");
+ Util.renameAndWrapShadow(translationUnit, "function", "wrapped");
+ Util.prependMain(translationUnit, "injected = 5;");
+ Util.replaceExpression(translationUnit, "vartest", "unint(5)");
+ Util.removeUnusedFunctions(translationUnit);
+ Util.rewriteStructArrays(translationUnit);
+ System.out.println(getFormattedShader(translationUnit));
+
+ ShaderViewerGUI.display(parser, translationUnit);
+ }
+
+ private static String getFormattedShader(ParseTree tree) {
+ StringBuilder sb = new StringBuilder();
+ getFormattedShader(tree, sb);
+ return sb.toString();
+ }
+
+ private static void getFormattedShader(ParseTree tree, StringBuilder stringBuilder) {
+ if (tree instanceof TerminalNode) {
+ String text = tree.getText();
+ stringBuilder.append(text);
+ if (text.equals("{")) {
+ stringBuilder.append(" \n\t"); //TODO fix indent
+ tab = "\t";
+ }
+ if (text.equals("}")) {
+ stringBuilder.deleteCharAt(stringBuilder.length() - 2);
+ tab = "";
+ }
+ stringBuilder.append(text.equals(";") ? " \n" + tab : " ");
+ } else {
+ for(int i = 0; i < tree.getChildCount(); i++) {
+ getFormattedShader(tree.getChild(i), stringBuilder);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/PrependFunction.java b/src/main/java/org/taumc/glsl/PrependFunction.java
new file mode 100644
index 0000000..2ef1534
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/PrependFunction.java
@@ -0,0 +1,28 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.taumc.glsl.grammar.GLSLLexer;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+public class PrependFunction extends GLSLParserBaseListener {
+
+ private final String name;
+ private final GLSLParser.StatementContext insert;
+
+ public PrependFunction(String name, String code) {
+ this.name = name;
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(code));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ this.insert = parser.statement();
+ }
+
+ @Override
+ public void enterFunction_definition(GLSLParser.Function_definitionContext ctx) {
+ if (ctx.function_prototype().IDENTIFIER().getText().equals(name)) {
+ ctx.compound_statement_no_new_scope().statement_list().children.add(0, insert);
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/QualifierFinder.java b/src/main/java/org/taumc/glsl/QualifierFinder.java
new file mode 100644
index 0000000..27a8780
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/QualifierFinder.java
@@ -0,0 +1,45 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.List;
+import java.util.Map;
+
+public class QualifierFinder extends GLSLParserBaseListener {
+
+ private final int type;
+ private final Map nodes;
+
+ public QualifierFinder(int type, Map nodes) {
+ this.type = type;
+ this.nodes = nodes;
+ }
+
+ @Override
+ public void enterStorage_qualifier(GLSLParser.Storage_qualifierContext ctx) {
+ if (ctx.children.get(0) instanceof TerminalNode node &&
+ node.getSymbol() instanceof CommonToken token &&
+ token.getType() == type) {
+ var parent = node.getParent();
+ while (!(parent instanceof GLSLParser.Single_declarationContext declarationContext)) {
+ parent = parent.getParent();
+ if (parent == null) {
+ return;
+ }
+ }
+
+ nodes.put(declarationContext.typeless_declaration().IDENTIFIER().getText(), declarationContext);
+
+ if (declarationContext.getParent() instanceof GLSLParser.Init_declarator_listContext listContext) {
+ if (listContext.typeless_declaration() != null) {
+ for (var entry : listContext.typeless_declaration()) {
+ nodes.put(entry.IDENTIFIER().getText(), declarationContext);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/RemoveVariable.java b/src/main/java/org/taumc/glsl/RemoveVariable.java
new file mode 100644
index 0000000..84c0d98
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/RemoveVariable.java
@@ -0,0 +1,33 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class RemoveVariable extends GLSLParserBaseListener {
+ private final String code;
+ private final AtomicReference top;
+
+ public RemoveVariable(String code, AtomicReference top) {
+ this.code = code;
+ this.top = top;
+ }
+
+ @Override
+ public void exitTypeless_declaration(GLSLParser.Typeless_declarationContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ Token token = ctx.IDENTIFIER().getSymbol();
+ if(token instanceof CommonToken cToken) {
+ if(code.equals(cToken.getText())) {
+ top.set(ctx.getParent().getParent().getParent().getParent());
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/Renamer.java b/src/main/java/org/taumc/glsl/Renamer.java
new file mode 100644
index 0000000..c2b1b77
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/Renamer.java
@@ -0,0 +1,41 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+import org.taumc.glsl.grammar.GLSLParser;
+
+import java.util.Map;
+
+public class Renamer extends GLSLParserBaseListener {
+ private final Map replacements;
+
+ public Renamer(Map replacements) {
+ this.replacements = replacements;
+ }
+
+ private void handleIdentifier(TerminalNode node) {
+ Token token = node.getSymbol();
+ if(token instanceof CommonToken cToken) {
+ String replacement = replacements.get(cToken.getText());
+ if(replacement != null) {
+ cToken.setText(replacement);
+ }
+ }
+ }
+
+ @Override
+ public void enterTypeless_declaration(GLSLParser.Typeless_declarationContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+
+ @Override
+ public void enterVariable_identifier(GLSLParser.Variable_identifierContext ctx) {
+ if (ctx.IDENTIFIER() != null) {
+ handleIdentifier(ctx.IDENTIFIER());
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/ReplaceExpression.java b/src/main/java/org/taumc/glsl/ReplaceExpression.java
new file mode 100644
index 0000000..6818a36
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ReplaceExpression.java
@@ -0,0 +1,45 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.taumc.glsl.grammar.GLSLLexer;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+public class ReplaceExpression extends GLSLParserBaseListener {
+
+ private final GLSLParser.Binary_expressionContext oldExpression;
+ private final String newExpression;
+
+ public ReplaceExpression(String oldExpression, String newExpression) {
+ this.newExpression = newExpression;
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(oldExpression));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ this.oldExpression = parser.binary_expression();
+
+ }
+
+ @Override
+ public void enterBinary_expression(GLSLParser.Binary_expressionContext ctx) {
+ if (ctx.getText().equals(oldExpression.getText())) {
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(newExpression));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ var expr = parser.binary_expression();
+ expr.parent = ctx.getParent();
+ int i = ctx.getParent().children.indexOf(ctx);
+ ctx.getParent().children.set(i, expr);
+ }
+ }
+
+ @Override
+ public void enterVariable_identifier(GLSLParser.Variable_identifierContext ctx) {
+ if (ctx.getText().equals(oldExpression.getText())) {
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(newExpression));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ var expr = parser.postfix_expression();
+ var parent = ctx.getParent().getParent().getParent();
+ int i = parent.children.indexOf(ctx.getParent().getParent());
+ parent.children.set(i, expr);
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/Shader.java b/src/main/java/org/taumc/glsl/Shader.java
new file mode 100644
index 0000000..ea1e233
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/Shader.java
@@ -0,0 +1,77 @@
+//package org.taumc.glsl;
+//
+//import org.taumc.glsl.grammar.GLSLParser;
+//
+//public class Shader {
+//
+// public static void commonnTransform(GLSLParser.Translation_unitContext root) {
+// Util.rename(root,"gl_FogFragCoord", "iris_FogFragCoord");
+// //if vertex
+// Util.injectVariable(root, "out float iris_FogFragCoord;");
+// Util.addMain(root, "iris_FogFragCoord = 0.0f;");
+// // if fragment
+// Util.injectVariable(root, "in float iris_FogFragCoord;");
+//
+// // if vertex
+// Util.injectVariable(root, "vec4 iris_FrontColor;"); //TODO different inject?
+// Util.rename(root, "gl_FrontColor", "iris_FrontColor");
+//
+// //if fragment
+// if (Util.has(root, "gl_FragColor")) {
+// Util.rename(root, "gl_FragColor", "gl_FragData[0]");
+// }
+//
+// if (Util.has(root,"gl_TexCoord")) {
+// Util.rename(root, "gl_TexCoord", "irs_texCoords");
+// Util.injectVariable(root, "in vec4 irs_texCoords[3];");
+// }
+//
+// if (Util.has(root, "gl_Color")) {
+// Util.rename(root, "gl_Color", "irs_Color");
+// Util.injectVariable(root, "in vec4 irs_Color;");
+// }
+//
+// // change gl_FragData[i] to iris_FragDatai
+// Util.renameArray(root, "gl_FragData", "iris_FragData");
+//
+// // addition: rename all uses of texture and gcolor to gtexture if it's *not*
+// // used as a function call.
+// // it only does this if they are declared as samplers and makes sure that there
+// // is only one sampler declaration.
+// //?
+//
+// Util.rename(root, "gl_Fog", "iris_Fog");
+// Util.injectVariable(root, "uniform float iris_FogDensity;",
+// "uniform float iris_FogStart;",
+// "uniform float iris_FogEnd;",
+// "uniform vec4 iris_FogColor;",
+// "struct iris_FogParameters {" +
+// "vec4 color;" +
+// "float density;" +
+// "float start;" +
+// "float end;" +
+// "float scale;" +
+// "};",
+// "iris_FogParameters iris_Fog = iris_FogParameters(iris_FogColor, iris_FogDensity, iris_FogStart, iris_FogEnd, 1.0 / (iris_FogEnd - iris_FogStart));"
+// );
+//
+// Util.renameFunctionCall(root, "texture2D", "texture");
+// Util.renameFunctionCall(root, "texture3D", "texture");
+// Util.renameFunctionCall(root, "texture2DLod", "textureLod");
+// Util.renameFunctionCall(root, "texture3DLod", "textureLod");
+// Util.renameFunctionCall(root, "texture2DGrad", "textureGrad");
+// Util.renameFunctionCall(root, "texture2DGradARB", "textureGrad");
+// Util.renameFunctionCall(root, "texture3DGrad", "textureGrad");
+// Util.renameFunctionCall(root, "texelFetch2D", "texelFetch");
+// Util.renameFunctionCall(root, "texelFetch3D", "texelFetch");
+// Util.renameFunctionCall(root, "textureSize2D", "textureSize");
+//
+// Util.renameAndWrapShadow(root, "shadow2D", "texture");
+// Util.renameAndWrapShadow(root, "shadow2DLod", "textureLod");
+//
+// }
+//
+// public static void CoreTransform(GLSLParser.Translation_unitContext root) {
+//
+// }
+//}
diff --git a/src/main/java/org/taumc/glsl/ShaderViewerGUI.java b/src/main/java/org/taumc/glsl/ShaderViewerGUI.java
new file mode 100644
index 0000000..3d58019
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/ShaderViewerGUI.java
@@ -0,0 +1,16 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.gui.TreeViewer;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.taumc.glsl.grammar.GLSLParser;
+
+import javax.swing.*;
+import java.util.Arrays;
+
+public class ShaderViewerGUI {
+ public static void display(GLSLParser parser, ParseTree tree) {
+ JFrame frame = new JFrame("Shader");
+ TreeViewer viewer = new TreeViewer(Arrays.asList(parser.getRuleNames()), tree);
+ viewer.open();
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/StorageCollector.java b/src/main/java/org/taumc/glsl/StorageCollector.java
new file mode 100644
index 0000000..85ab7ad
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/StorageCollector.java
@@ -0,0 +1,24 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.List;
+
+public class StorageCollector extends GLSLParserBaseListener {
+
+ private final List storage;
+
+ public StorageCollector(List storage) {
+ this.storage = storage;
+ }
+
+ @Override
+ public void enterStorage_qualifier(GLSLParser.Storage_qualifierContext ctx) {
+ if (ctx.getChild(0) instanceof TerminalNode node) {
+ this.storage.add(node);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/taumc/glsl/StructArrayRewriter.java b/src/main/java/org/taumc/glsl/StructArrayRewriter.java
new file mode 100644
index 0000000..1541862
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/StructArrayRewriter.java
@@ -0,0 +1,24 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+public class StructArrayRewriter extends GLSLParserBaseListener {
+
+ public StructArrayRewriter() {}
+
+ @Override
+ public void enterStruct_declaration(GLSLParser.Struct_declarationContext ctx) {
+ if (ctx.type_specifier().array_specifier() != null) {
+ var array_specifier = ctx.type_specifier().array_specifier();
+ if (array_specifier.dimension().get(0).constant_expression() != null) {
+ return;
+ }
+ ctx.type_specifier().children.remove(array_specifier);
+ for (var entry : ctx.struct_declarator_list().struct_declarator()) {
+ array_specifier.setParent(entry);
+ entry.children.add(array_specifier);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/TypeFinder.java b/src/main/java/org/taumc/glsl/TypeFinder.java
new file mode 100644
index 0000000..fa4bd8b
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/TypeFinder.java
@@ -0,0 +1,35 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class TypeFinder extends GLSLParserBaseListener {
+
+ private final String name;
+ private final AtomicInteger type;
+
+ public TypeFinder(String name, AtomicInteger type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override
+ public void enterSingle_declaration(GLSLParser.Single_declarationContext ctx) {
+ if (ctx.typeless_declaration() == null) {
+ return;
+ }
+ if (ctx.typeless_declaration().IDENTIFIER().getSymbol() instanceof CommonToken cToken) {
+ if (cToken.getText().equals(name)) {
+ if (ctx.fully_specified_type().type_specifier().type_specifier_nonarray().getChild(0) instanceof TerminalNode node) {
+ if (node.getSymbol() instanceof CommonToken t) {
+ type.set(t.getType());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/taumc/glsl/Util.java b/src/main/java/org/taumc/glsl/Util.java
new file mode 100644
index 0000000..992abe2
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/Util.java
@@ -0,0 +1,199 @@
+package org.taumc.glsl;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonToken;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.taumc.glsl.grammar.GLSLLexer;
+import org.taumc.glsl.grammar.GLSLParser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Util {
+
+ /**
+ * Injects at the end of the "external_declaration_list", before functions
+ * @param root the root parser
+ * @param code the to inject code
+ */
+ public static void injectVariable(GLSLParser.Translation_unitContext root, String... code) {
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(String.join("\n", code)));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ var insert = parser.external_declaration();
+
+ AtomicReference ref = new AtomicReference<>();
+ ParseTreeWalker.DEFAULT.walk(new VariableInjector(ref), root);
+
+ var left = ref.get();
+ if (left != null) {
+ var parent = left.getParent();
+ int i = parent.children.indexOf(left);
+ parent.children.add(i, insert);
+ insert.setParent(parent);
+ }
+ }
+
+ public static void injectFunction(GLSLParser.Translation_unitContext root, String... code) {
+ GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(String.join("\n", code)));
+ GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
+ var insert = parser.external_declaration();
+
+ AtomicReference ref = new AtomicReference<>();
+ ParseTreeWalker.DEFAULT.walk(new FunctionInjector(ref), root);
+
+ var left = ref.get();
+ if (left != null) {
+ var parent = left.getParent();
+ int i = parent.children.indexOf(left);
+ parent.children.add(i, insert);
+ insert.setParent(parent);
+ }
+ }
+
+ public static void rename(GLSLParser.Translation_unitContext root, String oldName, String newName) {
+ ParseTreeWalker.DEFAULT.walk(new Renamer(Map.of(oldName, newName)), root);
+ }
+
+ public static void replaceExpression(GLSLParser.Translation_unitContext root, String oldCode, String newCode) {
+ ParseTreeWalker.DEFAULT.walk(new ReplaceExpression(oldCode, newCode), root);
+ }
+
+ public static void prependMain(GLSLParser.Translation_unitContext root, String code) {
+ ParseTreeWalker.DEFAULT.walk(new PrependFunction("main", code), root);
+ }
+
+ public static void removeVariable(GLSLParser.Translation_unitContext root, String code) {
+ AtomicReference top = new AtomicReference<>();
+ ParseTreeWalker.DEFAULT.walk(new RemoveVariable(code, top), root);
+ if (top.get() != null) {
+ top.get().getParent().children.remove(top.get());
+ }
+ }
+
+ public static int findType(GLSLParser.Translation_unitContext root, String code) {
+ AtomicInteger type = new AtomicInteger();
+ ParseTreeWalker.DEFAULT.walk(new TypeFinder(code, type), root);
+ return type.get();
+ }
+
+ public static void appendMain(GLSLParser.Translation_unitContext root, String code) {
+ ParseTreeWalker.DEFAULT.walk(new AppendFunction("main", code), root);
+ }
+
+ public static boolean containsCall(GLSLParser.Translation_unitContext root, String name) {
+ AtomicBoolean atomicBoolean = new AtomicBoolean(false);
+ FastTreeWalker.walk(new IdentifierCollector(id -> {
+ if(id.equals(name)) {
+ atomicBoolean.set(true);
+ return false;
+ } else {
+ return true;
+ }
+ }), root);
+ return atomicBoolean.get();
+ }
+
+ public static boolean hasVariable(GLSLParser.Translation_unitContext root, String name) {
+ AtomicBoolean atomicBoolean = new AtomicBoolean(false);
+ ParseTreeWalker.DEFAULT.walk(new HasVariable(name, atomicBoolean), root);
+ return atomicBoolean.get();
+ }
+
+ public static void renameArray(GLSLParser.Translation_unitContext root, String oldName, String newName, Set found) {
+ ParseTreeWalker.DEFAULT.walk(new ArrayExpressionRewriteListener(Map.of(oldName, newName), found), root);
+ }
+
+ public static void renameFunctionCall(GLSLParser.Translation_unitContext root, String oldName, String newName) {
+ ParseTreeWalker.DEFAULT.walk(new ExpressionRenamer(Map.of(oldName, newName)), root);
+ }
+
+ public static void renameAndWrapShadow(GLSLParser.Translation_unitContext root, String oldName, String newName) {
+ ParseTreeWalker.DEFAULT.walk( new FunctionCallWrapper(oldName, "vec4"), root);
+ renameFunctionCall(root, oldName, newName);
+ }
+
+ public static List collectFunctions(GLSLParser.Translation_unitContext root) {
+ List result = new ArrayList<>();
+ ParseTreeWalker.DEFAULT.walk(new FunctionCollector(result), root);
+ return result;
+ }
+
+ public static void removeFunction(GLSLParser.Translation_unitContext root, String name) {
+ AtomicReference context = new AtomicReference<>();
+ FastTreeWalker.walk(new FunctionRemover(name, context), root);
+ if (context.get() != null) {
+ context.get().getParent().children.remove(context.get());
+ }
+ }
+
+ public static void removeUnusedFunctions(GLSLParser.Translation_unitContext root) {
+ List result = Util.collectFunctions(root);
+ Set usedIdentifiers = new HashSet<>();
+ FastTreeWalker.walk(new IdentifierCollector(id -> {
+ usedIdentifiers.add(id);
+ return true;
+ }), root);
+ List functionsToRemove = result.stream().filter(name -> !usedIdentifiers.contains(name) && !name.equals("main")).toList();
+ // TODO - remove all the functions in one walk of the tree
+ for (String name : functionsToRemove) {
+ removeFunction(root, name);
+ }
+ }
+
+ public static Map> findConstParameter(GLSLParser.Translation_unitContext root) {
+ Map> functions = new HashMap<>();
+ ParseTreeWalker.DEFAULT.walk(new ConstParameterFinder(functions), root);
+ return functions;
+ }
+
+ public static void removeConstAssignment(GLSLParser.Translation_unitContext root, Map> functions) {
+ for (Map.Entry> entry : functions.entrySet()) {
+ ParseTreeWalker.DEFAULT.walk(new ConstAssignmentRemover(entry.getKey(), entry.getValue()), root);
+ }
+ }
+
+ public static void removeConstAssignment(GLSLParser.Translation_unitContext root) {
+ Map> functions = Util.findConstParameter(root);
+ Util.removeConstAssignment(root, functions);
+ }
+
+ public static void initialize(GLSLParser.Translation_unitContext root, GLSLParser.Single_declarationContext declarationContext, String name) {
+ if (declarationContext.fully_specified_type().type_specifier().type_specifier_nonarray().getChild(0) instanceof TerminalNode node && node.getSymbol() instanceof CommonToken token) {
+ String insert = token.getText() + " " + name + " = " + BuiltinFunction.getByType(token.getType()).getInitializer() + ";" ;
+ Util.prependMain(root, insert);
+ }
+ }
+
+ public static void makeOutDeclaration(GLSLParser.Translation_unitContext root, GLSLParser.Single_declarationContext inDeclarationContext) {
+ String insert = inDeclarationContext.getText() + ";";
+ insert = insert.replaceFirst("in", "out");
+ Util.prependMain(root, insert);
+ }
+
+ public static Map findQualifiers(GLSLParser.Translation_unitContext root, int type) {
+ Map result = new HashMap<>();
+ ParseTreeWalker.DEFAULT.walk(new QualifierFinder(type, result), root);
+ return result;
+ }
+
+ public static boolean hasAssigment(GLSLParser.Translation_unitContext root, String name) {
+ AtomicBoolean atomicBoolean = new AtomicBoolean(false);
+ ParseTreeWalker.DEFAULT.walk(new AssigmentChecker(name, atomicBoolean), root);
+ return atomicBoolean.get();
+ }
+
+ public static void rewriteStructArrays(GLSLParser.Translation_unitContext root) {
+ ParseTreeWalker.DEFAULT.walk(new StructArrayRewriter(), root);
+ }
+
+}
diff --git a/src/main/java/org/taumc/glsl/VariableInjector.java b/src/main/java/org/taumc/glsl/VariableInjector.java
new file mode 100644
index 0000000..c321a55
--- /dev/null
+++ b/src/main/java/org/taumc/glsl/VariableInjector.java
@@ -0,0 +1,40 @@
+package org.taumc.glsl;
+
+import org.taumc.glsl.grammar.GLSLParser;
+import org.taumc.glsl.grammar.GLSLParserBaseListener;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+public class VariableInjector extends GLSLParserBaseListener {
+ private final AtomicReference atomic;
+ private boolean function = false;
+
+ public VariableInjector(AtomicReference atomic) {
+ this.atomic = atomic;
+ }
+
+ @Override
+ public void enterFunction_definition(GLSLParser.Function_definitionContext ctx) {
+ if (ctx.getParent() instanceof GLSLParser.External_declarationContext list) {
+ if (atomic.get() == null) {
+ function = true;
+ atomic.set(list);
+ }
+ }
+ }
+
+ @Override
+ public void enterStorage_qualifier(GLSLParser.Storage_qualifierContext ctx) {
+ var parent = ctx.getParent();
+ while (!(parent instanceof GLSLParser.External_declarationContext list)) {
+ if (parent.getParent() == null) {
+ return;
+ }
+ parent = parent.getParent();
+ }
+ if (atomic.get() == null || function) {
+ function = false;
+ atomic.set(list);
+ }
+ }
+}
diff --git a/test.glsl b/test.glsl
new file mode 100644
index 0000000..3bd5393
--- /dev/null
+++ b/test.glsl
@@ -0,0 +1,128 @@
+// This is just a test input file for the shader parsing, the license is LGPL3 from Sodium/Embeddium.
+
+uniform float framemod8;
+// The position of the vertex around the model origin
+vec3 _vert_position;
+
+// The block texture coordinate of the vertex
+vec2 _vert_tex_diffuse_coord;
+
+// The light texture coordinate of the vertex
+ivec2 _vert_tex_light_coord;
+
+// The color of the vertex
+vec4 _vert_color;
+
+// The index of the draw command which this vertex belongs to
+uint _draw_id;
+
+// The material bits for the primitive
+uint _material_params;
+
+#ifdef USE_VERTEX_COMPRESSION
+in uvec4 a_PosId;
+in vec4 a_Color;
+in vec2 a_TexCoord;
+in ivec2 a_LightCoord;
+
+#if !defined(VERT_POS_SCALE)
+#error "VERT_POS_SCALE not defined"
+#elif !defined(VERT_POS_OFFSET)
+#error "VERT_POS_OFFSET not defined"
+#elif !defined(VERT_TEX_SCALE)
+#error "VERT_TEX_SCALE not defined"
+#endif
+
+void _vert_init() {
+ _vert_position = (vec3(a_PosId.xyz) * VERT_POS_SCALE + VERT_POS_OFFSET);
+ _vert_tex_diffuse_coord = (a_TexCoord * VERT_TEX_SCALE);
+ _vert_tex_light_coord = a_LightCoord;
+ _vert_color = a_Color;
+
+ _draw_id = (a_PosId.w >> 8u) & 0xFFu;
+ _material_params = (a_PosId.w >> 0u) & 0xFFu;
+}
+
+#else
+
+in vec3 a_PosId, a_PosId2;
+in vec4 a_Color;
+in vec2 a_TexCoord;
+in uint a_LightCoord;
+
+out VertexData {
+ vec2 coord;
+ vec4 color;
+} fsh;
+
+void _vert_init(const vec2 vector) {
+ const vec2 storagetest = vector;
+ const vec2 test2 = vector;
+ _vert_position = a_PosId;
+ _vert_tex_diffuse_coord = a_TexCoord;
+ _vert_color = a_Color;
+
+ uint packed_draw_params = (a_LightCoord & 0xFFFFu);
+ // Vertex Material
+ _material_params = (packed_draw_params) & 0xFFu;
+
+ // Vertex Mesh ID
+ _draw_id = (packed_draw_params >> 8) & 0xFFu;
+ test[5] = function(uvec2(ivec2(0),8), uvec2(0)).x;
+
+ // Vertex Light
+ _vert_tex_light_coord = ivec2((uvec2((a_LightCoord >> 16) & 0xFFFFu) >> uvec2(0, 8)) & uvec2(0xFFu));
+}
+
+vec4 texture2D_POMSwitch(sampler2D textures2D,
+ vec2 lightmapCoord,
+ vec4 dcdxdcdy,
+ bool ifPOM
+) {
+
+}
+
+
+void main() {
+ if (vartest == test) {
+ test = 4;
+ }
+ const float test = _vert_init(vec2(1,1));
+
+ if (vartest > test) {
+ test = 4;
+ }
+
+ if (vartest > test2[5]) {
+ test = 4;
+ }
+
+ if (vartest == uint(5)) {
+ test = 4;
+ }
+
+ if (test == vartest.xy) {
+
+ }
+
+ if (test == vec4(_vert_tex_diffuse_coord, 0.0, 1.0).xy) {
+
+ }
+ shadowCol = texture2D ( shadowcolor0 , shadowPos . st );
+ _vert_init();
+}
+
+void removeMe() {
+
+}
+
+uniform sampler2D twodimsampler;
+
+void myTestFunctionWithTex2D() {
+ vec2 vec = vec2(0.05, 0.05);
+ float myothertest = someRandomFunc(twodimsampler, vec).r;
+ float mytest = texture2D(twodimsampler, vec).r;
+ float value = pow2(texture2D(twodimsampler, vec).r * pow1_5(texture2D(twodimsampler, vec * 0.5).r));
+}
+
+#endif