Skip to content

Commit eee63ca

Browse files
committed
Rework Symbol Classification
1 parent a8fd3f4 commit eee63ca

File tree

3 files changed

+72
-42
lines changed

3 files changed

+72
-42
lines changed

NEWS

+32-7
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,45 @@ This file is about changes in BNF Mode.
99
** Incompatible changes.
1010
*** Dropped support for GNU Emacs < 27.1.
1111
BNF Mode no longer support GNU Emacs versions older than 27.1. This
12-
change allows to use modern APIs, like 'rx-define', and simplifies CI
12+
change allows to use modern APIs, like `rx-define', and simplifies CI
1313
workflows by not having to accommodate outdated Emacs versions. If
1414
you are still using an older version of Emacs or other flavors (e.g.,
1515
XEmacs), please stick with an earlier version of BNF Mode.
1616

1717
*** Removed the 'bnf-rx' macro.
18-
The 'bnf-rx' macro is no longer part of BNF Mode as it's no longer
19-
necessary. BNF Mode now fully utilizes the modern 'rx' API, relying
20-
directly on 'rx-define' for pattern definitions.
18+
The `bnf-rx' macro is no longer part of BNF Mode as it's no longer
19+
necessary. BNF Mode now fully utilizes the modern `rx' API, relying
20+
directly on `rx-define' for pattern definitions.
2121

2222
*** Removed the 'bnf-rx-constituents' constant.
23-
BNF Mode no longer uses the 'bnf-rx-constituents' constant. Instead,
24-
it now relies on 'rx-define' to define patterns directly, utilizing
25-
the modern 'rx' API to simplify and streamline pattern definitions.
23+
BNF Mode no longer uses the `bnf-rx-constituents' constant. Instead,
24+
it now relies on `rx-define' to define patterns directly, utilizing
25+
the modern `rx' API to simplify and streamline pattern definitions.
26+
27+
** Syntax Table changes.
28+
*** Improved Syntax Table Handling.
29+
Changed the syntax classification of :, =, and | from symbol
30+
constituents to punctuation characters. This adjustment ensures that
31+
navigation commands like C-M-f and C-M-b work as expected, treating
32+
these characters as separate tokens rather than part of a symbol.
33+
34+
*** Improved Handling of Angle Brackets.
35+
Changed the default syntax classification of < and > to punctuation
36+
characters. Introduced the `bnf--syntax-propertize' constant that
37+
performs a detailed examination of the buffer content. It selectively
38+
reclassifies < and > as angle brackets (delimiter characters) only
39+
when they enclose nonterminal symbols. This approach allows for more
40+
accurate syntax highlighting and parsing, especially in lines where
41+
angle brackets are not part of nonterminals. By defaulting to
42+
punctuation and then dynamically adjusting the syntax properties as
43+
needed, we ensure that angle brackets are correctly interpreted in
44+
various contexts within BNF grammar files.
45+
46+
*** Fixed Incorrect Symbol Classification.
47+
Adjusted the syntax entries for characters like ', ", (, ), {, }, [,
48+
and ] to be treated as punctuation rather than symbols. This change
49+
prevents these characters from being incorrectly grouped with adjacent
50+
symbols, enhancing text manipulation and editing commands.
2651

2752
* BNF Mode 0.4.5
2853
** Tests were migrated from ert-runner to buttercup.

bnf-mode.el

+38-31
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
;;;; Requirements
3838

3939
(eval-when-compile
40-
(require 'rx)) ; `rx'
40+
(require 'rx)) ; `rx', `rx-define'
4141

4242

4343
;;;; Customization
@@ -69,8 +69,7 @@
6969
;;;; Font Locking
7070

7171
(defvar bnf-font-lock-keywords
72-
`(
73-
;; LHS nonterminals may be preceded
72+
`(;; LHS nonterminals may be preceded
7473
;; by an unlimited number of spaces
7574
(,(rx (and line-start
7675
(0+ space)
@@ -88,15 +87,14 @@
8887
(0+ space)))
8988
1 font-lock-builtin-face)
9089
;; “may expand into” symbol
91-
(,(rx (and symbol-start
90+
(,(rx (and ">"
91+
(0+ (in " \t\n"))
9292
(group "::=")
93-
symbol-end))
93+
(0+ space)))
9494
1 font-lock-constant-face)
9595
;; Alternatives
9696
(,(rx (and (0+ space)
97-
symbol-start
9897
(group "|")
99-
symbol-end
10098
(0+ space)))
10199
1 font-lock-warning-face))
102100
"Font lock BNF keywords for BNF Mode.")
@@ -106,35 +104,29 @@
106104

107105
(defvar bnf-mode-syntax-table
108106
(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)
120111

121112
;; 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)
125116

126117
;; In BNF there are no grouping
127118
;; 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)
138130

139131
;; Comments are begins with “;” and ends with “\n”
140132
(modify-syntax-entry ?\; "<" table)
@@ -143,6 +135,18 @@
143135
table)
144136
"Syntax table in use in `bnf-mode' buffers.")
145137

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+
146150

147151
;;;; Initialization
148152

@@ -162,6 +166,9 @@ Turning on BNF Mode calls the value of `prog-mode-hook' and then of
162166
(setq-local comment-end "")
163167
(setq-local comment-start-skip "\\(?:\\(\\W\\|^\\);+\\)\\s-+")
164168

169+
;; Enable dynamic syntax properties for accurate parsing
170+
(setq-local syntax-propertize-function bnf--syntax-propertize)
171+
165172
;; Font locking
166173
(setq font-lock-defaults
167174
'(

test/test-bnf-mode-font-lock.el

+2-4
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,9 @@
6060
"; foo" comment))))
6161

6262
(it "does not mix terminals and nonterminals"
63-
(expect "<stm> ::= <decl>
64-
angle-brackets ::= are-optional"
63+
(expect "<stm> ::= <decl>"
6564
:to-be-fontified-as
66-
'(("stm" function-name "::=" constant "decl" builtin)
67-
("::=" constant))))
65+
'(("stm" function-name "::=" constant "decl" builtin))))
6866

6967
(it "fontifies nonterminals despite the case"
7068
(expect "<RULE> ::= <foo>

0 commit comments

Comments
 (0)