TOKEN_COMMENT           ::= ( "/*" { 'not [*]' | "*" 'not [/]' } "*/" )
                            | ( "//" { 'not new-line' }
                            )

TOKEN_GLOBAL_IDENTIFIER ::= "&" identifier

TOKEN_LOCAL_IDENTIFIER  ::= "%" identifier

TOKEN_LABEL_IDENTIFIER  ::= "@" identifier

identifier              ::= '[a-zA-Z_]' { '[a-zA-Z0-9_]' }

TOKEN_CREGISTER         ::= "$c" registerNumber

TOKEN_SREGISTER         ::= "$s" registerNumber

TOKEN_DREGISTER         ::= "$d" registerNumber

TOKEN_QREGISTER         ::= "$q" registerNumber

registerNumber          ::= "0"
                          | '[1-9]' { '[0-9]' }
               
TOKEN_PROPERTY          ::= "normalized"
                          | "unnormalized"
                          | "nearest"
                          | "linear"
                          | "wrap"
                          | "clamp"
                          | "mirror"
                          | "mirroronce"
                          | "border"
                          | "snorm_int8"
                          | "snorm_int16"
                          | "unorm_int8"
                          | "unorm_int16"
                          | "unorm_int24"
                          | "unorm_short_565"
                          | "unorm_short_555"
                          | "unorm_short_101010"
                          | "signed_int8"
                          | "signed_int16"
                          | "signed_int32"
                          | "unsigned_int8"
                          | "unsigned_int16"
                          | "unsigned_int32"
                          | "half_float"
                          | "float"
                          | "r"
                          | "rx"
                          | "a"
                          | "rg"
                          | "rgx"
                          | "ra"
                          | "rgb"
                          | "srgb"
                          | "srgbx"
                          | "rgbx"
                          | "rgba"
                          | "bgra"
                          | "argb"
                          | "srgba"
                          | "sbgra"
                          | "intensity"
                          | "luminance"
              
TOKEN_INTEGER_CONSTANT  ::= decimalIntegerConstant
                          | hexIntegerConstant
                          | octalIntegerConstant

decimalIntegerConstant  ::= "0" | ( '[1-9]' { ['[0-9]'] } )

hexIntegerConstant      ::= "0" ( "x" | "X" ) '[0-9a-fA-F]' { '[0-9a-fA-F]' }

octalIntegerConstant    ::= "0" '[0-7]' { '[0-7]' }

TOKEN_HALF_CONSTANT     ::= decimalFloatConstant ( "h" | "H" )
                          | hexFloatConstant ( "h" | "H" )
                          | ieeeHalfConstant

TOKEN_SINGLE_CONSTANT   ::= decimalFloatConstant ( "f" | "F" )
                          | hexFloatConstant ( "f" | "F" )
                          | ieeeSingleConstant

TOKEN_DOUBLE_CONSTANT   ::= decimalFloatConstant [ "d" | "D" ]
                          | hexFloatConstant [ "d" | "D" ]
                          | ieeeDoubleConstant

decimal_float_constant  ::= ( ( '[0-9]' { '[0-9]' } "."
                              |  { '[0-9]' } "." '[0-9]' { '[0-9]' }
                              )
                              [ ( "e" | "E" ) [ "+" | "-" ] '[0-9]' { '[0-9]' } ] 
                            )
                            | '[0-9]' { '[0-9]' } ( "e" | "E" ) [ "+" | "-" ] '[0-9]' { '[0-9]' }

hexFloatConstant        ::= "0" ( "x" | "X" )
                            ( '[0-9a-fA-F]' { '[0-9a-fA-F]' } [ "." ]
                            | { '[0-9a-fA-F]' } "." '[0-9a-fA-F]' { '[0-9a-fA-F]' }
                            )
                            ( "p" | "P" ) [ "+" | "-" ] '[0-9]' { '[0-9]' }
                    
ieeeHalfConstant        ::= "0" ( "h" | "H" ) '[0-9a-fA-F]{4}'

ieeeSingleConstant      ::= "0" ( "f" | "F" ) '[0-9a-fA-F]{8}'

ieeeDoubleConstant      ::= "0" ( "d" | "D" ) '[0-9a-fA-F]{16}'

TOKEN_WAVESIZE          ::= "WAVESIZE"

TOKEN_STRING            ::= '"'
                          { 'not ([\"] or new-line)'
                          | "\" 
                            ( '"'
                            | "[\'?abfnrtv]"
                            | '[0-7]{1,3}'
                            | "x" '[0-9a-fA-F]' { '[0-9a-fA-F]' }
                            )
                          }
                          '"'
