176 lines
4.7 KiB
Ruby
176 lines
4.7 KiB
Ruby
# encoding: utf-8
|
|
module CodeRay
|
|
module Scanners
|
|
|
|
module Ruby::Patterns # :nodoc: all
|
|
|
|
KEYWORDS = %w[
|
|
and def end in or unless begin
|
|
defined? ensure module redo super until
|
|
BEGIN break do next rescue then
|
|
when END case else for retry
|
|
while alias class elsif if not return
|
|
undef yield
|
|
]
|
|
|
|
# See http://murfy.de/ruby-constants.
|
|
PREDEFINED_CONSTANTS = %w[
|
|
nil true false self
|
|
DATA ARGV ARGF ENV
|
|
FALSE TRUE NIL
|
|
STDERR STDIN STDOUT
|
|
TOPLEVEL_BINDING
|
|
RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL
|
|
RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION
|
|
__FILE__ __LINE__ __ENCODING__
|
|
]
|
|
|
|
IDENT_KIND = WordList.new(:ident).
|
|
add(KEYWORDS, :keyword).
|
|
add(PREDEFINED_CONSTANTS, :predefined_constant)
|
|
|
|
KEYWORD_NEW_STATE = WordList.new(:initial).
|
|
add(%w[ def ], :def_expected).
|
|
add(%w[ undef ], :undef_expected).
|
|
add(%w[ alias ], :alias_expected).
|
|
add(%w[ class module ], :module_expected)
|
|
|
|
IDENT = 'ä'[/[[:alpha:]]/] == 'ä' ? /[[:alpha:]_][[:alnum:]_]*/ : /[^\W\d]\w*/
|
|
|
|
METHOD_NAME = / #{IDENT} [?!]? /ox
|
|
METHOD_NAME_OPERATOR = /
|
|
\*\*? # multiplication and power
|
|
| [-+~]@? # plus, minus, tilde with and without at sign
|
|
| [\/%&|^`] # division, modulo or format strings, and, or, xor, system
|
|
| \[\]=? # array getter and setter
|
|
| << | >> # append or shift left, shift right
|
|
| <=?>? | >=? # comparison, rocket operator
|
|
| ===? | =~ # simple equality, case equality, match
|
|
| ![~=@]? # negation with and without at sign, not-equal and not-match
|
|
/ox
|
|
METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x
|
|
METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox
|
|
METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox
|
|
INSTANCE_VARIABLE = / @ #{IDENT} /ox
|
|
CLASS_VARIABLE = / @@ #{IDENT} /ox
|
|
OBJECT_VARIABLE = / @@? #{IDENT} /ox
|
|
GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox
|
|
PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox
|
|
VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox
|
|
|
|
QUOTE_TO_TYPE = {
|
|
'`' => :shell,
|
|
'/'=> :regexp,
|
|
}
|
|
QUOTE_TO_TYPE.default = :string
|
|
|
|
REGEXP_MODIFIERS = /[mousenix]*/
|
|
|
|
DECIMAL = /\d+(?:_\d+)*/
|
|
OCTAL = /0_?[0-7]+(?:_[0-7]+)*/
|
|
HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/
|
|
BINARY = /0b[01]+(?:_[01]+)*/
|
|
|
|
EXPONENT = / [eE] [+-]? #{DECIMAL} /ox
|
|
FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox
|
|
FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox
|
|
NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox
|
|
|
|
SYMBOL = /
|
|
:
|
|
(?:
|
|
#{METHOD_NAME_EX}
|
|
| #{PREFIX_VARIABLE}
|
|
| ['"]
|
|
)
|
|
/ox
|
|
METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox
|
|
|
|
SIMPLE_ESCAPE = /
|
|
[abefnrstv]
|
|
| [0-7]{1,3}
|
|
| x[0-9A-Fa-f]{1,2}
|
|
| .
|
|
/mx
|
|
|
|
CONTROL_META_ESCAPE = /
|
|
(?: M-|C-|c )
|
|
(?: \\ (?: M-|C-|c ) )*
|
|
(?: [^\\] | \\ #{SIMPLE_ESCAPE} )?
|
|
/mox
|
|
|
|
ESCAPE = /
|
|
#{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE}
|
|
/mox
|
|
|
|
CHARACTER = /
|
|
\?
|
|
(?:
|
|
[^\s\\]
|
|
| \\ #{ESCAPE}
|
|
)
|
|
/mox
|
|
|
|
# NOTE: This is not completely correct, but
|
|
# nobody needs heredoc delimiters ending with \n.
|
|
HEREDOC_OPEN = /
|
|
<< (-)? # $1 = float
|
|
(?:
|
|
( [A-Za-z_0-9]+ ) # $2 = delim
|
|
|
|
|
( ["'`\/] ) # $3 = quote, type
|
|
( [^\n]*? ) \3 # $4 = delim
|
|
)
|
|
/mx
|
|
|
|
RUBYDOC = /
|
|
=begin (?!\S)
|
|
.*?
|
|
(?: \Z | ^=end (?!\S) [^\n]* )
|
|
/mx
|
|
|
|
DATA = /
|
|
__END__$
|
|
.*?
|
|
(?: \Z | (?=^\#CODE) )
|
|
/mx
|
|
|
|
RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo
|
|
|
|
# Checks for a valid value to follow. This enables
|
|
# value_expected in method calls without parentheses.
|
|
VALUE_FOLLOWS = /
|
|
(?>[ \t\f\v]+)
|
|
(?:
|
|
[%\/][^\s=]
|
|
| <<-?\S
|
|
| [-+] \d
|
|
| #{CHARACTER}
|
|
)
|
|
/ox
|
|
KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[
|
|
and end in or unless begin
|
|
defined? ensure redo super until
|
|
break do next rescue then
|
|
when case else for retry
|
|
while elsif if not return
|
|
yield
|
|
])
|
|
|
|
FANCY_STRING_START = / % ( [QqrsWwx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x
|
|
FANCY_STRING_KIND = Hash.new(:string).merge({
|
|
'r' => :regexp,
|
|
's' => :symbol,
|
|
'x' => :shell,
|
|
})
|
|
FANCY_STRING_INTERPRETED = Hash.new(true).merge({
|
|
'q' => false,
|
|
's' => false,
|
|
'w' => false,
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
end
|