diff --git a/core/global_variables.rbs b/core/global_variables.rbs
new file mode 100644
index 000000000..6a6b0d26b
--- /dev/null
+++ b/core/global_variables.rbs
@@ -0,0 +1,180 @@
+# The Exception object set by Kernel#raise.
+$!: Exception | nil
+
+# The array contains the module names loaded by require.
+$": Array[String]
+
+# The process number of the Ruby running this script. Same as Process.pid.
+$$: Integer
+
+# The string matched by the last successful match.
+$&: String | nil
+
+# The string to the right of the last successful match.
+$': String | nil
+
+# The same as ARGV.
+$*: Array[String]
+
+# The highest group matched by the last successful match.
+$+: String | nil
+
+# The output field separator for Kernel#print and Array#join. Non-nil $, will be deprecated.
+$,: String | nil
+
+# The input record separator, newline by default.
+$-0: String | nil
+
+# The default separator for String#split. Non-nil $; will be deprecated.
+$-F: Regexp | String | nil
+
+# Load path for searching Ruby scripts and extension libraries used
+# by Kernel#load and Kernel#require.
+# Has a singleton method $LOAD_PATH.resolve_feature_path(feature)
+# that returns [+:rb+ or +:so+, path], which resolves the feature to
+# the path the original Kernel#require method would load.
+$-I: Array[String]
+
+$-W: 0 | 1 | 2
+
+# True if option -a is set. Read-only variable.
+$-a: bool
+
+# The debug flag, which is set by the -d switch. Enabling debug
+# output prints each exception raised to $stderr (but not its
+# backtrace). Setting this to a true value enables debug output as
+# if -d were given on the command line. Setting this to a false
+# value disables debug output.
+$-d: bool
+
+# In in-place-edit mode, this variable holds the extension, otherwise +nil+.
+$-i: bool
+
+# True if option -l is set. Read-only variable.
+$-l: bool
+
+# True if option -p is set. Read-only variable.
+$-p: bool
+
+# The verbose flag, which is set by the -w or -v switch.
+# Setting this to a true value enables warnings as if -w or -v were given
+# on the command line. Setting this to +nil+ disables warnings,
+# including from Kernel#warn.
+$-v: bool | nil
+
+# The verbose flag, which is set by the -w or -v switch.
+# Setting this to a true value enables warnings as if -w or -v were given
+# on the command line. Setting this to +nil+ disables warnings,
+# including from Kernel#warn.
+$-w: bool | nil
+
+# The current input line number of the last file that was read.
+$.: Integer
+
+# The input record separator, newline by default. Aliased to $-0.
+$/: String | nil
+
+# The same as $!.backtrace.
+$0: String
+
+# The Nth group of the last successful match. May be > 1.
+$1: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$2: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$3: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$4: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$5: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$6: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$7: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$8: String | nil
+
+# The Nth group of the last successful match. May be > 1.
+$9: String | nil
+
+# Load path for searching Ruby scripts and extension libraries used
+# by Kernel#load and Kernel#require.
+# Has a singleton method $LOAD_PATH.resolve_feature_path(feature)
+# that returns [+:rb+ or +:so+, path], which resolves the feature to
+# the path the original Kernel#require method would load.
+$:: Array[String]
+
+# The default separator for String#split. Non-nil $; will be deprecated. Aliased to $-F.
+$;: Regexp | String | nil
+
+# The same as ARGF.
+$<: IO
+
+# This variable is no longer effective. Deprecated.
+$=: bool
+
+# The default output stream for Kernel#print and Kernel#printf. $stdout by default.
+$>: IO
+
+# The status of the last executed child process (thread-local).
+$?: Process::Status | nil
+
+# The same as $!.backtrace
.
+$@: Array[String] | nil
+
+# The debug flag, which is set by the -d switch. Enabling debug
+# output prints each exception raised to $stderr (but not its
+# backtrace). Setting this to a true value enables debug output as
+# if -d were given on the command line. Setting this to a false
+# value disables debug output. Aliased to $-d.
+$DEBUG: bool
+
+# Current input filename from ARGF. Same as ARGF.filename.
+$FILENAME: String
+
+# The array contains the module names loaded by require.
+$LOADED_FEATURES: Array[String]
+
+# Load path for searching Ruby scripts and extension libraries used
+# by Kernel#load and Kernel#require. Aliased to $: and $-I.
+# Has a singleton method $LOAD_PATH.resolve_feature_path(feature)
+# that returns [+:rb+ or +:so+, path], which resolves the feature to
+# the path the original Kernel#require method would load.
+$LOAD_PATH: Array[String]
+
+# The same as $!.backtrace.
+$PROGRAM_NAME: String
+
+# The verbose flag, which is set by the -w or -v switch.
+# Setting this to a true value enables warnings as if -w or -v were given
+# on the command line. Setting this to +nil+ disables warnings,
+# including from Kernel#warn. Aliased to $-v and $-w.
+$VERBOSE: bool | nil
+
+# The output record separator for Kernel#print and IO#write. Default is +nil+.
+$\: String | nil
+
+# The last input line of string by gets or readline.
+$_: String | nil
+
+# The string to the left of the last successful match.
+$`: String | nil
+
+# The current standard error output.
+$stderr: IO
+
+# The current standard input.
+$stdin: IO
+
+# The current standard output.
+$stdout: IO
+
+# The information about the last match in the current scope (thread-local and frame-local).
+$~: MatchData | nil
diff --git a/lib/rbs/parser.rb b/lib/rbs/parser.rb
index 04518d015..24fa8a2ae 100644
--- a/lib/rbs/parser.rb
+++ b/lib/rbs/parser.rb
@@ -326,7 +326,7 @@ def next_token
new_token(:tUKEYWORD, input.matched.chop.to_sym)
when input.scan(/[A-Z]\w*[?!]:/)
new_token(:tUKEYWORD_Q_E, input.matched.chop.to_sym)
- when input.scan(/\$[A-Za-z_]\w*/)
+ when input.scan(/\$([A-Za-z_]\w*|[~*$?!@\/\\;,.=:<>"&`'+]|\d+|-[0-9_A-Za-z])/)
new_token(:tGLOBALIDENT)
when input.scan(/@[a-zA-Z_]\w*/)
new_token(:tIVAR, input.matched.to_sym)
diff --git a/lib/rbs/parser.y b/lib/rbs/parser.y
index 5aba4f12f..c7dfc73ac 100644
--- a/lib/rbs/parser.y
+++ b/lib/rbs/parser.y
@@ -1708,7 +1708,7 @@ def next_token
new_token(:tUKEYWORD, input.matched.chop.to_sym)
when input.scan(/[A-Z]\w*[?!]:/)
new_token(:tUKEYWORD_Q_E, input.matched.chop.to_sym)
- when input.scan(/\$[A-Za-z_]\w*/)
+ when input.scan(/\$([A-Za-z_]\w*|[~*$?!@\/\\;,.=:<>"&`'+]|\d+|-[0-9_A-Za-z])/)
new_token(:tGLOBALIDENT)
when input.scan(/@[a-zA-Z_]\w*/)
new_token(:tIVAR, input.matched.to_sym)