Subject: bug#61436: Emacs Freezing With Java Files

From: Alan Mackenzie <[email-masked]>
Date: Mon, 16 Oct 2023 14:05:20 +0000

Hello, Bob.

On Sun, Oct 15, 2023 at 06:20:15 -0400, Robert Weiner wrote:
> Hi Alan:

> Would be great if you can improve those two regexps.  The only
> requirement is that they be able to recognize all defuns in the two
> languages as best a regexp can, so that the whole defun can be
> selected based on finding the opening brace regardless of coding
> style.

So far, I've only looked at the Java regexp.  It had some serious
deficiencies, notably:
(i) It used "\\s-" (space syntax) a lot.  This fails to mach \n, which in
Java mode has comment-end syntax.
(ii) The bit for the parenthesis expression was in an optional part of
the regexp with the result that it would match "almost anything" rather
than a defun start.

In the following regexp these faults are fixed.  Additionally, I've
included more modifiers (things like private, volatile) which Java seems
to have gathered over the years.  I've also attempted to match generic
functions.  I don't know how well this will work out.

Here's the regexp.  Would people please try it out and let me know how
well it works.  

(defconst java-defun-prompt-regexp
  (let ((space* "[ \t\n\r\f]*")
        (space+ "[ \t\n\r\f]+")
        (modifier*
         (concat "\\(?:"
                 (regexp-opt '("abstract" "const" "default" "final" "native"
                               "private" "protected" "public" "static"
                               "strictfp" "synchronized" "threadsafe"
                               "transient" "volatile")
                             'words)    ; Compatible with XEmacs
                 space+ "\\)*"))
        (ids-with-dots "[_$a-zA-Z][_$.a-zA-Z0-9]*")
        (ids-with-dot-\[\] "[[_$a-zA-Z][][_$.a-zA-Z0-9]*")
        (paren-exp "([^);{}]*)")
        (generic-exp "<[^(){};]*>"))
    (concat "^[ \t]*"
            modifier*
            "\\(?:" generic-exp space* "\\)?"
            ids-with-dot-\[\] space+                ; first part of type
            "\\(?:" ids-with-dot-\[\] space+ "\\)?" ; optional second part of type.
            "\\(?:[_a-zA-Z][^][ \t:;.,{}()=<>]*"    ; defun name
                "\\|" ids-with-dot*
            "\\)" space*
            paren-exp
            "\\(?:" space* "]\\)*"      ; What's this for?
            "\\(?:" space* "\\<throws\\>" space* ids-with-dot-\[\]s*
                  "\\(?:," space* ids-with-dot-\[\]s* "\\)*"
            "\\)?"
            space*)))

> Thanks.

> -- Bob

> > On Oct 14, 2023, at 8:41 PM, Alan Mackenzie <[email-masked]> wrote:

[ .... ]

> > Mats, I'm willing to work on that regular expression, and also the one
> > for C++.  As I mentioned earlier, I've got some tools which work on
> > regexps, in particular pp-regexp, which prints a regexp more readably on
> > several lines, and fix-re, which rewrites a regexp when it is
> > ill-conditioned in certain ways.

> > I foresee reverse engineering the regexps into more readable forms built
> > up by concatenating basic blocks.  For example for the java regexp I
> > would define

> >    (defconst id "[a-zA-Z][][_$.a-zA-Z0-9]*")

> > , and use this id in a largish concat form.

> > I'm also willing to share pp-regexp and fix-re with you(r team), if that
> > might help, on the understanding that neither is of release quality.

-- 
Alan Mackenzie (Nuremberg, Germany).