143 lines
3.9 KiB
Ruby
143 lines
3.9 KiB
Ruby
# -*- 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
|