diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb
index 7639a901df..b838a78db7 100755
--- a/ext/ripper/tools/preproc.rb
+++ b/ext/ripper/tools/preproc.rb
@@ -45,7 +45,7 @@ def prelude(f, out)
   while line = f.gets
     case line
     when /\A%%/
-      out << '%%' << $/
+      out << "%%\n"
       return
     when /\A%token/
       out << line.sub(/<\w+>/, '<val>')
@@ -79,15 +79,15 @@ def grammar(f, out)
   while line = f.gets
     case line
     when %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/>
-      out << DSL.new($2, ($1 || "").split(",")).generate << $/
+      out << DSL.new($2, ($1 || "").split(",")).generate << "\n"
     when %r</\*%%%\*/>
-      out << '#if 0' << $/
+      out << "#if 0\n"
     when %r</\*%>
-      out << '#endif' << $/
+      out << "#endif\n"
     when %r<%\*/>
-      out << $/
+      out << "\n"
     when /\A%%/
-      out << '%%' << $/
+      out << "%%\n"
       return
     else
       out << line
diff --git a/parse.y b/parse.y
index 0edbc565a4..fe28fd2f1c 100644
--- a/parse.y
+++ b/parse.y
@@ -8360,17 +8360,21 @@ parse_gvar(struct parser_params *p, const enum lex_state_e last_state)
 	pushback(p, c);
 	c = '_';
 	/* fall through */
+      case '/':         /* $/: input record separator */
+      case '\\':        /* $\: output record separator */
+      case ';':         /* $;: field separator */
+      case ',':         /* $,: output field separator */
+      case '.':         /* $.: last read line number */
+        if (c != '_' && strcmp(p->ruby_sourcefile, "-e")) {
+            rb_warn1("global variable $%c is deprecated", WARN_I(c));
+        }
+        /* fall through */
       case '~':		/* $~: match-data */
       case '*':		/* $*: argv */
       case '$':		/* $$: pid */
       case '?':		/* $?: last status */
       case '!':		/* $!: error string */
       case '@':		/* $@: error position */
-      case '/':		/* $/: input record separator */
-      case '\\':		/* $\: output record separator */
-      case ';':		/* $;: field separator */
-      case ',':		/* $,: output field separator */
-      case '.':		/* $.: last read line number */
       case '=':		/* $=: ignorecase */
       case ':':		/* $:: load path */
       case '<':		/* $<: reading filename */
diff --git a/template/encdb.h.tmpl b/template/encdb.h.tmpl
index 06afb5dbe1..b3bd54548a 100644
--- a/template/encdb.h.tmpl
+++ b/template/encdb.h.tmpl
@@ -58,7 +58,7 @@ encdirs.each do |encdir|
           else
             name = $1
           end
-          check_duplication(defs, $1, fn, $.)
+          check_duplication(defs, $1, fn, f.lineno)
           next if BUILTIN_ENCODINGS[name]
           encodings << $1
           count += 1
@@ -71,18 +71,18 @@ encdirs.each do |encdir|
           when /^ENC_REPLICATE\(\s*"([^"]+)"\s*,\s*"([^"]+)"/
             raise ArgumentError,
             '%s:%d: ENC_REPLICATE: %s is not defined yet. (replica %s)' %
-              [fn, $., $2, $1] unless defs[$2.upcase]
+              [fn, f.lineno, $2, $1] unless defs[$2.upcase]
             count += 1
           when /^ENC_ALIAS\(\s*"([^"]+)"\s*,\s*"([^"]+)"/
             raise ArgumentError,
             '%s:%d: ENC_ALIAS: %s is not defined yet. (alias %s)' %
-              [fn, $., $2, $1] unless defs[$2.upcase]
+              [fn, f.lineno, $2, $1] unless defs[$2.upcase]
           when /^ENC_DUMMY\w*\(\s*"([^"]+)"/
             count += 1
           else
             next
           end
-          check_duplication(defs, $1, fn, $.)
+          check_duplication(defs, $1, fn, f.lineno)
           lines << line.sub(/;.*/m, "").chomp + ";" if line
         end
       end
diff --git a/template/transdb.h.tmpl b/template/transdb.h.tmpl
index 16565dd638..990a8639d0 100644
--- a/template/transdb.h.tmpl
+++ b/template/transdb.h.tmpl
@@ -44,9 +44,9 @@ transdirs.each do |transdir|
           from_to = "%s to %s" % [$1, $2]
           if converters[from_to]
             raise ArgumentError, '%s:%d: transcode "%s" is already registered at %s:%d' %
-            [path, $., from_to, *converters[from_to].values_at(3, 4)]
+            [path, f.lineno, from_to, *converters[from_to].values_at(3, 4)]
           else
-            converters[from_to] = [$1, $2, fn[0..-3], path, $.]
+            converters[from_to] = [$1, $2, fn[0..-3], path, f.lineno]
             converter_list << from_to
           end
         end
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index f0a22903b1..8e35c6cf4c 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -605,6 +605,20 @@ def test_unassignable
     end
   end
 
+  def test_deprecated_global_variable
+    assert_warn(/global variable \$; is deprecated/) { eval('$;') }
+    assert_warn(/global variable \$, is deprecated/) { eval('$,') }
+    assert_warn(/global variable \$\/ is deprecated/) { eval('$/') }
+    assert_warn(/global variable \$\\ is deprecated/) { eval('$\\') }
+    assert_warn(/global variable \$\. is deprecated/) { eval('$.') }
+
+    assert_no_warning(/global variable \$; is deprecated/) { eval('$;', binding, '-e') }
+    assert_no_warning(/global variable \$, is deprecated/) { eval('$,', binding, '-e') }
+    assert_no_warning(/global variable \$\/ is deprecated/) { eval('$/', binding, '-e') }
+    assert_no_warning(/global variable \$\\ is deprecated/) { eval('$\\', binding, '-e') }
+    assert_no_warning(/global variable \$\. is deprecated/) { eval('$.', binding, '-e') }
+  end
+
   Bug7559 = '[ruby-dev:46737]'
 
   def test_lineno_command_call_quote
