You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将GUI文本框中的字符串表达式转换为Scheme列表?

Scheme表达式字符串转列表的修复方案

问题现状

开发了仅支持加法和乘法的Scheme算术表达式化简程序,GUI模块中需要将用户输入的表达式字符串(如(a + (b * 1)))转换为程序可处理的Scheme列表形式,但当前convert函数的转换结果不符合预期:

> (convert "(a + b)")
'(|(a| + |b)|)

问题根源

原convert函数仅通过空格分割字符串,导致括号与标识符粘在一起被识别为单个符号(如(a、b)),无法正确解析Scheme列表的结构边界。

改进方案

需要先将字符串拆分为独立的语法单元(token):把括号()、运算符+*、标识符(如a、2)分别拆成单独元素,再利用Scheme的read函数直接解析为列表。

实现代码

1. 新增tokenize辅助函数

该函数遍历字符串,将不同语法单元拆分:

(define (tokenize str)
  (let loop ([chars (string->list str)] [current '()] [tokens '()])
    (cond
      [(null? chars)
       ;; 处理最后一个未完成的标识符
       (reverse (if (null? current) tokens (cons (list->string (reverse current)) tokens)))]
      [(member (car chars) '(#\( #\) #\+ #\*))
       ;; 遇到括号或运算符,先保存当前标识符,再添加符号
       (loop (cdr chars)
             '()
             (cons (string (car chars))
                   (if (null? current) tokens (cons (list->string (reverse current)) tokens))))]
      [(char-whitespace? (car chars))
       ;; 遇到空格,保存当前标识符,重置当前缓冲区
       (loop (cdr chars)
             '()
             (if (null? current) tokens (cons (list->string (reverse current)) tokens)))]
      [else
       ;; 收集标识符字符(字母/数字)
       (loop (cdr chars) (cons (car chars) current) tokens)])))

2. 重写convert函数

利用tokenize拆分后的单元,拼接成Scheme可解析的字符串,再用read生成列表:

(define (convert str)
  (read (open-input-string (string-join (tokenize str) " "))))

3. 完整GUI代码

替换原convert函数后的完整代码:

(define (tokenize str)
  (let loop ([chars (string->list str)] [current '()] [tokens '()])
    (cond
      [(null? chars)
       (reverse (if (null? current) tokens (cons (list->string (reverse current)) tokens)))]
      [(member (car chars) '(#\( #\) #\+ #\*))
       (loop (cdr chars)
             '()
             (cons (string (car chars))
                   (if (null? current) tokens (cons (list->string (reverse current)) tokens))))]
      [(char-whitespace? (car chars))
       (loop (cdr chars)
             '()
             (if (null? current) tokens (cons (list->string (reverse current)) tokens)))]
      [else
       (loop (cdr chars) (cons (car chars) current) tokens)])))

(define (convert str)
  (read (open-input-string (string-join (tokenize str) " "))))

; Crée une fenêtre "Simplifier"
(define frame (new frame% [label "Simplifier"]))

; Crée un conteneur "panel"
(define panel (new vertical-panel% [parent frame]))

; Crée un message dans le conteneur "panel"
(define msg (new message%
                 [parent panel]
                 [label "Donnez une expression à simplifier.
N'oubliez pas les parenthèses!"]))

; Crée un champ de texte
(define text-field (new text-field%
                        (label "Expression : ")
                        (parent panel)))

; Crée un message qui affichera le résultat
(define message (new message%
                     (parent panel)
                     (auto-resize #t)
                     (label " ")))

; Faire le bouton "Validez"
(new button% [parent panel]
             [label "Validez"]
             ; Procédure Callback pour un clique sur le bouton "Validez":
             [callback (lambda (button event)
                         (define text (simplifier (convert (send text-field get-value))))
                         (send message set-label (slist->string text)))])

; Affiche la fenêtre
(send frame show #t)

测试验证

> (convert "(a + b)")
'(a + b)
> (convert "((a + 2) * b)")
'((a + 2) * b)
> (convert "(a + (b * 1))")
'(a + (b * 1))

内容的提问来源于stack exchange,提问作者louberlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:47:11