Skip to content

Instantly share code, notes, and snippets.

@xoppa
Created October 7, 2015 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xoppa/95dbc55a0b4c27818b0e to your computer and use it in GitHub Desktop.
Save xoppa/95dbc55a0b4c27818b0e to your computer and use it in GitHub Desktop.
/**
* @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