为EOPL中的LET语言添加数组索引访问功能遇阻求助
为LET语言添加数组索引访问支持
针对你基于EOPL中LET语言扩展数组的需求,以下是实现索引访问功能的具体步骤:
1. 扩展语法定义
首先在表达式语法中添加数组索引访问的规则,同时新增对应的抽象语法树节点:
修改语法解析规则
在expression的parser定义中添加索引访问的分支:
(expression ; 保留原有所有语法规则... ("array" "{" expression (arbno "," expression) "}") array-exp ("<" expression ">" "[" expression "]") array-index-exp)
新增抽象语法树节点
在define-datatype expression中添加array-index-exp:
(define-datatype expression expression? ; 保留原有所有节点... (array-exp (e1 expression?) (exps (list-of expression?))) (array-index-exp (arr-expr expression?) (index-expr expression?)))
2. 实现索引访问的求值逻辑
在eval-expression函数中添加处理array-index-exp的分支,处理数组取值、索引转换(1-based转0-based)以及嵌套数组的支持:
(define eval-expression (lambda (exp env) (cases expression exp ; 保留原有所有求值分支... (array-exp (e1 exps) ; 沿用你已实现的逻辑,将array转成list-exp求值 (eval-expression (list-exp (cons e1 exps)) env)) (array-index-exp (arr-expr index-expr) (let* ([arr-val (eval-expression arr-expr env)] [index-val (eval-expression index-expr env)]) ; 验证数组值类型 (cases expval arr-val (list-val (elements) ; 验证索引值类型 (cases expval index-val (num-val (n) ; 检查索引是否在有效范围(1-based) (if (and (>= n 1) (<= n (length elements))) ; 转成0-based索引取元素,自动支持嵌套数组 (list-ref elements (- n 1)) (eopl:error 'eval-expression "Invalid array index: ~s" n))) (else (eopl:error 'eval-expression "Expected number as index, got ~s" index-val)))) (else (eopl:error 'eval-expression "Expected array (list) for indexing, got ~s" arr-val)))))))
3. 验证示例代码
你的测试代码:
let A = array {10, -(5,7) , zero?(8), array {1,2,3}, 12 } in -(<A>[1] , <<A>[4]>[2])
求值流程:
A被解析为list-val,包含元素:(num-val 10)、(num-val -2)、(bool-val #f)、(list-val (num-val 1) (num-val 2) (num-val 3))、(num-val 12)<A>[1]取第1个元素,得到(num-val 10)<A>[4]取第4个元素(嵌套数组),再通过[2]取其第2个元素,得到(num-val 2)- 最终计算
-(10, 2),返回(num-val 8),符合预期。
关键说明
- 由于你已将
array-exp映射为list-exp,数组本质是LET语言中的list类型,因此嵌套数组天然支持——当索引访问返回的是list-val时,再次进行索引访问会自动递归处理。 - 代码中添加了类型检查和索引范围校验,避免非法输入导致的错误。
内容的提问来源于stack exchange,提问作者Dani Dubinskey
相关产品推荐
相关产品推荐

