37
37
; ;;; Requirements
38
38
39
39
(eval-when-compile
40
- (require 'rx )) ; `rx'
40
+ (require 'rx )) ; `rx' , `rx-define'
41
41
42
42
43
43
; ;;; Customization
69
69
; ;;; Font Locking
70
70
71
71
(defvar bnf-font-lock-keywords
72
- `(
73
- ; ; LHS nonterminals may be preceded
72
+ `(; ; LHS nonterminals may be preceded
74
73
; ; by an unlimited number of spaces
75
74
(,(rx (and line-start
76
75
(0+ space)
88
87
(0+ space)))
89
88
1 font-lock-builtin-face )
90
89
; ; “may expand into” symbol
91
- (,(rx (and symbol-start
90
+ (,(rx (and " >"
91
+ (0+ (in " \t\n " ))
92
92
(group " ::=" )
93
- symbol-end ))
93
+ (0+ space) ))
94
94
1 font-lock-constant-face )
95
95
; ; Alternatives
96
96
(,(rx (and (0+ space)
97
- symbol-start
98
97
(group " |" )
99
- symbol-end
100
98
(0+ space)))
101
99
1 font-lock-warning-face ))
102
100
" Font lock BNF keywords for BNF Mode." )
106
104
107
105
(defvar bnf-mode-syntax-table
108
106
(let ((table (make-syntax-table )))
109
- ; ; FIXME: "_" doesn't mean "symbol" but "symbol constituent".
110
- ; ; I.e. the settings below mean that Emacs will consider "a:b=(c" as one
111
- ; ; symbol (aka "identifier") which can be seen if you try to C-M-f and
112
- ; ; C-M-b to move by sexps.
113
-
114
- ; ; Treat ::= as sequence of symbols
115
- (modify-syntax-entry ?\: " _" table)
116
- (modify-syntax-entry ?\= " _" table)
117
-
118
- ; ; Treat | as a symbol
119
- (modify-syntax-entry ?\| " _" table)
107
+ ; ; Treat :, =, and | as punctuation
108
+ (modify-syntax-entry ?\: " ." table)
109
+ (modify-syntax-entry ?\= " ." table)
110
+ (modify-syntax-entry ?\| " ." table)
120
111
121
112
; ; In BNF there are no strings
122
- ; ; so treat ' and " as symbols
123
- (modify-syntax-entry ?\" " _ " table)
124
- (modify-syntax-entry ?\' " _ " table)
113
+ ; ; so treat ' and " as punctuation
114
+ (modify-syntax-entry ?\" " . " table)
115
+ (modify-syntax-entry ?\' " . " table)
125
116
126
117
; ; In BNF there are no grouping
127
118
; ; brackets except angle ones
128
- (modify-syntax-entry ?\( " _" table)
129
- (modify-syntax-entry ?\) " _" table)
130
- (modify-syntax-entry ?\{ " _" table)
131
- (modify-syntax-entry ?\} " _" table)
132
- (modify-syntax-entry ?\[ " _" table)
133
- (modify-syntax-entry ?\] " _" table)
134
-
135
- ; ; Group angle brackets
136
- (modify-syntax-entry ?\< " (>" table)
137
- (modify-syntax-entry ?\> " )<" table)
119
+ (modify-syntax-entry ?\( " ." table)
120
+ (modify-syntax-entry ?\) " ." table)
121
+ (modify-syntax-entry ?\{ " ." table)
122
+ (modify-syntax-entry ?\} " ." table)
123
+ (modify-syntax-entry ?\[ " ." table)
124
+ (modify-syntax-entry ?\] " ." table)
125
+
126
+ ; ; Treat angle brackets as punctuation by default.
127
+ ; ; We'll ajust them later, in `bnf--syntax-propertize' .
128
+ (modify-syntax-entry ?\< " ." table)
129
+ (modify-syntax-entry ?\> " ." table)
138
130
139
131
; ; Comments are begins with “;” and ends with “\n”
140
132
(modify-syntax-entry ?\; " <" table)
143
135
table)
144
136
" Syntax table in use in `bnf-mode' buffers." )
145
137
138
+ (defconst bnf--syntax-propertize
139
+ (syntax-propertize-rules
140
+ ; ; Group angle brackets
141
+ (" \\ (<\\ )\\ ([^<>]*\\ )\\ (>\\ )"
142
+ (1 " (>" )
143
+ (3 " )<" )))
144
+ " Syntax propertization rules for `bnf-mode' .
145
+
146
+ These rules assign appropriate syntax properties to specific
147
+ sequences in BNF grammar files, ensuring correct syntax
148
+ highlighting and code navigation in `bnf-mode' buffers." )
149
+
146
150
147
151
; ;;; Initialization
148
152
@@ -162,6 +166,9 @@ Turning on BNF Mode calls the value of `prog-mode-hook' and then of
162
166
(setq-local comment-end " " )
163
167
(setq-local comment-start-skip " \\ (?:\\ (\\ W\\ |^\\ );+\\ )\\ s-+" )
164
168
169
+ ; ; Enable dynamic syntax properties for accurate parsing
170
+ (setq-local syntax-propertize-function bnf--syntax-propertize)
171
+
165
172
; ; Font locking
166
173
(setq font-lock-defaults
167
174
'(
0 commit comments