В Racket, как мне настроить лексер для распознавания идентификатора с комбинацией всех цифр и букв A-Z И a-z

#string #racket #lexer

#строка #racket #лексер

Вопрос:

Мой лексер в настоящее время выглядит следующим образом:

 #lang racket
(require parser-tools/lex)

(define testLexer
  (lexer
    ["foo" (list 'FOO lexeme)]
    ["bar" (list 'BAR lexeme)]
    [(repetition 1  inf.0 (char-range #a #z)) (list 'ID lexeme)]
    [whitespace (testLexer input-port)]))
  

Символы ‘ID работают со всеми комбинациями строчных букв и цифр. Я хочу, чтобы он работал и с прописными буквами.Я пытался:

 [(repetition 1  inf.0 (char-range #a #z) (char-range #A #Z) (list 'ID lexeme)]
  

но поскольку повторение принимает только два аргумента, я не могу ввести третий.

Должен быть какой-то простой способ включить также буквы верхнего регистра.

редактировать: Кроме того, если есть какой-то способ убедиться, что идентификатор начинается с буквы (не числа), это тоже было бы неплохо

Ответ №1:

Использование union смотрите больше в разделе 1.1. в документации lexer

 #lang racket
(require parser-tools/lex)

(define testLexer
  (lexer
    ["foo"                (list 'FOO lexeme)]
    ["bar"                (list 'BAR lexeme)]
    [(repetition 1  inf.0 (union (char-range #a #z) (char-range #A #Z))) (list 'ID lexeme)]
    [whitespace           (testLexer input-port)]))

(testLexer (open-input-string "AbCDe"))
  

Комментарии:

1. Спасибо, это то, что я искал. Единственное, что еще нужно, это как мне заставить его разрешать только идентификаторы, начинающиеся с буквы? Прямо сейчас, я думаю, что 1aBc3XyZ8 сработал бы, например.

2. Нет — прямо сейчас никакие цифры не разрешены. Поскольку цифры лежат за пределами диапазона от А до я.

3. Я вижу. Итак, если бы мне тоже нужны были цифры, я мог бы сделать (union (char-range # a # z) (char-range # A # Z) (char-range # 0 # 9))? В таком случае, как бы мне ограничить его только буквами в качестве первого символа?

4. Вы бы использовали concatenation . Пример: (contenation alfa (repetition 0 inf.0 alfa-or-digit) где alfa это (union (char-range #a #z) (char-range #A #Z)) и alfa-or-digit это (union (char-range #a #z) (char-range #A #Z) (char-range # #9))

5. Отлично, я думаю, я начинаю понимать, как обращаться с подобными строками в лексерах. Огромное спасибо.