azslLexer.g4 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. Work from Tim Jones
  3. MIT license
  4. -
  5. modifications by Amazon. C 2018
  6. */
  7. lexer grammar azslLexer;
  8. channels { PREPROCESSOR, COMMENTS }
  9. AppendStructuredBuffer : 'AppendStructuredBuffer';
  10. Bool : 'bool';
  11. Bool1 : 'bool1';
  12. Bool2 : 'bool2';
  13. Bool3 : 'bool3';
  14. Bool4 : 'bool4';
  15. Bool1x1 : 'bool1x1';
  16. Bool1x2 : 'bool1x2';
  17. Bool1x3 : 'bool1x3';
  18. Bool1x4 : 'bool1x4';
  19. Bool2x1 : 'bool2x1';
  20. Bool2x2 : 'bool2x2';
  21. Bool2x3 : 'bool2x3';
  22. Bool2x4 : 'bool2x4';
  23. Bool3x1 : 'bool3x1';
  24. Bool3x2 : 'bool3x2';
  25. Bool3x3 : 'bool3x3';
  26. Bool3x4 : 'bool3x4';
  27. Bool4x1 : 'bool4x1';
  28. Bool4x2 : 'bool4x2';
  29. Bool4x3 : 'bool4x3';
  30. Bool4x4 : 'bool4x4';
  31. Buffer : 'Buffer';
  32. BuiltInTriangleIntersectionAttributes : 'BuiltInTriangleIntersectionAttributes';
  33. ByteAddressBuffer : 'ByteAddressBuffer';
  34. Break : 'break';
  35. Case : 'case';
  36. CBuffer : 'cbuffer';
  37. Centroid : 'centroid';
  38. ConstantBuffer : 'constantbuffer';
  39. ConstantBufferCamel : 'ConstantBuffer';
  40. Class : 'class';
  41. ColumnMajor : 'column_major';
  42. Const : 'const';
  43. ConsumeStructuredBuffer : 'ConsumeStructuredBuffer';
  44. Continue : 'continue';
  45. Default : 'default';
  46. Discard : 'discard';
  47. Do : 'do';
  48. Double : 'double';
  49. Double1 : 'double1';
  50. Double2 : 'double2';
  51. Double3 : 'double3';
  52. Double4 : 'double4';
  53. Double1x1 : 'double1x1';
  54. Double1x2 : 'double1x2';
  55. Double1x3 : 'double1x3';
  56. Double1x4 : 'double1x4';
  57. Double2x1 : 'double2x1';
  58. Double2x2 : 'double2x2';
  59. Double2x3 : 'double2x3';
  60. Double2x4 : 'double2x4';
  61. Double3x1 : 'double3x1';
  62. Double3x2 : 'double3x2';
  63. Double3x3 : 'double3x3';
  64. Double3x4 : 'double3x4';
  65. Double4x1 : 'double4x1';
  66. Double4x2 : 'double4x2';
  67. Double4x3 : 'double4x3';
  68. Double4x4 : 'double4x4';
  69. Else : 'else';
  70. Enum : 'enum';
  71. Export : 'export';
  72. Extern : 'extern';
  73. FeedbackTexture2D : 'FeedbackTexture2D';
  74. FeedbackTexture2DArray : 'FeedbackTexture2DArray';
  75. Float : 'float';
  76. Float1 : 'float1';
  77. Float2 : 'float2';
  78. Float3 : 'float3';
  79. Float4 : 'float4';
  80. Float1x1 : 'float1x1';
  81. Float1x2 : 'float1x2';
  82. Float1x3 : 'float1x3';
  83. Float1x4 : 'float1x4';
  84. Float2x1 : 'float2x1';
  85. Float2x2 : 'float2x2';
  86. Float2x3 : 'float2x3';
  87. Float2x4 : 'float2x4';
  88. Float3x1 : 'float3x1';
  89. Float3x2 : 'float3x2';
  90. Float3x3 : 'float3x3';
  91. Float3x4 : 'float3x4';
  92. Float4x1 : 'float4x1';
  93. Float4x2 : 'float4x2';
  94. Float4x3 : 'float4x3';
  95. Float4x4 : 'float4x4';
  96. For : 'for';
  97. Groupshared : 'groupshared';
  98. Globallycoherent : 'globallycoherent';
  99. Global: 'global';
  100. Half : 'half';
  101. Half1 : 'half1';
  102. Half2 : 'half2';
  103. Half3 : 'half3';
  104. Half4 : 'half4';
  105. Half1x1 : 'half1x1';
  106. Half1x2 : 'half1x2';
  107. Half1x3 : 'half1x3';
  108. Half1x4 : 'half1x4';
  109. Half2x1 : 'half2x1';
  110. Half2x2 : 'half2x2';
  111. Half2x3 : 'half2x3';
  112. Half2x4 : 'half2x4';
  113. Half3x1 : 'half3x1';
  114. Half3x2 : 'half3x2';
  115. Half3x3 : 'half3x3';
  116. Half3x4 : 'half3x4';
  117. Half4x1 : 'half4x1';
  118. Half4x2 : 'half4x2';
  119. Half4x3 : 'half4x3';
  120. Half4x4 : 'half4x4';
  121. If : 'if';
  122. In : 'in';
  123. Inline : 'inline';
  124. Rootconstant : 'rootconstant'; // Amazon extension
  125. Inout : 'inout' | 'in out';
  126. InputPatch : 'InputPatch';
  127. Int : 'int';
  128. Int16_t : 'int16_t';
  129. Int32_t : 'int32_t';
  130. Int64_t : 'int64_t';
  131. Int1 : 'int1';
  132. Int2 : 'int2';
  133. Int3 : 'int3';
  134. Int4 : 'int4';
  135. Int1x1 : 'int1x1';
  136. Int1x2 : 'int1x2';
  137. Int1x3 : 'int1x3';
  138. Int1x4 : 'int1x4';
  139. Int2x1 : 'int2x1';
  140. Int2x2 : 'int2x2';
  141. Int2x3 : 'int2x3';
  142. Int2x4 : 'int2x4';
  143. Int3x1 : 'int3x1';
  144. Int3x2 : 'int3x2';
  145. Int3x3 : 'int3x3';
  146. Int3x4 : 'int3x4';
  147. Int4x1 : 'int4x1';
  148. Int4x2 : 'int4x2';
  149. Int4x3 : 'int4x3';
  150. Int4x4 : 'int4x4';
  151. Interface : 'interface';
  152. Line_ : 'line';
  153. LineAdj : 'lineadj';
  154. Linear : 'linear';
  155. LineStream : 'LineStream';
  156. Long : 'long';
  157. Matrix : 'matrix';
  158. Nointerpolation : 'nointerpolation';
  159. Noperspective : 'noperspective';
  160. Option : 'option';
  161. Out : 'out';
  162. OutputPatch : 'OutputPatch';
  163. Override : 'override'; // Amazon extension
  164. Partial : 'partial'; // Amazon extension
  165. Packoffset : 'packoffset';
  166. Point : 'point';
  167. PointStream : 'PointStream';
  168. Precise : 'precise';
  169. // 'payload' is a free identifier as well, DXC has a hard literal keyword that disrupts semantic understanding in some contexts
  170. // notably as variable declarator, if you mention payload it will say «'payload' object must be an in parameter»
  171. // but actually the name the programmer choses doesn't have to be 'payload'. (Also SV_RayPayload appears to be a fake semantic)
  172. RasterizerOrderedBuffer : 'RasterizerOrderedBuffer';
  173. RasterizerOrderedByteAddressBuffer : 'RasterizerOrderedByteAddressBuffer';
  174. RasterizerOrderedStructuredBuffer : 'RasterizerOrderedStructuredBuffer';
  175. RasterizerOrderedTexture1D : 'RasterizerOrderedTexture1D';
  176. RasterizerOrderedTexture1DArray : 'RasterizerOrderedTexture1DArray';
  177. RasterizerOrderedTexture2D : 'RasterizerOrderedTexture2D';
  178. RasterizerOrderedTexture2DArray : 'RasterizerOrderedTexture2DArray';
  179. RasterizerOrderedTexture3D : 'RasterizerOrderedTexture3D';
  180. RayDesc : 'RayDesc';
  181. RaytracingAccelerationStructure : 'RaytracingAccelerationStructure';
  182. Register : 'register';
  183. Return : 'return';
  184. RowMajor : 'row_major';
  185. RWBuffer : 'RWBuffer';
  186. RWByteAddressBuffer : 'RWByteAddressBuffer';
  187. RWStructuredBuffer : 'RWStructuredBuffer';
  188. RWTexture1D : 'RWTexture1D';
  189. RWTexture1DArray : 'RWTexture1DArray';
  190. RWTexture2D : 'RWTexture2D';
  191. RWTexture2DArray : 'RWTexture2DArray';
  192. RWTexture3D : 'RWTexture3D';
  193. Sample : 'sample';
  194. Sampler : 'sampler';
  195. SamplerCapitalS : 'Sampler';
  196. SamplerComparisonState : 'SamplerComparisonState';
  197. SamplerStateCamel : 'SamplerState';
  198. SamplerState : 'sampler_state';
  199. Shared : 'shared';
  200. SNorm : 'snorm';
  201. Static : 'static';
  202. Struct : 'struct';
  203. StructuredBuffer : 'StructuredBuffer';
  204. SubpassInput : 'SubpassInput';
  205. SubpassInputMS : 'SubpassInputMS';
  206. SubpassInputDS : 'SubpassInputDS';
  207. SubpassInputDSMS : 'SubpassInputDSMS';
  208. Switch : 'switch';
  209. TBuffer : 'tbuffer';
  210. Texture1D : 'Texture1D';
  211. Texture1DArray : 'Texture1DArray';
  212. Texture2D : 'Texture2D';
  213. Texture2DArray : 'Texture2DArray';
  214. Texture2DMS : 'Texture2DMS';
  215. Texture2DMSArray : 'Texture2DMSArray';
  216. Texture3D : 'Texture3D';
  217. TextureCube : 'TextureCube';
  218. TextureCubeArray : 'TextureCubeArray';
  219. Triangle : 'triangle';
  220. TriangleAdj : 'triangleadj';
  221. TriangleStream : 'TriangleStream';
  222. Uniform : 'uniform';
  223. // For the --listpredefined option to work, we absolutely need all types to exist in (simple) rules
  224. // that can return strings from Vocabulary::getLiteralName()
  225. // so that rule: Uint : 'uint' | 'dword' # can't be used because it's non-trivialness makes it a non-citizen.
  226. // I tried to recompose the rule with fragments, but fragment also are not listed in the vocabulary. (_literalNames)
  227. Uint : 'uint';
  228. Uint1 : 'uint1';
  229. Uint2 : 'uint2';
  230. Uint3 : 'uint3';
  231. Uint4 : 'uint4';
  232. Uint1x1 : 'uint1x1';
  233. Uint1x2 : 'uint1x2';
  234. Uint1x3 : 'uint1x3';
  235. Uint1x4 : 'uint1x4';
  236. Uint2x1 : 'uint2x1';
  237. Uint2x2 : 'uint2x2';
  238. Uint2x3 : 'uint2x3';
  239. Uint2x4 : 'uint2x4';
  240. Uint3x1 : 'uint3x1';
  241. Uint3x2 : 'uint3x2';
  242. Uint3x3 : 'uint3x3';
  243. Uint3x4 : 'uint3x4';
  244. Uint4x1 : 'uint4x1';
  245. Uint4x2 : 'uint4x2';
  246. Uint4x3 : 'uint4x3';
  247. Uint4x4 : 'uint4x4';
  248. Uint16_t : 'uint16_t';
  249. Uint32_t : 'uint32_t';
  250. Uint64_t : 'uint64_t';
  251. UNorm : 'unorm';
  252. Unsigned : 'unsigned';
  253. Dword : 'dword';
  254. // Amazon addition: DXC didn't advertise it, but the vector/matrix forms of dword are now accepted
  255. Dword1 : 'dword1';
  256. Dword2 : 'dword2';
  257. Dword3 : 'dword3';
  258. Dword4 : 'dword4';
  259. Dword1x1 : 'dword1x1';
  260. Dword1x2 : 'dword1x2';
  261. Dword1x3 : 'dword1x3';
  262. Dword1x4 : 'dword1x4';
  263. Dword2x1 : 'dword2x1';
  264. Dword2x2 : 'dword2x2';
  265. Dword2x3 : 'dword2x3';
  266. Dword2x4 : 'dword2x4';
  267. Dword3x1 : 'dword3x1';
  268. Dword3x2 : 'dword3x2';
  269. Dword3x3 : 'dword3x3';
  270. Dword3x4 : 'dword3x4';
  271. Dword4x1 : 'dword4x1';
  272. Dword4x2 : 'dword4x2';
  273. Dword4x3 : 'dword4x3';
  274. Dword4x4 : 'dword4x4';
  275. Vector : 'vector';
  276. Volatile : 'volatile';
  277. Void : 'void';
  278. While : 'while';
  279. // library subobject types from modern HLSL:
  280. StateObjectConfig : 'StateObjectConfig';
  281. LocalRootSignature : 'LocalRootSignature';
  282. GlobalRootSignature : 'GlobalRootSignature';
  283. SubobjectToExportsAssociation : 'SubobjectToExportsAssociation';
  284. RaytracingShaderConfig : 'RaytracingShaderConfig';
  285. RaytracingPipelineConfig : 'RaytracingPipelineConfig';
  286. RaytracingPipelineConfig1 : 'RaytracingPipelineConfig1';
  287. TriangleHitGroup : 'TriangleHitGroup';
  288. ProceduralPrimitiveHitGroup : 'ProceduralPrimitiveHitGroup';
  289. // AZSL: Allow Sampler states to be defined in the AZSL code as part of the SRG definition
  290. ADDRESS_U : 'AddressU';
  291. ADDRESS_V : 'AddressV';
  292. ADDRESS_W : 'AddressW';
  293. BORDER_COLOR : 'BorderColor';
  294. MIN_FILTER : 'MinFilter';
  295. MAG_FILTER : 'MagFilter';
  296. MIP_FILTER : 'MipFilter';
  297. MAX_ANISOTROPY : 'MaxAnisotropy';
  298. MAX_LOD : 'MaxLOD';
  299. MIN_LOD : 'MinLOD';
  300. MIP_LOD_BIAS : 'MipLODBias';
  301. COMPARISON_FUNC : 'ComparisonFunc';
  302. REDUCTION_TYPE : 'ReductionType';
  303. FILTER_MODE_POINT : 'Point';
  304. FILTER_MODE_LINEAR : 'Linear';
  305. REDUCTION_TYPE_FILTER : 'Filter';
  306. REDUCTION_TYPE_COMPARISON : 'Comparison';
  307. REDUCTION_TYPE_MINIMUM : 'Minimum';
  308. REDUCTION_TYPE_MAXIMUM : 'Maximum';
  309. ADDRESS_MODE_WRAP : 'Wrap';
  310. ADDRESS_MODE_MIRROR : 'Mirror';
  311. ADDRESS_MODE_CLAMP : 'Clamp';
  312. ADDRESS_MODE_BORDER : 'Border';
  313. ADDRESS_MODE_MIRROR_ONCE : 'MirrorOnce';
  314. COMPARISON_FUNCTION_NEVER : 'Never';
  315. COMPARISON_FUNCTION_LESS : 'Less';
  316. COMPARISON_FUNCTION_EQUAL : 'Equal';
  317. COMPARISON_FUNCTION_LESS_EQUAL : 'LessEqual';
  318. COMPARISON_FUNCTION_GREATER : 'Greater';
  319. COMPARISON_FUNCTION_NOT_EQUAL : 'NotEqual';
  320. COMPARISON_FUNCTION_GREATER_EQUAL : 'GreaterEqual';
  321. COMPARISON_FUNCTION_ALWAYS : 'Always';
  322. BORDER_COLOR_OPAQUE_BLACK : 'OpaqueBlack';
  323. BORDER_COLOR_TRANSPARENT_BLACK : 'TransparentBlack';
  324. BORDER_COLOR_OPAQUE_WHITE : 'OpaqueWhite';
  325. LeftParen : '(';
  326. RightParen : ')';
  327. LeftBracket : '[';
  328. RightBracket : ']';
  329. LeftBrace : '{';
  330. RightBrace : '}';
  331. LeftDoubleBracket : '[[';
  332. Less : '<';
  333. LessEqual : '<=';
  334. Greater : '>';
  335. GreaterEqual : '>=';
  336. LeftShift : '<<';
  337. RightShift : '>>';
  338. Plus : '+';
  339. PlusPlus : '++';
  340. Minus : '-';
  341. MinusMinus : '--';
  342. Star : '*';
  343. Div : '/';
  344. Mod : '%';
  345. And : '&';
  346. Or : '|';
  347. AndAnd : '&&';
  348. OrOr : '||';
  349. Caret : '^';
  350. Not : '!';
  351. Tilde : '~';
  352. Question : '?';
  353. Colon : ':';
  354. ColonColon : '::';
  355. Semi : ';';
  356. Comma : ',';
  357. Assign : '=';
  358. // '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
  359. StarAssign : '*=';
  360. DivAssign : '/=';
  361. ModAssign : '%=';
  362. PlusAssign : '+=';
  363. MinusAssign : '-=';
  364. LeftShiftAssign : '<<=';
  365. RightShiftAssign : '>>=';
  366. AndAssign : '&=';
  367. XorAssign : '^=';
  368. OrAssign : '|=';
  369. Equal : '==';
  370. NotEqual : '!=';
  371. Dot : '.';
  372. True : 'true';
  373. False : 'false';
  374. // AZSL extensions
  375. KW_AssociatedType : 'associatedtype' ;
  376. KW_TypeAlias : 'typealias' ;
  377. KW_Typedef : 'typedef' ;
  378. KW_Fundamental : 'fundamental' ; // [GFX TODO]
  379. KW_Typeof : 'typeof' ; // simple decltype-like operator
  380. // AZSL SRG
  381. FrequencyId : 'FrequencyId';
  382. ShaderVariantFallback : 'ShaderVariantFallback';
  383. ShaderResourceGroupSemantic : 'ShaderResourceGroupSemantic';
  384. ShaderResourceGroup : 'ShaderResourceGroup';
  385. // AZSLc-specific internal access keywords
  386. KW_ext_print_message : '__azslc_print_message' ;
  387. KW_ext_print_symbol : '__azslc_print_symbol' ;
  388. KW_ext_prtsym_fully_qualified : '__azslc_prtsym_fully_qualified' ;
  389. KW_ext_prtsym_least_qualified : '__azslc_prtsym_least_qualified' ;
  390. KW_ext_prtsym_constint_value : '__azslc_prtsym_constint_value' ;
  391. HLSLSemanticStream:
  392. 'BINORMAL' Digit*
  393. | 'BLENDINDICES' Digit*
  394. | 'BLENDWEIGHT' Digit*
  395. | 'COLOR' Digit*
  396. | 'NORMAL' Digit*
  397. | 'POSITION' Digit*
  398. | 'POSITIONT'
  399. | 'PSIZE' Digit*
  400. | 'TANGENT' Digit*
  401. | 'TEXCOORD' Digit*
  402. | 'FOG'
  403. | 'TESSFACTOR' Digit*
  404. | 'TEXCOORD' Digit*
  405. | 'VFACE'
  406. | 'VPOS' Digit*
  407. | 'DEPTH' Digit*
  408. ;
  409. HLSLSemanticSystem:
  410. 'SV_' (Nondigit | Digit)*
  411. | 'Sv_' (Nondigit | Digit)*
  412. | 'sV_' (Nondigit | Digit)*
  413. | 'sv_' (Nondigit | Digit)*
  414. ;
  415. // Those keywords are removed from the vocabulary, as of 1.8.8 (were present from 1.8.5)
  416. // since they can be emulated with a lazy Identifier recognition in the qualifier rule
  417. //Center : 'center';
  418. //Indices : 'indices'; // mesh-shader parameter qualifier
  419. //Vertices : 'vertices'; // mesh-shader parameter qualifier
  420. //Payload : 'payload'; // mesh-shader parameter qualifier & hit-shader optional qualifier
  421. Identifier
  422. : Nondigit (Nondigit | Digit)*
  423. ;
  424. fragment
  425. Nondigit
  426. : [a-zA-Z_]
  427. ;
  428. fragment
  429. Digit
  430. : [0-9]
  431. ;
  432. fragment
  433. DecimalOrOctalIntegerLiteral
  434. : Digit+
  435. ;
  436. fragment
  437. HexadecimalIntegerLiteral
  438. : ('0x' | '0X') HexadecimalDigit+
  439. ;
  440. fragment
  441. HexadecimalDigit
  442. : [0-9a-fA-F]
  443. ;
  444. fragment
  445. FractionalConstant
  446. : DigitSequence? '.' DigitSequence
  447. | DigitSequence '.'
  448. ;
  449. fragment
  450. ExponentPart
  451. : 'e' Sign? DigitSequence
  452. | 'E' Sign? DigitSequence
  453. ;
  454. fragment
  455. Sign
  456. : '+' | '-'
  457. ;
  458. fragment
  459. DigitSequence
  460. : Digit+
  461. ;
  462. fragment
  463. HexadecimalDigitSequence
  464. : HexadecimalDigit+
  465. ;
  466. fragment
  467. IntegerSuffix
  468. : [uU]?[lL]?[lL]?
  469. | [lL]?[uU]?
  470. ;
  471. IntegerLiteral
  472. : DecimalOrOctalIntegerLiteral IntegerSuffix?
  473. | HexadecimalIntegerLiteral IntegerSuffix?
  474. ;
  475. // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-appendix-grammar#floating-point-numbers
  476. fragment
  477. FloatingSuffix
  478. : [hHflFL]
  479. ;
  480. FloatLiteral
  481. : FractionalConstant ExponentPart? FloatingSuffix?
  482. | DigitSequence ExponentPart FloatingSuffix?
  483. ;
  484. fragment
  485. EscapeSequence
  486. : SimpleEscapeSequence
  487. ;
  488. fragment
  489. SimpleEscapeSequence
  490. : '\\' ['"?abfnrtv\\]
  491. ;
  492. StringLiteral
  493. : '"' SCharSequence? '"'
  494. ;
  495. fragment
  496. SCharSequence
  497. : SChar+
  498. ;
  499. fragment
  500. SChar
  501. : ~["\\\r\n]
  502. | EscapeSequence
  503. ;
  504. PragmaDirective
  505. : '#' Whitespace? 'pragma' Whitespace ~[\r\n]*
  506. -> channel(PREPROCESSOR)
  507. ;
  508. // valid line directives examples:
  509. // #1
  510. // # 1
  511. // # 1 "file"
  512. // #line 1
  513. // #line 1 "file"
  514. // # line 1 "file" 2 // comment
  515. LineDirective
  516. : '#' Whitespace? ('line' Whitespace)? IntegerLiteral Whitespace? StringLiteral?
  517. -> channel(PREPROCESSOR)
  518. ;
  519. Whitespace
  520. : [ \t]+ -> channel(HIDDEN)
  521. ;
  522. Newline
  523. : ( '\r' '\n'?
  524. | '\n'
  525. ) -> channel(HIDDEN)
  526. ;
  527. // Amazon: The original mode switches from Tim Jones were not working.
  528. BlockComment
  529. : '/*' .*? '*/' -> channel(COMMENTS)
  530. ;
  531. LineComment
  532. : '//' ~[\r\n]* -> channel(COMMENTS)
  533. ;