Skip to content

Commit f54b535

Browse files
committed
ohm-js: use Unicode letter properties in isSyntactic (#611)
1 parent 47da2c7 commit f54b535

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

doc/releases/ohm-js-18.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ if (result.failed()) {
147147
}
148148
```
149149

150+
## Breaking changes
151+
152+
### Syntactic vs. lexical rule classification
153+
154+
`isSyntactic()` now looks at the first _letter_ in the rule name — if it's an upper case letter, the rule is syntactic, otherwise it's lexical. In v17, we compared `firstChar === firstChar.toUpperCase()`, which incorrectly classified rule names starting with non-letter characters (e.g. `_`, digits) as syntactic. This now means that a rule named `_ident` is now treated as lexical, not syntactic.
155+
150156
## Removed APIs
151157

152158
The following v17 APIs do not exist in v18 (yet):

packages/ohm-js/src/common.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,13 @@ export function copyWithoutDuplicates(array) {
101101
return noDuplicates;
102102
}
103103

104+
// Changed in v18 to use Unicode letter properties, matching the compiler.
105+
// Previously, this compared `firstChar === firstChar.toUpperCase()`, which
106+
// incorrectly returned true for non-letter characters (e.g. '_', digits).
104107
export function isSyntactic(ruleName) {
105-
const firstChar = ruleName[0];
106-
return firstChar === firstChar.toUpperCase();
108+
const firstLetter = ruleName.match(/\p{L}/u)?.[0];
109+
if (!firstLetter) return false;
110+
return /\p{Lu}/u.test(firstLetter);
107111
}
108112

109113
export function isLexical(ruleName) {

0 commit comments

Comments
 (0)