2015-05-15 2 views
1

Я новичок в Racket, но очень взволнован. Я работал над написанием простого лексера для заголовков WWW-Authenticate. Я очень хорошо разбираюсь в лексинге, но теперь хочу изменить свой результат.Racket lexer - возвратный список минусов

#lang racket 

(require parser-tools/lex) 
(require (prefix-in : parser-tools/lex-sre)) 

(define in (open-input-string "MsRtcOAuth href=\"https://foo.com/WebTicket/oauthtoken\",grant_type=\"urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password\", Bearer trusted_issuers=\"\", client_id=\"00000004-0000-0ff1-ce00-000000000000\"")) 


(define key-lexer 
    (lexer 

    ;anything not an "=" 
    [(:* (char-complement #\=)) 
    ;=> 
    (cons `(KEY, lexeme) 
     (equals-lexer input-port))] 

    ;eof 
    [(eof) '()])) 

(define equals-lexer 
    (lexer 
    [#\= 
    ;=> 
    (value-lexer input-port)] 

    ;eof 
    [(eof) '()])) 

(define value-lexer 
    (lexer 
    ;values are anything between two " " 
    [(concatenation #\" (:* (char-complement #\")) #\") 
    ;=> 
    (cons `(VAL, lexeme) 
      (comma-lexer input-port))] 

    ;eof 
    [(eof) '()])) 

(define comma-lexer 
    (lexer 
    [(concatenation (:* whitespace) #\, (:* whitespace)) 
    ;=> 
    (key-lexer input-port)] 

    ;eof 
    [(eof) '()])) 

(key-lexer in) 

Прямо сейчас, результат выглядит следующим образом:

'((KEY "MsRtcOAuth href") 
(VAL "\"https://foo.com/WebTicket/oauthtoken\"") 
(KEY "grant_type") 
(VAL "\"urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password\"") 
(KEY "Bearer trusted_issuers") 
(VAL "\"\"") 
(KEY "client_id") 
(VAL "\"00000004-0000-0ff1-ce00-000000000000\"")) 

Что я предпочел бы список пар, похожий на этот:

(("MsRtcOAuth href" . "\"https://foo.com/WebTicket/oauthtoken\"") 
("grant_type" . "\"urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password\"") etc... 

Любая помощь или указатели значительно оценили. Благодаря!

ответ

1

Вот один из способов превратить то, что вы попали в то, что вы хотите:

(define (prettify key-val-pairs) 
    (match key-val-pairs 
    [(list (list 'KEY key) (list 'VAL val) more ...) 
    (cons (list key val) 
      (prettify more))] 
    [_ key-val-pairs])) 


(prettify 
'((KEY "MsRtcOAuth href") 
    (VAL "\"https://foo.com/WebTicket/oauthtoken\"") 
    (KEY "grant_type") 
    (VAL "\"urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password\"") 
    (KEY "Bearer trusted_issuers") 
    (VAL "\"\"") 
    (KEY "client_id") 
    (VAL "\"00000004-0000-0ff1-ce00-000000000000\""))) 

Выход:

'(("MsRtcOAuth href" "\"https://foo.com/WebTicket/oauthtoken\"") 
    ("grant_type" "\"urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password\"") 
    ("Bearer trusted_issuers" "\"\"") 
    ("client_id" "\"00000004-0000-0ff1-ce00-000000000000\"")) 
+0

это действительно здорово. Есть ли способ сделать это внутри функции Лексинга? Должен ли я использовать библиотеку разбора? –

+0

lexer производит значения в порядке появления токенов. Любое переупорядочение обычно выполняется в синтаксическом анализаторе. – soegaard

+0

В этом случае нет необходимости использовать библиотеку разбора. Функция prettify является парсером. – soegaard

Смежные вопросы