-#ifdef MSDOS
-      strlwr (spec_file_prefix);
-#endif /* MSDOS */
-      short_base_name = xstrdup (spec_file_prefix);
-      base_name = XMALLOC (char,
-                          strlen (short_base_name) + strlen (EXT_TAB) + 1);
-      stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
-
-      /* Computes the extensions from the garmmar file name.  */
-      ext_index = get_extension_index (infile);
-      /* If the initial segment of extension contains a 'y' or a 'Y', I assume
-         that it is a yacc or bison grammar file.  */
-      if (ext_index)
-       ext_index = (strspn (infile + ext_index + 1, "yY")) ? ext_index : 0;
-      if (ext_index)
-       compute_exts_from_gf (infile + ext_index);
-
-      return;
-    }
-
-  /* If neither -o nor --file-prefix were specified, and the input
-     file is foo.y, BASE_NAME is `foo.tab', and SHORT_BASE_NAME is
-     `foo'.
-
-     If --yacc is used, do as if the input file was `y.y'.  */
-  {
-    const char *name_base = yacc_flag ? "y.y" : infile;
-
-    /* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any.  */
-
-    base_length = strlen (name_base);
-
-    ext_index = get_extension_index (name_base);
-    /* If the initial segment of extension contains a 'y' or a 'Y', I assume
-       that it is a yacc or bison grammar file.  */
-    if (ext_index)
-      ext_index = (strspn (name_base + ext_index + 1, "yY")) ? ext_index : 0;
-    if (ext_index)
-      {
-       base_length -= strlen (name_base + ext_index);
-       compute_exts_from_gf (name_base + ext_index);
-      }
-
-    short_base_length = base_length;
-    short_base_name = strndup (name_base, short_base_length);
-
-    base_name = XMALLOC (char,
-                        strlen (short_base_name) + strlen (EXT_TAB) + 1);
-    stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
+      file_name_split (grammar_file, &base, &tab, &ext);
+
+      if (spec_file_prefix)
+        {
+          /* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'.  */
+          dir_prefix =
+            xstrndup (spec_file_prefix,
+                      last_component (spec_file_prefix) - spec_file_prefix);
+          all_but_tab_ext = xstrdup (spec_file_prefix);
+        }
+      else if (yacc_flag)
+        {
+          /* If --yacc, then the output is `y.tab.c'.  */
+          dir_prefix = xstrdup ("");
+          all_but_tab_ext = xstrdup ("y");
+        }
+      else
+        {
+          /* Otherwise, ALL_BUT_TAB_EXT is computed from the input
+             grammar: `foo/bar.yy' => `bar'.  */
+          dir_prefix = xstrdup ("");
+          all_but_tab_ext =
+            xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
+        }
+
+      if (language->add_tab)
+        all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
+      else
+        all_but_ext = xstrdup (all_but_tab_ext);