Created
October 7, 2015 17:22
-
-
Save xoppa/95dbc55a0b4c27818b0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Xoppa | |
*/ | |
options | |
{ | |
JDK_VERSION = "1.6"; | |
static = false; | |
} | |
PARSER_BEGIN(GSLParser) | |
package com.xoppa.gsl.parser; | |
import com.xoppa.gsl.program.*; | |
import com.xoppa.gsl.program.Constant.*; | |
import com.xoppa.gsl.program.Qualifier.*; | |
public class GSLParser | |
{ | |
// TODO: Add custom code | |
} | |
PARSER_END(GSLParser) | |
SKIP : { " " | "\t" | "\r\n" | "\n" } | |
TOKEN_MGR_DECLS : { | |
int nativeNestingDepth; | |
} | |
/** Documentation: | |
* Everything in between "/**" and "*\/". | |
* Optionally allows for for various keys (just like javadoc), starting with \@. | |
*/ | |
TOKEN : { < DOC_START : ("/**") ([" ","\t","\r","\n","*"])* > : IN_DOC } | |
<IN_DOC> TOKEN : { < DOC_END : ([" ","\t","\r","\n","*"])* ("*/") > : DEFAULT } | |
<IN_DOC> TOKEN : { < DOC_NEWLINE: ([" ","\t"])* ("\r\n" | "\n") (([" ", "\t"])* ("*")?)* > } | |
<IN_DOC> TOKEN [IGNORE_CASE] : | |
{ | |
< DOC_RETURN : "@return" > | |
| < DOC_PARAM : "@param" > : IN_DOC_IDENTIFIER | |
| < DOC_AUTHOR : "@author" > | |
| < DOC_VERSION : "@version" > | |
| < DOC_DEPRECATED : "@deprecated" > | |
| < DOC_SEE : "@see" > | |
} | |
<IN_DOC> TOKEN : { < DOC_OTHER : ~[] > } | |
<IN_DOC_IDENTIFIER> SKIP : { " " | "\t" | "\r\n" | "\n" } | |
<IN_DOC_IDENTIFIER> TOKEN : { < DOC_IDENTIFIER : (~[" ","\t","\r","\n"])+ > : IN_DOC } | |
/** Comments and preprocessor directives: | |
* Everything starting with "//" up until the end of the line or, | |
* Everything in between "/*" and "*\/", but not in-line documentation or, | |
* Everything starting with "#" up until the end of the line. | |
*/ | |
MORE : | |
{ | |
"//" : IN_LINE_COMMENT | |
| "#" : PREPROCESSOR_OUTPUT | |
| "/*" : IN_COMMENT | |
} | |
<IN_LINE_COMMENT> SPECIAL_TOKEN: { "\n" : DEFAULT } | |
<IN_LINE_COMMENT> MORE: { < ~[] > } | |
<IN_COMMENT> SPECIAL_TOKEN: { "*/" : DEFAULT } | |
<IN_COMMENT> MORE: { < ~[] > } | |
<PREPROCESSOR_OUTPUT> SPECIAL_TOKEN: { "\n" : DEFAULT } | |
<PREPROCESSOR_OUTPUT> MORE: { "\\\n" | "\\\r\n" | < ~[] > } | |
/** Native code: | |
* Two possibilities, both starting with the keyword "native", up until the first of: | |
* - If a "{" is found, then up until "}" (may include nesting) | |
* - If a ";" if found. | |
* Note that the content is used as-is, no error checking is performed on the content. | |
*/ | |
TOKEN : { <NATIVE : "native" > { nativeNestingDepth=0; } : IN_NATIVE } | |
<IN_NATIVE> TOKEN : { <NATIVE_LBRACE : "{" > { nativeNestingDepth += 1; } } | |
<IN_NATIVE> TOKEN : { <NATIVE_RBRACE : "}" > { | |
nativeNestingDepth -= 1; | |
SwitchTo(nativeNestingDepth == 0 ? DEFAULT : IN_NATIVE); | |
} } | |
<IN_NATIVE> TOKEN : { <NATIVE_SEMICOLON : ";" > { | |
if (nativeNestingDepth == 0) | |
SwitchTo(DEFAULT); | |
} } | |
<IN_NATIVE> TOKEN : { <NATIVE_WHITE : " " | "\t" | "\r\n" | "\n" > } | |
<IN_NATIVE> TOKEN : { <NATIVE_OTHER : ~[] > } | |
/** Operators: */ | |
TOKEN : | |
{ | |
< LCURLYBRACE: "{" > | |
| < RCURLYBRACE: "}" > | |
| < LBRACKET: "[" > | |
| < RBRACKET: "]" > | |
| < LPARENTHESIS: "(" > | |
| < RPARENTHESIS: ")" > | |
| < SCOPE: "::" > | |
| < COLON: ":" > | |
| < SEMICOLON: ";" > | |
| < COMMA: "," > | |
| < QUESTIONMARK: "?" > | |
| < ELLIPSIS: "..." > | |
| < ASSIGNEQUAL: "=" > | |
| < TIMESEQUAL: "*=" > | |
| < DIVIDEEQUAL: "/=" > | |
| < MODEQUAL: "%=" > | |
| < PLUSEQUAL: "+=" > | |
| < MINUSEQUAL: "-=" > | |
| < SHIFTLEFTEQUAL: "<<=" > | |
| < SHIFTRIGHTEQUAL: ">>=" > | |
| < BITWISEANDEQUAL: "&=" > | |
| < BITWISEXOREQUAL: "^=" > | |
| < BITWISEOREQUAL: "|=" > | |
| < OR: "||" > | |
| < AND: "&&" > | |
| < BITWISEOR: "|" > | |
| < BITWISEXOR: "^" > | |
| < AMPERSAND: "&" > | |
| < EQUAL: "==" > | |
| < NOTEQUAL: "!=" > | |
| < LESSTHAN: "<" > | |
| < GREATERTHAN: ">" > | |
| < LESSTHANOREQUALTO: "<=" > | |
| < GREATERTHANOREQUALTO: ">=" > | |
| < SHIFTLEFT: "<<" > | |
| < SHIFTRIGHT: ">>" > | |
| < PLUS: "+" > | |
| < MINUS: "-" > | |
| < STAR: "*" > | |
| < DIVIDE: "/" > | |
| < MOD: "%" > | |
| < PLUSPLUS: "++" > | |
| < MINUSMINUS: "--" > | |
| < TILDE: "~" > | |
| < NOT: "!" > | |
| < DOT: "." > | |
| < POINTERTO: "->" > | |
| < DOTSTAR: ".*" > | |
| < ARROWSTAR: "->*" > | |
} | |
/** GLSL Keywords: | |
* Mostly copied from the GLSL specification, not all supported though | |
*/ | |
TOKEN: | |
{ | |
< ATTRIBUTE: "attribute" > | |
| < CONST: "const" > | |
| < UNIFORM: "uniform" > | |
| < VARYING: "varying" > | |
| < BUFFER: "buffer" > | |
| < SHARED: "shared" > | |
| < COHERENT: "coherent" > | |
| < VOLATILE: "volatile" > | |
| < RESTRICT: "restrict" > | |
| < READONLY: "readonly" > | |
| < WRITEONLY: "writeonly" > | |
| < LOWP: "lowp" > | |
| < MEDIUMP: "mediump" > | |
| < HIGHP: "highp" > | |
| < PRECISION: "precision" > | |
| < ATOMIC_UINT: "atomic_uint" > | |
| < LAYOUT: "layout" > | |
| < FLAT: "flat" > | |
| < SMOOTH: "smooth" > | |
| < NOPERSPECTIVE: "noperspective" > | |
| < CENTROID: "centroid" > | |
| < PATCH: "patch" > | |
| < SAMPLE: "sample" > | |
| < BREAK: "break" > | |
| < CONTINUE: "continue" > | |
| < DO: "do" > | |
| < FOR: "for" > | |
| < WHILE: "while" > | |
| < SWITCH: "switch" > | |
| < CASE: "case" > | |
| < _DEFAULT: "default" > | |
| < IF: "if" > | |
| < ELSE: "else" > | |
| < SUBROUTINE: "subroutine" > | |
| < IN: "in" > | |
| < OUT: "out" > | |
| < INOUT: "inout" > | |
| < FLOAT: "float" > | |
| < DOUBLE: "double" > | |
| < INT: "int" > | |
| < UINT: "uint" > | |
| < VOID: "void" > | |
| < BOOL: "bool" > | |
| < TRUE: "true" > | |
| < FALSE: "false" > | |
| < INVARIANT: "invariant" > | |
| < DISCARD: "discard" > | |
| < RETURN: "return" > | |
| < STRUCT: "struct" > | |
//mat2 mat3 mat4 dmat2 dmat3 dmat4 | |
//mat2x2 mat2x3 mat2x4 dmat2x2 dmat2x3 dmat2x4 | |
//mat3x2 mat3x3 mat3x4 dmat3x2 dmat3x3 dmat3x4 | |
//mat4x2 mat4x3 mat4x4 dmat4x2 dmat4x3 dmat4x4 | |
//vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 dvec2 dvec3 dvec4 | |
//uvec2 uvec3 uvec4 | |
//sampler1D sampler2D sampler3D samplerCube | |
//sampler1DShadow sampler2DShadow samplerCubeShadow | |
//sampler1DArray sampler2DArray | |
//sampler1DArrayShadow sampler2DArrayShadow | |
//isampler1D isampler2D isampler3D isamplerCube | |
//isampler1DArray isampler2DArray | |
//usampler1D usampler2D usampler3D usamplerCube | |
//usampler1DArray usampler2DArray | |
//sampler2DRect sampler2DRectShadow isampler2DRect usampler2DRect | |
//samplerBuffer isamplerBuffer usamplerBuffer | |
//sampler2DMS isampler2DMS usampler2DMS | |
//sampler2DMSArray isampler2DMSArray usampler2DMSArray | |
//samplerCubeArray samplerCubeArrayShadow isamplerCubeArray usamplerCubeArray | |
//image1D iimage1D uimage1D | |
//image2D iimage2D uimage2D | |
//image3D iimage3D uimage3D | |
//image2DRect iimage2DRect uimage2DRect | |
//imageCube iimageCube uimageCube | |
//imageBuffer iimageBuffer uimageBuffer | |
//image1DArray iimage1DArray uimage1DArray | |
//image2DArray iimage2DArray uimage2DArray | |
//imageCubeArray iimageCubeArray uimageCubeArray | |
//image2DMS iimage2DMS uimage2DMS | |
//image2DMSArray iimage2DMSArray uimage2DMSArray | |
} | |
/** Custom keywords: | |
* Either reserved or not specified by GLSL specification | |
*/ | |
TOKEN: | |
{ | |
< OPERATOR: "operator" > | |
| < INLINE: "inline" > | |
| < STATIC: "static" > | |
} | |
/** Reserved keywords | |
* These keywords may currently not be used and are reserved for later usage | |
*/ | |
TOKEN: | |
{ | |
"common" | |
| "partition" | |
| "active" | |
| "asm" | |
| "class" | |
| "union" | |
| "enum" | |
| "typedef" | |
| "template" | |
| "this" | |
| "packed" | |
| "resource" | |
| "goto" | |
| "noinline" | |
| "public" | |
| "extern" | |
| "external" | |
| "interface" | |
| "long" | |
| "short" | |
| "half" | |
| "fixed" | |
| "unsigned" | |
| "superp" | |
| "input" | |
| "output" | |
| "hvec2" | |
| "hvec3" | |
| "hvec4" | |
| "fvec2" | |
| "fvec3" | |
| "fvec4" | |
| "sampler3DRect" | |
| "filter" | |
| "sizeof" | |
| "cast" | |
| "namespace" | |
| "using" | |
| "row_major" | |
| < __RESERVED: ("__") (["a"-"z","A"-"Z","0"-"9","_"])* > | |
| < GL_RESERVED: ("gl_") (["a"-"z","A"-"Z","0"-"9","_"])* > | |
} | |
/** Integer/float constants: */ | |
TOKEN [IGNORE_CASE] : | |
{ | |
< OCTALINT : "0" (["0"-"7"])* > | |
| < OCTALLONG : <OCTALINT> "l" > | |
| < UNSIGNED_OCTALINT : <OCTALINT> "u" > | |
| < UNSIGNED_OCTALLONG : <OCTALINT> ("ul" | "lu") > | |
| < DECIMALINT : ["1"-"9"] (["0"-"9"])* > | |
| < DECIMALLONG : <DECIMALINT> ["u","l"] > | |
| < UNSIGNED_DECIMALINT : <DECIMALINT> "u" > | |
| < UNSIGNED_DECIMALLONG : <DECIMALINT> ("ul" | "lu") > | |
| < HEXADECIMALINT : "0x" (["0"-"9","a"-"f"])+ > | |
| < HEXADECIMALLONG : <HEXADECIMALINT> (["u","l"])? > | |
| < UNSIGNED_HEXADECIMALINT : <HEXADECIMALINT> "u" > | |
| < UNSIGNED_HEXADECIMALLONG : <HEXADECIMALINT> ("ul" | "lu") > | |
| < FLOATONE : ((["0"-"9"])+ "." (["0"-"9"])* | (["0"-"9"])* "." (["0"-"9"])+) | |
("e" (["-","+"])? (["0"-"9"])+)? ("lf" | ["f","l"])? > | |
| < FLOATTWO : (["0"-"9"])+ "e" (["-","+"])? (["0"-"9"])+ ("lf" | ["f","l"])? > | |
} | |
/** String and character constants: */ | |
TOKEN : | |
{ | |
< CHARACTER : ("L")? "'" ( | |
(~["'","\\","\n","\r"]) | |
| ("\\" ( | |
["n","t","v","b","r","f","a","\\","?","'","\""] | |
| "0" (["0"-"7"])* | |
| ["1"-"9"] (["0"-"9"])* | |
| ("0x" | "0X") (["0"-"9","a"-"f","A"-"F"])+ | |
)) | |
) "'" > | |
| < STRING : ("L")? "\"" ( | |
( ~["\"","\\","\n","\r"]) | |
| ("\\" ( | |
["n","t","v","b","r","f","a","\\","?","'","\"","\n"] | |
| "0" (["0"-"7"])* | |
| ["1"-"9"] (["0"-"9"])* | |
| ("0x" | "0X") (["0"-"9","a"-"f","A"-"F"])+ | |
)) | |
)* "\"" > | |
} | |
/** Identifiers: */ | |
TOKEN : | |
{ | |
< IDENTIFIER : ["a"-"z","A"-"Z", "_"] (["a"-"z","A"-"Z","0"-"9","_"])* > | |
} | |
/** Scoped identifiers: */ | |
TOKEN : | |
{ | |
< SCOPE_IDENTIFIER : < IDENTIFIER > < SCOPE > > | |
} | |
/** Parse documentation to a Documentation object */ | |
Documentation documentation() : | |
{ | |
Token t; | |
String value = "", param = ""; | |
int tag = Documentation.DESCRIPTION; | |
Documentation result = new Documentation(); | |
} | |
{ | |
( | |
< DOC_START > | |
( | |
t = < DOC_OTHER > { value += t.image; } | |
| < DOC_NEWLINE > { value += "\n"; } | |
| { | |
result.add(tag, param, value); | |
value = ""; | |
param = ""; | |
} | |
( | |
< DOC_RETURN > { tag = Documentation.RETURN; } | |
| ( | |
< DOC_PARAM > | |
t = < DOC_IDENTIFIER > | |
{ param = t.image; tag = Documentation.PARAM; } | |
) | |
| < DOC_AUTHOR > { tag = Documentation.AUTHOR; } | |
| < DOC_VERSION > { tag = Documentation.VERSION; } | |
| < DOC_DEPRECATED > { tag = Documentation.DEPRECATED; } | |
| < DOC_SEE > { tag = Documentation.SEE; } | |
) | |
)* | |
< DOC_END > | |
) | |
{ | |
result.add(tag, param, value); | |
return result; | |
} | |
} | |
/** Parse operators: | |
* Divides them into a few groups: | |
* - assignment_operator: = *= /= %= += -= <<= >>= &= ^= |= | |
* - logical_operator: || && | |
* - bitwise_operator: | ^ & | |
* - equality_operator: == != | |
* - relational_operator: < > <= >= | |
* - shift_operator: << >> | |
* - additive_operator: + - | |
* - multiplicative_operator: * / % | |
* - prefix_operator: ++ -- + - ~ ! | |
* - call_operator: () | |
* - index_operator: [] | |
*/ | |
Operator assign_operator() : {} { < ASSIGNEQUAL > { return Operator.ASSIGN; } } | |
Operator multiply_assign_operator() : {} { < TIMESEQUAL > { return Operator.MULTIPLY_ASSIGN; } } | |
Operator divide_assign_operator() : {} { < DIVIDEEQUAL > { return Operator.DIVIDE_ASSIGN; } } | |
Operator modulo_assign_operator() : {} { < MODEQUAL > { return Operator.MODULO_ASSIGN; } } | |
Operator add_assign_operator() : {} { < PLUSEQUAL > { return Operator.ADD_ASSIGN; } } | |
Operator substract_assign_operator() : {} { < MINUSEQUAL > { return Operator.SUBSTRACT_ASSIGN; } } | |
Operator shiftleft_assign_operator() : {} { < SHIFTLEFTEQUAL > { return Operator.SHIFTLEFT_ASSIGN; } } | |
Operator shiftright_assign_operator() : {} { < SHIFTRIGHTEQUAL > { return Operator.SHIFTRIGHT_ASSIGN; } } | |
Operator bitwise_and_assign_operator() : {} { < BITWISEANDEQUAL > { return Operator.BITWISE_AND_ASSIGN; } } | |
Operator bitwise_xor_assign_operator() : {} { < BITWISEXOREQUAL > { return Operator.BITWISE_XOR_ASSIGN; } } | |
Operator bitwise_or_assign_operator() : {} { < BITWISEOREQUAL > { return Operator.BITWISE_OR_ASSIGN; } } | |
Operator assignment_operator() : { Operator op; } | |
{ | |
( op = assign_operator() | |
| op = multiply_assign_operator() | |
| op = divide_assign_operator() | |
| op = modulo_assign_operator() | |
| op = add_assign_operator() | |
| op = substract_assign_operator() | |
| op = shiftleft_assign_operator() | |
| op = shiftright_assign_operator() | |
| op = bitwise_and_assign_operator() | |
| op = bitwise_xor_assign_operator() | |
| op = bitwise_or_assign_operator() | |
) { return op; } | |
} | |
Operator logical_or_operator() : {} { < OR > { return Operator.OR; } } | |
Operator logical_and_operator() : {} { < AND > { return Operator.AND; } } | |
Operator logical_operator() : { Operator op; } { ( op = logical_or_operator() | op = logical_and_operator() ) { return op; } } | |
Operator bitwise_or_operator() : {} { < BITWISEOR > { return Operator.BITWISE_OR; } } | |
Operator bitwise_xor_operator() : {} { < BITWISEXOR > { return Operator.BITWISE_XOR; } } | |
Operator bitwise_and_operator() : {} { < AMPERSAND > { return Operator.BITWISE_AND; } } | |
Operator bitwise_operator() : { Operator op; } | |
{ | |
( op = bitwise_or_operator() | |
| op = bitwise_xor_operator() | |
| op = bitwise_and_operator() | |
) { return op; } | |
} | |
Operator equal_operator() : {} { < EQUAL > { return Operator.EQUAL; } } | |
Operator not_equal_operator() : {} { < NOTEQUAL > { return Operator.NOT_EQUAL; } } | |
Operator equality_operator() : { Operator op; } { ( op = equal_operator() | op = not_equal_operator() ) { return op; } } | |
Operator less_operator() : {} { < LESSTHAN > { return Operator.LESS; } } | |
Operator greater_operator() : {} { < GREATERTHAN > { return Operator.GREATER; } } | |
Operator less_equal_operator() : {} { < LESSTHANOREQUALTO > { return Operator.LESS_EQUAL; } } | |
Operator greater_equal_operator() : {} { < GREATERTHANOREQUALTO > { return Operator.GREATER_EQUAL; } } | |
Operator relational_operator() : { Operator op; } | |
{ | |
( op = less_operator() | |
| op = greater_operator() | |
| op = less_equal_operator() | |
| op = greater_equal_operator() | |
) { return op; } | |
} | |
Operator shiftleft_operator() : {} { < SHIFTLEFT > { return Operator.SHIFTLEFT; } } | |
Operator shiftright_operator() : {} { < SHIFTRIGHT > { return Operator.SHIFTRIGHT; } } | |
Operator shift_operator() : { Operator op; } { ( op = shiftleft_operator() | op = shiftright_operator() ) { return op; } } | |
Operator add_operator() : {} { < PLUS > { return Operator.ADD; } } | |
Operator substract_operator() : {} { < MINUS > { return Operator.SUBSTRACT; } } | |
Operator additive_operator() : { Operator op; } { ( op = add_operator() | op = substract_operator() ) { return op; } } | |
Operator multiply_operator() : {} { < STAR > { return Operator.MULTIPLY; } } | |
Operator divide_operator() : {} { < DIVIDE > { return Operator.DIVIDE; } } | |
Operator modulo_operator() : {} { < MOD > { return Operator.MODULO; } } | |
Operator multiplicative_operator() : { Operator op; } | |
{ | |
( op = multiply_operator() | |
| op = divide_operator() | |
| op = modulo_operator() | |
) { return op; } | |
} | |
Operator increment_operator() : {} { < PLUSPLUS > { return Operator.INCREMENT; } } | |
Operator decrement_operator() : {} { < MINUSMINUS > { return Operator.DECREMENT; } } | |
Operator positive_operator() : {} { < PLUS > { return Operator.POSITIVE; } } | |
Operator negative_operator() : {} { < MINUS > { return Operator.NEGATIVE; } } | |
Operator bitwise_not_operator() : {} { < TILDE > { return Operator.BITWISE_NOT; } } | |
Operator not_operator() : {} { < NOT > { return Operator.NOT; } } | |
Operator prefix_operator() : { Operator op = null; } | |
{ | |
( op = increment_operator() | |
| op = decrement_operator() | |
| op = positive_operator() | |
| op = negative_operator() | |
| op = bitwise_not_operator() | |
| op = not_operator() | |
) { return op; } | |
} | |
Operator call_operator() : {} { < LBRACKET > < RBRACKET > { return Operator.CALL; } } | |
Operator index_operator() : {} { < LPARENTHESIS > < RPARENTHESIS > { return Operator.INDEX; } } | |
Operator operator() : { Operator op; } | |
{ | |
( LOOKAHEAD(2) | |
op = prefix_operator() | |
| op = assignment_operator() | |
| op = logical_operator() | |
| op = bitwise_operator() | |
| op = equality_operator() | |
| op = relational_operator() | |
| op = shift_operator() | |
| op = additive_operator() | |
| op = multiplicative_operator() | |
| op = call_operator() | |
| op = index_operator() | |
) { return op; } | |
} | |
/** Semicolon and scope are handled immediatly (if needed) */ | |
void semicolon() : { Token t; } { t = <SEMICOLON> } | |
void scope() : { Token t; } { t = < SCOPE > } | |
/** Parse number (integer, short, long, etc.) constants: */ | |
NumberConstant octalInt() : { Token t; } { t = <OCTALINT> {return new NumberConstant(t.image, 8); } } | |
NumberConstant octalLong() : { Token t; } { t = <OCTALLONG> {return new NumberConstant(t.image, 8); } } | |
NumberConstant unsignedOctalInt() : { Token t; } { t = <UNSIGNED_OCTALINT> {return new NumberConstant(t.image, 8); } } | |
NumberConstant unsignedOctalLong() : { Token t; } { t = <UNSIGNED_OCTALLONG> {return new NumberConstant(t.image, 8); } } | |
NumberConstant decimalInt() : { Token t; } { t = <DECIMALINT> {return new NumberConstant(t.image, 10); } } | |
NumberConstant decimalLong() : { Token t; } { t = <DECIMALLONG> {return new NumberConstant(t.image, 10); } } | |
NumberConstant unsignedDecimalInt() : { Token t; } { t = <UNSIGNED_DECIMALINT> {return new NumberConstant(t.image, 10); } } | |
NumberConstant unsignedDecimalLong() : { Token t; } { t = <UNSIGNED_DECIMALLONG> {return new NumberConstant(t.image, 10); } } | |
NumberConstant hexadecimalInt() : { Token t; } { t = <HEXADECIMALINT> {return new NumberConstant(t.image, 16); } } | |
NumberConstant hexadecimalLong() : { Token t; } { t = <HEXADECIMALLONG> {return new NumberConstant(t.image, 16); } } | |
NumberConstant unsignedHexadecimalInt() : { Token t; } { t = <UNSIGNED_HEXADECIMALINT> {return new NumberConstant(t.image, 16); } } | |
NumberConstant unsignedHexadecimalLong() : { Token t; } { t = <UNSIGNED_HEXADECIMALLONG> {return new NumberConstant(t.image, 16); } } | |
NumberConstant number_constant() : { NumberConstant value; } | |
{ | |
( | |
value = octalInt() | |
| value = octalLong() | |
| value = decimalInt() | |
| value = decimalLong() | |
| value = hexadecimalInt() | |
| value = hexadecimalLong() | |
| value = unsignedOctalInt() | |
| value = unsignedOctalLong() | |
| value = unsignedDecimalInt() | |
| value = unsignedDecimalLong() | |
| value = unsignedHexadecimalInt() | |
| value = unsignedHexadecimalLong() | |
) | |
{ return value; } | |
} | |
/** Parse floating point (float, double) constants: */ | |
FloatConstant floatOne() : { Token t; } { t = <FLOATONE> {return new FloatConstant(t.image); } } | |
FloatConstant floatTwo() : { Token t; } { t = <FLOATTWO> {return new FloatConstant(t.image); } } | |
FloatConstant float_constant() : { FloatConstant value; } { ( value = floatOne() | value = floatTwo() ) { return value; } } | |
/** Parse character constants: */ | |
CharConstant character_constant() : { Token t; } { t = <CHARACTER> { return new CharConstant(t.image); } } | |
/** Parse string constants: */ | |
StringConstant string_constant() : { Token t; } { t = <STRING> { return new StringConstant(t.image); } } | |
/** Parse any of the above constants: */ | |
Constant constant() : | |
{ | |
Constant result; | |
} | |
{ | |
( | |
result = number_constant() | |
| result = float_constant() | |
| result = character_constant() | |
| result = string_constant() | |
) | |
{ return result; } | |
} | |
/** Parse an identifier, which is basically everything else (except for scope, see below) */ | |
String identifier() : | |
{ | |
Token t; | |
} | |
{ | |
t = < IDENTIFIER > | |
{ return t.image; } | |
} | |
/** Parse a scope identifier, an (optional) identifier followed by "::" */ | |
String scope_identifier() : | |
{ | |
Token t; | |
} | |
{ | |
t = < SCOPE_IDENTIFIER > | |
{ return t.image; } | |
} | |
/** Parse a scope selector and selects it */ | |
Scope scope_selector(Scope s) : | |
{ | |
String sub; | |
} | |
{ | |
( scope() { s = s.getRoot(); } )? | |
( | |
sub = scope_identifier() | |
{ s = s.getChild(sub); } | |
)* | |
{ return s; } | |
} | |
///** Parse a qualified identifier, which is an optional scope followed by an identifier */ | |
//String qualified_identifier(Scope s) : | |
//{ | |
// String name; | |
//} | |
//{ | |
// s = scope_selector(s) | |
// name = identifier() | |
// { return name; } | |
//} | |
/** A primary expression, one of: "string"+, (expression), id_expression, constant */ | |
Expression primary_expression(Scope scope) : | |
{ | |
Expression result; | |
} | |
{ | |
( | |
LOOKAHEAD(2) | |
( { Constant c; } | |
c = constant() | |
{ result = c; } | |
) | |
| < LPARENTHESIS > | |
result = expression(scope) | |
< RPARENTHESIS > | |
| result = variable_expression(scope) | |
) | |
{ return result; } | |
} | |
/** Parse the type precision: lowp mediump highp */ | |
TypePrecision type_precision() : | |
{ } | |
{ | |
( (<LOWP>) { return TypePrecision.LOWP; } | |
| (<MEDIUMP>) { return TypePrecision.MEDIUMP; } | |
| (<HIGHP>) { return TypePrecision.HIGHP; } ) | |
} | |
/** Parse the type qualifier: const volatile */ | |
TypeQualifier type_qualifier() : | |
{ } | |
{ | |
( (<CONST>) { return TypeQualifier.CONST; } | |
| (<VOLATILE>) { return TypeQualifier.VOLATILE; } ) | |
} | |
/** Parse the storage qualifier: in out inout attribute uniform varying buffer shared static */ | |
StorageQualifier storage_qualifier() : | |
{ } | |
{ | |
( | |
< IN > { return StorageQualifier.IN; } | |
| < OUT > { return StorageQualifier.OUT; } | |
| < INOUT > { return StorageQualifier.INOUT; } | |
| < ATTRIBUTE > { return StorageQualifier.ATTRIBUTE; } | |
| < UNIFORM > { return StorageQualifier.UNIFORM; } | |
| < VARYING > { return StorageQualifier.VARYING; } | |
| < BUFFER > { return StorageQualifier.BUFFER; } | |
| < SHARED > { return StorageQualifier.SHARED; } | |
| < STATIC > { return StorageQualifier.STATIC; } | |
) | |
} | |
/** Parse the interpolation qualifier: smooth flat noperspective */ | |
InterpolationQualifier interpolation_qualifier() : | |
{ } | |
{ | |
( (<SMOOTH>) { return InterpolationQualifier.SMOOTH; } | |
| (<FLAT>) { return InterpolationQualifier.FLAT; } | |
| (<NOPERSPECTIVE>) { return InterpolationQualifier.NOPERSPECTIVE; } ) | |
} | |
/** Parse the qualifier: */ | |
Qualifier qualifier() : | |
{ Qualifier result = new Qualifier(); } | |
{ | |
( | |
result.storage = storage_qualifier() | |
| result.qualifier = type_qualifier() | |
| result.precision = type_precision() | |
| result.interpolation = interpolation_qualifier() | |
)* | |
{return result;} | |
} | |
/** Parse basic types: void bool int uint float double */ | |
BasicType basic_type_specifier() : | |
{ | |
} | |
{ | |
< VOID > { return BasicType.VOID; } | |
| < BOOL > { return BasicType.BOOL; } | |
| < INT > { return BasicType.INT; } | |
| < UINT > { return BasicType.UINT; } | |
| < FLOAT > { return BasicType.FLOAT; } | |
| < DOUBLE > { return BasicType.DOUBLE; } | |
} | |
/** Parse a qualified type, e.g. MyClass, ::MyClass, MyClass::SubClass, ::MyClass::SubClass::SubSubClass */ | |
Type qualified_type_specifier(Scope s) : | |
{ | |
String name; | |
} | |
{ | |
s = scope_selector(s) | |
name = identifier() | |
{ return s.getType(name); } | |
} | |
/** Parse a simple type, either a basic type or a qualified type */ | |
Type simple_type_specifier(Scope scope) : | |
{ | |
Type result; | |
} | |
{ | |
( | |
(result = basic_type_specifier()) | |
| (result = qualified_type_specifier(scope)) | |
) | |
//( result = array_type_specifier(scope, result) )* | |
{return result;} | |
} | |
void init_declarator(Scope scope, Qualifier qualifier, Type type) : | |
{ | |
String name; | |
} | |
{ | |
name = identifier() | |
{ scope.declareVariable(name, qualifier, type); } | |
} | |
/** A single declaration, e.g. "const inout vec3 val", without semicolon or comma. */ | |
void single_declaration(Scope scope) : | |
{ | |
Type type; | |
Qualifier qualifier; | |
} | |
{ | |
qualifier = qualifier() | |
type = simple_type_specifier(scope) | |
init_declarator(scope, qualifier, type) | |
} | |
/** The main entry of the program */ | |
void global_scope(Scope scope) : { } | |
{ | |
(LOOKAHEAD(2) single_declaration(scope) < SEMICOLON >)* <EOF> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment