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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
module Rugments
module Lexers
load_const :C, 'c.rb'
class ObjectiveC < C
tag 'objective_c'
title 'Objective-C'
desc 'an extension of C commonly used to write Apple software'
aliases 'objc'
filenames '*.m', '*.h'
mimetypes 'text/x-objective_c', 'application/x-objective_c'
def self.at_keywords
@at_keywords ||= %w(
selector private protected public encode synchronized try
throw catch finally end property synthesize dynamic optional
interface implementation import
)
end
def self.at_builtins
@at_builtins ||= %w(true false YES NO)
end
def self.builtins
@builtins ||= %w(YES NO nil)
end
def self.analyze_text(text)
return 1 if text =~ /@(end|implementation|protocol|property)\b/
id = /[a-z$_][a-z0-9$_]*/i
return 0.4 if text =~ %r{
\[ \s* #{id} \s+
(?:
#{id} \s* \]
| #{id}? :
)
}x
return 0.4 if text.include? '@"'
end
id = /[a-z$_][a-z0-9$_]*/i
prepend :statements do
rule /@"/, Str, :string
rule /@'(\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|\\.|[^\\'\n]')/,
Str::Char
rule /@(\d+[.]\d*|[.]\d+|\d+)e[+-]?\d+l?/i,
Num::Float
rule /@(\d+[.]\d*|[.]\d+|\d+f)f?/i, Num::Float
rule /@0x\h+[lL]?/, Num::Hex
rule /@0[0-7]+l?/i, Num::Oct
rule /@\d+l?/, Num::Integer
rule /\bin\b/, Keyword
rule /@(?:interface|implementation)\b/ do
token Keyword
goto :classname
end
rule /@(?:class|protocol)\b/ do
token Keyword
goto :forward_classname
end
rule /@([[:alnum:]]+)/ do |m|
if self.class.at_keywords.include? m[1]
token Keyword
elsif self.class.at_builtins.include? m[1]
token Name::Builtin
else
token Error
end
end
rule /[?]/, Punctuation, :ternary
rule /\[/, Punctuation, :message
end
state :ternary do
rule /:/, Punctuation, :pop!
mixin :statements
end
state :message_shared do
rule /\]/, Punctuation, :pop!
rule /;/, Error
mixin :statement
end
state :message do
rule /(#{id})(\s*)(:)/ do
groups(Name::Function, Text, Punctuation)
goto :message_with_args
end
rule /(#{id})(\s*)(\])/ do
groups(Name::Function, Text, Punctuation)
pop!
end
mixin :message_shared
end
state :message_with_args do
rule /(#{id})(\s*)(:)/ do
groups(Name::Function, Text, Punctuation)
end
mixin :message_shared
end
state :classname do
mixin :whitespace
rule /(#{id})(\s*)(:)(\s*)(#{id})/ do
groups(Name::Class, Text,
Punctuation, Text,
Name::Class)
pop!
end
rule /(#{id})(\s*)([(])(\s*)(#{id})(\s*)([)])/ do
groups(Name::Class, Text,
Punctuation, Text,
Name::Label, Text,
Punctuation)
end
rule id, Name::Class, :pop!
end
state :forward_classname do
mixin :whitespace
rule /(#{id})(\s*)(,)(\s*)/ do
groups(Name::Class, Text, Punctuation, Text)
push
end
rule /(#{id})(\s*)(;?)/ do
groups(Name::Class, Text, Punctuation)
pop!
end
end
prepend :root do
rule %r{
([-+])(\s*)
([(].*?[)])?(\s*)
(?=#{id}:?)
}ix do |m|
token Keyword, m[1]; token Text, m[2]
recurse m[3]; token Text, m[4]
push :method_definition
end
end
state :method_definition do
rule /,/, Punctuation
rule /[.][.][.]/, Punctuation
rule /([(].*?[)])(#{id})/ do |m|
recurse m[1]; token Name::Variable, m[2]
end
rule /(#{id})(\s*)(:)/m do
groups(Name::Function, Text, Punctuation)
end
rule /;/, Punctuation, :pop!
rule /{/ do
token Punctuation
goto :function
end
mixin :inline_whitespace
rule %r{//.*?\n}, Comment::Single
rule /\s+/m, Text
rule(//) { pop! }
end
end
end
end
|