summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb
blob: 0891470ee7dd34d70808f0bdb9f0aa4bbb0c19fa (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
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class RML < RegexLexer
      title "RML"
      desc "A system agnostic domain-specific language for runtime monitoring and verification (https://rmlatdibris.github.io/)"
      tag 'rml'
      filenames '*.rml'

      def self.keywords
        @keywords ||= Set.new %w(
          matches not with empty
          all if else true false
        )
      end

      def self.arithmetic_keywords
        @arithmetic_keywords ||= Set.new %w(
          abs sin cos tan min max
        )
      end

      id_char = /[a-zA-Z0-9_]/
      uppercase_id = /[A-Z]#{id_char}*/
      lowercase_id = /[a-z]#{id_char}*/

      ellipsis = /(\.){3}/
      int = /[0-9]+/
      float = /#{int}\.#{int}/
      string = /'(\\'|[ a-zA-Z0-9_.])*'/

      whitespace = /[ \t\r\n]+/
      comment = /\/\/[^\r\n]*/

      state :common_rules do
        rule %r/#{whitespace}/, Text
        rule %r/#{comment}/, Comment::Single
        rule %r/#{string}/, Literal::String
        rule %r/#{float}/, Num::Float
        rule %r/#{int}/, Num::Integer
      end

      state :root do
        mixin :common_rules
        rule %r/(#{lowercase_id})(\()/ do
          groups Name::Function, Operator
          push :event_type_params
        end
        rule %r/#{lowercase_id}/ do |m|
          if m[0] == 'with'
            token Keyword
            push :data_expression_with
          elsif self.class.keywords.include? m[0]
            token Keyword
          else
            token Name::Function
          end
        end
        rule %r/\(|\{|\[/, Operator, :event_type_params
        rule %r/[_\|]/, Operator
        rule %r/#{uppercase_id}/, Name::Class, :equation_block_expression
        rule %r/;/, Operator
      end

      state :event_type_params do
        mixin :common_rules
        rule %r/\(|\{|\[/, Operator, :push
        rule %r/\)|\}|\]/, Operator, :pop!
        rule %r/#{lowercase_id}(?=:)/, Name::Entity
        rule %r/(#{lowercase_id})/ do |m|
          if self.class.keywords.include? m[0]
            token Keyword
          else
            token Literal::String::Regex
          end
        end
        rule %r/#{ellipsis}/, Literal::String::Symbol
        rule %r/[_\|;,:]/, Operator
      end

      state :equation_block_expression do
        mixin :common_rules
        rule %r/[<,>]/, Operator
        rule %r/#{lowercase_id}/, Literal::String::Regex
        rule %r/=/ do
          token Operator
          goto :exp
        end
        rule %r/;/, Operator, :pop!
      end

      state :exp do
        mixin :common_rules
        rule %r/(if)(\()/ do
          groups Keyword, Operator
          push :data_expression
        end
        rule %r/let|var/, Keyword, :equation_block_expression
        rule %r/(#{lowercase_id})(\()/ do
          groups Name::Function, Operator
          push :event_type_params
        end
        rule %r/(#{lowercase_id})/ do |m|
          if self.class.keywords.include? m[0]
            token Keyword
          else
            token Name::Function
          end
        end
        rule %r/#{uppercase_id}(?=<)/, Name::Class, :data_expression
        rule %r/#{uppercase_id}/, Name::Class
        rule %r/[=(){}*+\/\\\|!>?]/, Operator
        rule %r/;/, Operator, :pop!
      end

      state :data_expression do
        mixin :common_rules
        rule %r/#{lowercase_id}/ do |m|
          if (self.class.arithmetic_keywords | self.class.keywords).include? m[0]
            token Keyword
          else
            token Literal::String::Regex
          end
        end
        rule %r/\(/, Operator, :push
        rule %r/\)/, Operator, :pop!
        rule %r/(>)(?=[^A-Z;]+[A-Z;>])/, Operator, :pop!
        rule %r/[*^?!%&\[\]<>\|+=:,.\/\\_-]/, Operator
        rule %r/;/, Operator, :pop!
      end

      state :data_expression_with do
        mixin :common_rules
        rule %r/>/, Operator
        mixin :data_expression

      end
    end
  end
end