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
|