(input)
| 2492 | |
| 2493 | // 解析规则 |
| 2494 | function parseRule(input) { |
| 2495 | // 分析器 |
| 2496 | class Tokenizer { |
| 2497 | constructor(input) { |
| 2498 | this.input = input |
| 2499 | this.position = 0 |
| 2500 | this.tokens = [] |
| 2501 | } |
| 2502 | |
| 2503 | isWhitespace(char) { |
| 2504 | return /\s/.test(char) |
| 2505 | } |
| 2506 | |
| 2507 | isDelimiter(char) { |
| 2508 | return ['(', ')', ','].includes(char) |
| 2509 | } |
| 2510 | |
| 2511 | tokenize() { |
| 2512 | // console.log('=== 开始词法分析 ===') |
| 2513 | while (this.position < this.input.length) { |
| 2514 | let currentChar = this.input[this.position] |
| 2515 | |
| 2516 | if (this.isWhitespace(currentChar)) { |
| 2517 | this.position++ |
| 2518 | continue |
| 2519 | } |
| 2520 | |
| 2521 | if (currentChar === '(') { |
| 2522 | this.tokens.push({ type: 'LPAREN', value: '(' }) |
| 2523 | // console.log(`Token: LPAREN '(' at position ${this.position}`) |
| 2524 | this.position++ |
| 2525 | continue |
| 2526 | } |
| 2527 | |
| 2528 | if (currentChar === ')') { |
| 2529 | this.tokens.push({ type: 'RPAREN', value: ')' }) |
| 2530 | // console.log(`Token: RPAREN ')' at position ${this.position}`) |
| 2531 | this.position++ |
| 2532 | continue |
| 2533 | } |
| 2534 | |
| 2535 | if (currentChar === ',') { |
| 2536 | this.tokens.push({ type: 'COMMA', value: ',' }) |
| 2537 | // console.log(`Token: COMMA ',' at position ${this.position}`) |
| 2538 | this.position++ |
| 2539 | continue |
| 2540 | } |
| 2541 | |
| 2542 | // 收集单词 |
| 2543 | let start = this.position |
| 2544 | while ( |
| 2545 | this.position < this.input.length && |
| 2546 | !this.isWhitespace(this.input[this.position]) && |
| 2547 | !this.isDelimiter(this.input[this.position]) |
| 2548 | ) { |
| 2549 | this.position++ |
| 2550 | } |
| 2551 | let value = this.input.slice(start, this.position) |
no test coverage detected