129 lines
4.1 KiB
Ruby
129 lines
4.1 KiB
Ruby
# -*- coding: utf-8 -*- #
|
|
# frozen_string_literal: true
|
|
|
|
module Rouge
|
|
module Lexers
|
|
class Dafny < RegexLexer
|
|
title "Dafny"
|
|
desc "The Dafny programming language (github.com/dafny-lang/dafny)"
|
|
tag "dafny"
|
|
filenames "*.dfy"
|
|
mimetypes "text/x-dafny"
|
|
|
|
keywords = %w(
|
|
abstract allocated assert assume
|
|
break by
|
|
calc case class codatatype const constructor
|
|
datatype decreases downto
|
|
else ensures exists expect export extends
|
|
false for forall fresh function
|
|
ghost greatest
|
|
if import include invariant iterator
|
|
label least lemma
|
|
match method modifies modify module
|
|
nameonly new newtype null
|
|
old opened
|
|
predicate print provides
|
|
reads refines requires return returns reveal reveals
|
|
static
|
|
then this to trait true twostate type
|
|
unchanged
|
|
var
|
|
while witness
|
|
yield yields
|
|
)
|
|
|
|
literals = %w{ true false null }
|
|
|
|
textOperators = %w{ as is in }
|
|
|
|
types = %w(bool char int real string nat
|
|
array array? object object? ORDINAL
|
|
seq set iset map imap multiset )
|
|
|
|
idstart = /[0-9a-zA-Z?]/
|
|
idchar = /[0-9a-zA-Z_'?]/
|
|
id = /#{idstart}#{idchar}*/
|
|
|
|
arrayType = /array(?:1[0-9]+|[2-9][0-9]*)\??(?!#{idchar})/
|
|
bvType = /bv(?:0|[1-9][0-9]*)(?!#{idchar})/
|
|
|
|
digit = /\d/
|
|
digits = /#{digit}+(?:_#{digit}+)*/
|
|
bin_digits = /[01]+(?:_[01]+)*/
|
|
hex_digit = /(?:[0-9a-fA-F])/
|
|
hex_digits = /#{hex_digit}+(?:_#{hex_digit}+)*/
|
|
|
|
cchar = /(?:[^\\'\n\r]|\\["'ntr\\0])/
|
|
schar = /(?:[^\\"\n\r]|\\["'ntr\\0])/
|
|
uchar = /(?:\\u#{hex_digit}{4})/
|
|
|
|
## IMPORTANT: Rules are ordered, which allows later rules to be
|
|
## simpler than they would otherwise be
|
|
state :root do
|
|
rule %r(/\*), Comment::Multiline, :comment
|
|
rule %r(//.*?$), Comment::Single
|
|
rule %r(\*/), Error # should not have closing comment in :root
|
|
# is an improperly nested comment
|
|
|
|
rule %r/'#{cchar}'/, Str::Char # standard or escape char
|
|
rule %r/'#{uchar}'/, Str::Char # unicode char
|
|
rule %r/'[^'\n\r]*'/, Error # bad any other enclosed char
|
|
rule %r/'[^'\n\r]*$/, Error # bad unclosed char
|
|
|
|
rule %r/"(?:#{schar}|#{uchar})*"/, Str::Double # valid string
|
|
rule %r/".*"/, Error # anything else that is closed
|
|
rule %r/".*$/, Error # bad unclosed string
|
|
|
|
rule %r/@"([^"]|"")*"/, Str::Other # valid verbatim string
|
|
rule %r/@".*/m, Error # anything else , multiline unclosed
|
|
|
|
|
|
rule %r/#{digits}\.#{digits}(?!#{idchar})/, Num::Float
|
|
rule %r/0b#{bin_digits}(?!#{idchar})/, Num::Bin
|
|
rule %r/0b#{idchar}*/, Error
|
|
rule %r/0x#{hex_digits}(?!#{idchar})/, Num::Hex
|
|
rule %r/0x#{idchar}*/, Error
|
|
rule %r/#{digits}(?!#{idchar})/, Num::Integer
|
|
rule %r/_(?!#{idchar})/, Name
|
|
rule %r/_[0-9_]+[_]?(?!#{idchar})/, Error
|
|
rule %r/[0-9_]+_(?!#{idchar})/, Error
|
|
rule %r/[0-9]#{idchar}+/, Error
|
|
|
|
rule %r/#{arrayType}/, Keyword::Type
|
|
rule %r/#{bvType}/, Keyword::Type
|
|
|
|
rule id do |m|
|
|
if types.include?(m[0])
|
|
token Keyword::Type
|
|
elsif literals.include?(m[0])
|
|
token Keyword::Constant
|
|
elsif textOperators.include?(m[0])
|
|
token Operator::Word
|
|
elsif keywords.include?(m[0])
|
|
token Keyword::Reserved
|
|
else
|
|
token Name
|
|
end
|
|
end
|
|
|
|
rule %r/\.\./, Operator
|
|
rule %r/[*!%&<>\|^+=:.\/-]/, Operator
|
|
rule %r/[\[\](){},;`]/, Punctuation
|
|
|
|
rule %r/[^\S\n]+/, Text
|
|
rule %r/\n/, Text
|
|
rule %r/./, Error # Catchall
|
|
end
|
|
|
|
state :comment do
|
|
rule %r(\*/), Comment::Multiline, :pop!
|
|
rule %r(/\*), Comment::Multiline, :comment
|
|
rule %r([^*/]+), Comment::Multiline
|
|
rule %r(.), Comment::Multiline
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|