summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.5.2/lib/rouge/lexers/hcl.rb
blob: 69a65f99e92caf9fa77b18724e3f57bd4b8b442f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class Hcl < RegexLexer
      tag 'hcl'
      filenames '*.hcl', '*.nomad'

      title 'Hashicorp Configuration Language'
      desc 'Hashicorp Configuration Language, used by Terraform and other Hashicorp tools'

      state :multiline_comment do
        rule %r([*]/), Comment::Multiline, :pop!
        rule %r([^*/]+), Comment::Multiline
        rule %r([*/]), Comment::Multiline
      end

      state :comments_and_whitespace do
        rule %r/\s+/, Text
        rule %r(//.*?$), Comment::Single
        rule %r(#.*?$), Comment::Single
        rule %r(/[*]), Comment::Multiline, :multiline_comment
      end

      state :primitives do
        rule %r/[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?([kKmMgG]b?)?/, Num::Float
        rule %r/[0-9]+([kKmMgG]b?)?/, Num::Integer
        rule %r/[-+*\/!%&<>|=:?]/, Operator

        rule %r/"/, Str::Double, :dq
        rule %r/'/, Str::Single, :sq
        rule %r/(<<-?)(\s*)(\'?)(\\?)(\w+)(\3)/ do |m|
          groups Operator, Text, Str::Heredoc, Str::Heredoc, Name::Constant, Str::Heredoc
          @heredocstr = Regexp.escape(m[5])
          push :heredoc
        end
      end

      def self.keywords
        @keywords ||= Set.new %w()
      end

      def self.declarations
        @declarations ||= Set.new %w()
      end

      def self.reserved
        @reserved ||= Set.new %w()
      end

      def self.constants
        @constants ||= Set.new %w(true false null)
      end

      def self.builtins
        @builtins ||= %w()
      end

      id = /[$a-z_\-][a-z0-9_\-]*/io

      state :root do
        mixin :comments_and_whitespace
        mixin :primitives

        rule %r/\{/ do
          token Punctuation
          push :hash
        end
        rule %r/\[/ do
          token Punctuation
          push :array
        end

        rule id do |m|
          if self.class.keywords.include? m[0]
            token Keyword
            push :composite
          elsif self.class.declarations.include? m[0]
            token Keyword::Declaration
            push :composite
          elsif self.class.reserved.include? m[0]
            token Keyword::Reserved
          elsif self.class.constants.include? m[0]
            token Keyword::Constant
          elsif self.class.builtins.include? m[0]
            token Name::Builtin
          else
            token Name::Other
            push :composite
          end
        end
      end

      state :composite do
        mixin :comments_and_whitespace

        rule %r/[{]/ do
          token Punctuation
          pop!
          push :hash
        end

        rule %r/[\[]/ do
          token Punctuation
          pop!
          push :array
        end

        mixin :root

        rule %r//, Text, :pop!
      end

      state :hash do
        mixin :comments_and_whitespace

        rule %r/[.,()\\\/*]/, Punctuation
        rule %r/\=/, Punctuation
        rule %r/\}/, Punctuation, :pop!

        mixin :root
      end

      state :array do
        mixin :comments_and_whitespace

        rule %r/[.,()\\\/*]/, Punctuation
        rule %r/\]/, Punctuation, :pop!

        mixin :root
      end

      state :dq do
        rule %r/[^\\"]+/, Str::Double
        rule %r/\\"/, Str::Escape
        rule %r/"/, Str::Double, :pop!
      end

      state :sq do
        rule %r/[^\\']+/, Str::Single
        rule %r/\\'/, Str::Escape
        rule %r/'/, Str::Single, :pop!
      end

      state :heredoc do
        rule %r/\n/, Str::Heredoc, :heredoc_nl
        rule %r/[^$\n]+/, Str::Heredoc
        rule %r/[$]/, Str::Heredoc
      end

      state :heredoc_nl do
        rule %r/\s*(\w+)\s*\n/ do |m|
          if m[1] == @heredocstr
            token Name::Constant
            pop! 2
          else
            token Str::Heredoc
          end
        end

        rule(//) { pop! }
      end
    end
  end
end