Я пытаюсь сделать терминальный парсер (для комбинатора парсеров) с нуля. Мой подход заключается в использовании regexp-match-positions*
во входной строке, и если шаблон найден в первой позиции, мы выводим разделенную строку.
Это то, что у меня есть, до сих пор:
#lang racket/base
(require racket/match)
(define (make-terminal-parser pattern)
(define (regexp-match-from-start pattern input)
(match (regexp-match-positions* pattern input)
[(list (cons 0 x) ...)
(let ([index (car x)])
(values (substring input 0 index)
(substring input index)))]
[_ (error "Not found!")]))
(lambda (input)
(regexp-match-from-start pattern input)))
(define ALPHA (make-terminal-parser #rx"[a-zA-Z]"))
(ALPHA "hello")
Мой ALPHA
, похоже, не работает, и я думаю, что это из-за того, что сопоставление с образцом ни к чему не приравнивается. В REPL (regexp-match-positions* #rx"[a-zA-Z]" "hello")
выводит то, что я ожидал ('((0 . 1) (1 . 2) etc.)
), поэтому я действительно не понимаю, почему это не соответствует (list (cons 0 x) ...)
. Если я изменю регулярное выражение на #rx"h"
, оно правильно разделит строку; но, очевидно, это слишком конкретно.
(В соответствующей заметке: я не понимаю, почему мне нужно (car x)
, чтобы получить фактическое значение индекса из совпадающих минусов.)