cel.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. """
  2. pygments.lexers.cel
  3. ~~~~~~~~~~~~~~~~~~~
  4. Lexer for CEL (Common Expression Language).
  5. :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. __all__ = ['CELLexer']
  9. import re
  10. from pygments.lexer import RegexLexer, words
  11. from pygments.token import (
  12. Comment, Keyword, Name, Number, Operator, Punctuation, String, Whitespace,
  13. )
  14. class CELLexer(RegexLexer):
  15. """Lexer for CEL (Common Expression Language)."""
  16. name = 'CEL'
  17. aliases = ['cel']
  18. filenames = ['*.cel']
  19. mimetypes = []
  20. url = 'https://cel.dev'
  21. version_added = '2.21'
  22. flags = re.MULTILINE | re.UNICODE
  23. # Escape sequence per the CEL spec:
  24. # \a \b \f \n \r \t \v \\ \" \' \` \?
  25. # \xHH or \XHH (exactly 2 hex digits)
  26. # \uHHHH (exactly 4 hex digits)
  27. # \UHHHHHHHH (exactly 8 hex digits)
  28. # \OOO (3-digit octal, first digit 0-3)
  29. # \. (fallback for unknown escapes)
  30. _ESCAPE = r"""\\(?:[abfnrtv\\"'`?]|[xX][0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-3][0-7][0-7]|.)"""
  31. # Raw prefix: r/R alone, or b/B combined with r/R in either order
  32. _RAW = r'(?:[bB][rR]|[rR][bB]|[rR])'
  33. tokens = {
  34. 'root': [
  35. (r'\s+', Whitespace),
  36. # CEL only has line comments; no block comments.
  37. (r'//.*$', Comment.Single),
  38. # Bytes and string literals.
  39. # Raw variants (no escape processing) must be tried before
  40. # non-raw so that br/rb/r prefixes are consumed greedily.
  41. # Triple-quoted raw (br""", rb""", r""")
  42. (_RAW + r'"""', String, 'triple-double-raw'),
  43. (_RAW + r"'''", String, 'triple-single-raw'),
  44. # Triple-quoted non-raw with optional b prefix (b""" or """)
  45. (r'[bB]?"""', String, 'triple-double'),
  46. (r"[bB]?'''", String, 'triple-single'),
  47. # Single-line raw
  48. (_RAW + r'"[^"\r\n]*"', String),
  49. (_RAW + r"'[^'\r\n]*'", String),
  50. # Single-line non-raw with optional b prefix
  51. (r'[bB]?"', String, 'double-string'),
  52. (r"[bB]?'", String, 'single-string'),
  53. # Numbers.
  54. # uint_literal: integer (decimal or hex) followed by u/U suffix.
  55. (r'(?:0[xX][0-9a-fA-F]+|0|[1-9][0-9]*)[uU]', Number.Integer),
  56. # float_literal: the grammar requires digits on both sides of the
  57. # decimal point for the dotted form — `1.` is not valid CEL.
  58. (r'(?:[0-9]+\.[0-9]+(?:[eE][+-]?[0-9]+)?'
  59. r'|[0-9]+[eE][+-]?[0-9]+'
  60. r'|\.[0-9]+(?:[eE][+-]?[0-9]+)?)',
  61. Number.Float),
  62. # int_literal: hex or decimal.
  63. (r'0[xX][0-9a-fA-F]+|0|[1-9][0-9]*', Number.Integer),
  64. # Reserved keywords (may not appear as identifiers).
  65. (words((
  66. 'as', 'break', 'const', 'continue', 'else', 'for',
  67. 'function', 'if', 'import', 'let', 'loop', 'namespace',
  68. 'package', 'return', 'var', 'void', 'while',
  69. ), suffix=r'\b'), Keyword.Reserved),
  70. # `in` is a comparison operator keyword.
  71. (r'in\b', Keyword),
  72. # Built-in literal constants.
  73. (words(('true', 'false', 'null'), suffix=r'\b'), Keyword.Constant),
  74. # Logical and comparison operators.
  75. (r'&&|\|\|', Operator),
  76. (r'==|!=|<=|>=', Operator),
  77. # Arithmetic, unary, ternary, and remaining comparison operators.
  78. (r'[+\-*/%<>!?]', Operator),
  79. # Punctuation: brackets, comma, dot, colon.
  80. (r'[(){}\[\]]', Punctuation),
  81. (r'[,.]', Punctuation),
  82. (r':', Punctuation),
  83. # Identifiers: start with letter or underscore (Unicode-aware).
  84. (r'[^\W\d]\w*', Name),
  85. ],
  86. # Raw triple-quoted (no escape tokens; content is one big String).
  87. 'triple-double-raw': [
  88. (r'"""', String, '#pop'),
  89. (r'"(?!"")', String),
  90. (r'[^"]+', String),
  91. ],
  92. 'triple-single-raw': [
  93. (r"'''", String, '#pop'),
  94. (r"'(?!'')", String),
  95. (r"[^']+", String),
  96. ],
  97. # Non-raw triple-quoted (escape sequences highlighted separately).
  98. 'triple-double': [
  99. (r'"""', String, '#pop'),
  100. (_ESCAPE, String.Escape),
  101. (r'"(?!"")', String),
  102. (r'[^"\\]+', String),
  103. ],
  104. 'triple-single': [
  105. (r"'''", String, '#pop'),
  106. (_ESCAPE, String.Escape),
  107. (r"'(?!'')", String),
  108. (r"[^'\\]+", String),
  109. ],
  110. # Single-line non-raw strings (cannot span lines).
  111. 'double-string': [
  112. (r'"', String, '#pop'),
  113. (_ESCAPE, String.Escape),
  114. (r'[^"\\\r\n]+', String),
  115. ],
  116. 'single-string': [
  117. (r"'", String, '#pop'),
  118. (_ESCAPE, String.Escape),
  119. (r"[^'\\\r\n]+", String),
  120. ],
  121. }