mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 20:35:24 +00:00
60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
|
|
import { ExternalTokenizer } from "@lezer/lr";
|
||
|
|
import { negate } from "./parser.terms";
|
||
|
|
|
||
|
|
// External tokenizer for negation
|
||
|
|
// Only tokenizes `-` as negate when followed by a prefix keyword or `(`
|
||
|
|
export const negateToken = new ExternalTokenizer((input) => {
|
||
|
|
if (input.next !== 45 /* '-' */) return; // Not a dash
|
||
|
|
|
||
|
|
const startPos = input.pos;
|
||
|
|
|
||
|
|
// Look ahead to see what follows the dash
|
||
|
|
input.advance();
|
||
|
|
|
||
|
|
// Skip whitespace
|
||
|
|
let ch = input.next;
|
||
|
|
while (ch === 32 || ch === 9 || ch === 10) {
|
||
|
|
input.advance();
|
||
|
|
ch = input.next;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if followed by opening paren
|
||
|
|
if (ch === 40 /* '(' */) {
|
||
|
|
input.acceptToken(negate, -input.pos + startPos + 1); // Accept just the dash
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if followed by a prefix keyword (by checking for keyword followed by colon)
|
||
|
|
// Look ahead until we hit a delimiter or colon
|
||
|
|
const checkPos = input.pos;
|
||
|
|
let foundColon = false;
|
||
|
|
|
||
|
|
// Look ahead until we hit a delimiter or colon
|
||
|
|
while (ch >= 0) {
|
||
|
|
if (ch === 58 /* ':' */) {
|
||
|
|
foundColon = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// Hit a delimiter (whitespace, paren, or quote) - not a prefix keyword
|
||
|
|
if (ch === 32 || ch === 9 || ch === 10 || ch === 40 || ch === 41 || ch === 34) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
input.advance();
|
||
|
|
ch = input.next;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Reset position
|
||
|
|
while (input.pos > checkPos) {
|
||
|
|
input.advance(-1);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (foundColon) {
|
||
|
|
// It's a prefix keyword, accept as negate
|
||
|
|
input.acceptToken(negate, -input.pos + startPos + 1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Otherwise, don't tokenize as negate (let word handle it)
|
||
|
|
});
|
||
|
|
|