4

文字列からsxml式を作成する単純なパーサーを作成しようとしています。

"This is a [Test]" ===> (item "This is a" (subitem "Test"))

与えられた例の中の角括弧について疑問に思っている人は誰でも、いわゆるライデンの慣習を見るかもしれません。

これは私がこれまでに書いたコードです:

(define my-sequence '("this" "[" "is" "a" "]" "test"))

(define (left-square-bracket? item)
  (or (equal? item "[")
      (eq? item #\x005b)))

(define (right-square-bracket? item)
  (or (equal? item "]")
      (eq? item #\x005d)))

(define (parse-sequence sequence)
  (cond ((null? sequence) '())
        ((left-square-bracket? (car sequence))
         (let ((subsequence (get-subsequence (cdr sequence))))
           (list subsequence)))
        (else
         (cons (car sequence)
               (parse-sequence (cdr sequence))))))

(define (get-subsequence sequence)
  (if (right-square-bracket? (car sequence))
      '()
      (cons (car sequence)
            (get-subsequence (cdr sequence)))))

(parse-sequence my-sequence)歩留まりの評価("this" ("is" "a"))。ネストされた式が作成されましたが、プログラムは最後の項目を評価せずに終了しました"test"。問題は、どうすればからに戻ることができるかということget-subsequenceですparse-sequence

どんな助けでもありがたいです、事前に感謝します!:)

4

2 に答える 2

2

最初の質問に対処するには、複数の値を返す方法:「値」フォームを使用します。これは、内部プロシージャが処理される残りのリストとこれまでの結果の両方を返す実装例です。角かっこを開くと繰り返します。

(define (parse-sequence lst)

  (define (parse-seq lst)
    (let loop ((lst lst) (res null))
      (cond
        ((null? lst) (values null res))
        ((string=? (car lst) "[")
         (let-values ([(lst2 res2) (parse-seq (cdr lst))])
           (loop lst2 (append res (list res2)))))
        ((string=? (car lst) "]")
         (values (cdr lst) res))
        (else
          (loop (cdr lst) (append res (list (car lst))))))))

  (let-values ([(lst res) (parse-seq lst)])
    res))

それから

(parse-sequence '("this" "is" "a" "test"))
(parse-sequence '("this" "[" "is" "a" "]" "test"))
(parse-sequence '("this" "[" "is" "[" "a" "]" "]" "test"))

降伏します

'("this" "is" "a" "test")
'("this" ("is" "a") "test")
'("this" ("is" ("a")) "test")
于 2012-11-18T18:46:12.447 に答える
0

open-input-stringと組み合わせて使うことで少し進歩しましたread-char:

(define my-sequence (open-input-string "this [is a] test"))

(define (parse-sequence sequence)
  `(item
    ,@(let loop ((next-char (read-char sequence)))
        (cond ((eof-object? next-char) '())
              ((left-square-bracket? next-char)
               (let ((subsequence (get-subsequence sequence)))
                 (cons subsequence
                       (loop (read-char sequence)))))
              (else
               (cons next-char
                     (loop (read-char sequence))))))))

(define (get-subsequence sequence)
  `(subitem
    ,@(let loop ((next-char (read-char sequence)))
        (if (right-square-bracket? next-char)
            '()
            (cons next-char
                  (loop (read-char sequence)))))))

(parse-sequence my-sequence)
===> (item #\t #\h #\i #\s #\space (subitem #\i #\s #\space #\a) #\space #\t #\e #\s #\t)

今、作業は段階的に進んでいます。:)

コメントや提案は引き続き歓迎します。:)

于 2012-11-17T22:31:07.263 に答える