Skip to content

Commit 742216c

Browse files
committed
Add Vim NFA regexp engine dump log helpers
1 parent 82276e2 commit 742216c

4 files changed

Lines changed: 119 additions & 8 deletions

File tree

clj/src/vim_clojure_static/generate.clj

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
;; Joel Holdbrooks <cjholdbrooks@gmail.com>
33

44
(ns vim-clojure-static.generate
5-
(:require [clojure.string :as string]
6-
[clojure.set :as set]))
5+
(:require [clojure.java.shell :as shell]
6+
[clojure.set :as set]
7+
[clojure.string :as string]))
78

89
;;
910
;; Helpers
@@ -221,7 +222,18 @@
221222
(fmt "script=" :script)
222223
(fmt "block=" :block)])))
223224

225+
(defn vim-nfa-dump
226+
"Run a patched version of Vim compiled with -DDEBUG on a new file containing
227+
buffer, then move the NFA log to log-path. The patch is located at
228+
vim/custom-nfa-log.patch"
229+
[vim-path buffer log-path]
230+
(let [file "tmp/nfa-test-file.clj"]
231+
(spit file buffer)
232+
(shell/sh vim-path "-u" "NONE" "-N" "-S" "vim/test-runtime.vim" file)
233+
(shell/sh "mv" "nfa_regexp.log" log-path)))
234+
224235
(comment
236+
;; Generate the vim literal definitions for pasting into the runtime files.
225237
(spit "tmp/clojure-defs.vim"
226238
(str generation-comment
227239
clojure-version-comment
@@ -239,6 +251,23 @@
239251
vim-unicode-category-char-classes
240252
vim-unicode-script-char-classes
241253
vim-unicode-block-char-classes))
242-
(spit "tmp/clojure-regexp-properties.clj"
254+
(spit "tmp/nfa-test-file.clj"
243255
comprehensive-clojure-character-property-regexps)
256+
;; Create regexp engine dump files and compare number of operations.
257+
(let [syn-path "../syntax/clojure.vim"
258+
orig-syn-buf (slurp syn-path)
259+
vim-path (or (System/getenv "VIMDEBUG") "vim")
260+
buf (format "#\"\\p{%s}\"\n" "Ll")
261+
buf-hash (hash buf)]
262+
(try
263+
(mapv (fn [path]
264+
(let [syn-buf (slurp path)
265+
syn-hash (hash syn-buf)
266+
log-path (format "tmp/debug:%d:%d.log" buf-hash syn-hash)]
267+
(spit syn-path syn-buf)
268+
(vim-nfa-dump vim-path buf log-path)
269+
(count (re-seq #"\n" (slurp log-path)))))
270+
["../syntax/clojure.vim" "tmp/altsyntax.vim"])
271+
(finally
272+
(spit syn-path orig-syn-buf))))
244273
)

clj/src/vim_clojure_static/test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
[file & lines]
1818
(io/make-parents file)
1919
(spit file (string/join \newline lines))
20-
(shell/sh "vim" "-u" "NONE" "-N" "-S" "vim/syn-id-names.vim" file)
20+
(shell/sh "vim" "-u" "NONE" "-N" "-S" "vim/test-runtime.vim" file)
2121
;; The last line of the file will contain valid EDN
2222
(into {} (map (fn [l ids] [l (mapv keyword ids)])
2323
lines

clj/vim/custom-nfa-log.patch

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
commit 4f385fb359c5d51bd4a079ffd35bbcc1c6676c4a (HEAD, github/custom-nfa-log, custom-nfa-log)
2+
Author: guns <self@sungpae.com>
3+
Date: 9 hours ago
4+
5+
Add custom NFA logging to nfa_regexp.log
6+
7+
The goal is to get a ballpark estimate of the number of steps the regexp
8+
engine undertakes in a session. One line of logging is done:
9+
10+
* Start of nfa_regmatch()
11+
* For each character considered
12+
* For each state of a character considered
13+
14+
Vimm should be compiled with -DDEBUG; if the NFA engine state graphs are
15+
desired, then also use -DINCLUDE_NFA_DUMP.
16+
17+
This branch can also be found at:
18+
19+
https://github.com/guns/vim/tree/custom-nfa-log
20+
---
21+
src/regexp_nfa.c | 20 +++++++++++++++++---
22+
1 file changed, 17 insertions(+), 3 deletions(-)
23+
24+
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
25+
index 738ac3b..c39f94d 100644
26+
--- a/src/regexp_nfa.c
27+
+++ b/src/regexp_nfa.c
28+
@@ -24,9 +24,18 @@
29+
#ifdef DEBUG
30+
# define NFA_REGEXP_ERROR_LOG "nfa_regexp_error.log"
31+
# define ENABLE_LOG
32+
-# define NFA_REGEXP_DUMP_LOG "nfa_regexp_dump.log"
33+
-# define NFA_REGEXP_RUN_LOG "nfa_regexp_run.log"
34+
-# define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log"
35+
+# ifdef INCLUDE_NFA_DUMP
36+
+# define NFA_REGEXP_DUMP_LOG "/dev/null"
37+
+# else
38+
+# define NFA_REGEXP_DUMP_LOG "nfa_regexp.log"
39+
+# endif
40+
+# define NFA_REGEXP_RUN_LOG "/dev/null"
41+
+# define NFA_REGEXP_DEBUG_LOG "/dev/null"
42+
+# define LOG(fmt, ...) do { \
43+
+ FILE *log = fopen("nfa_regexp.log", "a"); \
44+
+ fprintf(log, fmt, __VA_ARGS__); \
45+
+ fclose(log); \
46+
+} while (0)
47+
#endif
48+
49+
enum
50+
@@ -5043,6 +5052,8 @@ nfa_regmatch(prog, start, submatch, m)
51+
goto theend;
52+
53+
#ifdef ENABLE_LOG
54+
+ LOG("START nfa_regmatch: alloc=%d pattern=\"%s\"\n", size*2, prog->pattern);
55+
+
56+
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
57+
if (log_fd != NULL)
58+
{
59+
@@ -5129,6 +5140,8 @@ nfa_regmatch(prog, start, submatch, m)
60+
nextlist->id = nfa_listid + 1;
61+
62+
#ifdef ENABLE_LOG
63+
+ LOG("# states=%d reginput=\"%s\"\n", thislist->n, reginput);
64+
+
65+
fprintf(log_fd, "------------------------------------------\n");
66+
fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput);
67+
fprintf(log_fd, ">>> Advanced one character ... Current char is %c (code %d) \n", curc, (int)curc);
68+
@@ -5161,6 +5174,7 @@ nfa_regmatch(prog, start, submatch, m)
69+
fprintf(debug, "%s, ", code);
70+
#endif
71+
#ifdef ENABLE_LOG
72+
+ LOG("## computing nextlist: code=\"%s\"\n", code);
73+
{
74+
int col;
75+
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
execute 'set rtp=' . expand('%:p:h:h:h') . ',$VIMRUNTIME'
44
filetype plugin on
55
syntax on
6+
set synmaxcol=0
67
setfiletype clojure
78

8-
function! s:append_syn_id_names()
9+
if !exists('g:testing')
10+
let g:testing = 1
11+
endif
12+
13+
function! s:syn_id_names()
914
let names = []
1015
for lnum in range(1, line('$'))
1116
let f = 'synIDattr(synID(' . lnum . ', v:val, 0), "name")'
1217
call add(names, map(range(1, virtcol([lnum, '$']) - 1), f))
1318
endfor
14-
" Changing the quotes will make this valid EDN
15-
call append(line('$'), tr(string(names), "'", '"'))
19+
return names
1620
endfunction
1721

18-
call s:append_syn_id_names() | write | quitall!
22+
if g:testing
23+
" Changing the quotes will make this valid EDN
24+
call append(line('$'), tr(string(s:syn_id_names()), "'", '"')) | write | quitall!
25+
endif

0 commit comments

Comments
 (0)