
Program <- Version? (LineMarker / GoogleIncludeExtensionEnable / UniformBlock / Declaration / ConstArray / Stage / Indent / IgnoredKeyword / Line)*

~LineMarker <- '#line' (!EndOfLine .)* EndOfLine
~GoogleIncludeExtensionEnable <- '#extension GL_GOOGLE_include_directive' (!EndOfLine .)* EndOfLine
Line <- <(!EndOfLine !EndOfFile .)*> (EndOfLine / EndOfFile)
~IgnoredKeyword <- !'const int' ('inline' / 'static ' / 'const ')
Version <- '#'_'version' Space+ <Int> <(!EndOfLine .)*> EndOfLine
Stage <- '#'_'pragma' Space+ 'stage' Space? <(!EndOfLine .)*> EndOfLine
#.*Include <- '#'_'include' _ '"' <(!'"' .)*> '"' _ EndOfLine

Declaration <- Layout? _ Qualifier Space _ Type Space _ Name _ ArraySize? _ EndOfStatement
ConstArray <- Type Space _ Name _ ArraySize? _ '=' _ Array  _ EndOfStatement
UniformBlock <- Layout? _ 'uniform' _ StructName? _ '{' Member* '}' _ Name? _ EndOfStatement
Member <- (_ Type Space _ Name _ ArraySize? _ EndOfStatement? _ Comment?)
~Comment <- ('//' Line)

Value <- (Float / Int / (!EndOfStatement .)*)
Array <- ('{' ( _ ArrayItem+ _ ',')* (_ ArrayItem+ _ )? '}')
ArrayItem <- <(!'}'!',' (groupedItem/.))+>
groupedItem <- '(' (!')' (groupedItem/.))+ ')'

Qualifier <- 'in' / 'out' / 'uniform'
Type <- <'uint' / 'int' / 'ivec2' / 'ivec3' / 'ivec4' /
         'float' / 'vec2' / 'vec3' / 'vec4' /
         'bool' / 'bvec2' / 'bvec3' / 'bvec4' /
         'mat2x2' / 'mat2' /
         'mat3x2' / 'mat3x3' / 'mat3' /
         'mat4x2' / 'mat4x3' / 'mat4x4' / 'mat4' /
         'void' / 'sampler2D' / Name>
StructName <- <Name>
ArraySize <- '[' _ <Int> _ ']'
Name <- ([a-z]/[A-Z]/'_'/[0-9])+
Layout <- 'layout' _ '(' ( _ (Location / Binding / Set / PushConstant / Std) _ ','?)+ ')'
Location <- 'location' _ '=' _ <Int>
Binding <- 'binding' _ '=' _ <Int>
Set <- 'set' _ '=' _ <Int>
PushConstant <- 'push_constant'
Std <- 'std' <Int>

#.*Block <- '{' (Directive/ Statement / Block _)* '}'

Float <- $< '-'? [0-9]+ '.' ([0-9]+ ('e-'[0-9]+)? )? 'f'? >
Int <- < '-'? [0-9]+ >
~EndOfStatement <- ';'
~EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
End <- EndOfLine / EndOfFile
~_  <-  [ \t\r\n]*
Indent  <-  [ \t]
~Space  <-  [ \t]
