Scheme语言自定义语法结构时的Literal identifier
2004-09-28 17:25
393 查看
Scheme语言允许用户使用let-syntax等机制自定义特殊的语法结构。定义这种语法结构时使用的Pattern language里有一个不太显眼的Literal identifier,就是下面语法中的<literals>:
(syntax-rules <literals> <syntax rule> ... )
Scheme标准R5RS里对Literal identifier的阐释比较晦涩难懂。我根据自己的理解写了一个小例子,大概可以起到补充说明的作用:
;;; 不使用Literal identifier时定义语法z
(define-syntax z
(syntax-rules ()
((z (+ x y)) (+ x y))))
;;; 下面一行的结果是 7
(z (+ 3 4))
;;; 下面一行的结果是 -1,在局部改变意义后的加号起了作用
(let ((+ -)) (z (+ 3 4)))
;;; 使用Literal identifier时定义语法z
(define-syntax z
(syntax-rules (+)
((z (+ x y)) (+ x y))))
;;; 下面一行的结果仍是 7
(z (+ 3 4))
;;; 下面这一行报错:z: bad syntax in: (z (+ 3 4))
;;; 与定义语法时含义不同(其实是绑定不同)的加号无法应用到这样的语法中
(let ((+ -)) (z (+ 3 4)))
有了上面这个例子,R5RS里提到的那个较复杂的例子就比较好理解了:
(define-syntax cond
(syntax-rules (else =>)
((cond (else result1 result2 ...))
(begin result1 result2 ...))
((cond (test => result))
(let ((temp test))
(if temp (result temp))))
((cond (test => result) clause1 clause2 ...)
(let ((temp test))
(if temp
(result temp)
(cond clause1 clause2 ...))))
((cond (test)) test)
((cond (test) clause1 clause2 ...)
(let ((temp test))
(if temp
temp
(cond clause1 clause2 ...))))
((cond (test result1 result2 ...))
(if test (begin result1 result2 ...)))
((cond (test result1 result2 ...)
clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(cond clause1 clause2 ...)))))
在上面这样的cond定义基础上,下面的代码
(let ((=> #f))
(cond (#t => 'ok))) ; =) ok
将被解释为(这里的=>被视为变量而不是语法元素)
(let ((=> #f))
(if #t (begin => 'ok)))
而不是
(let ((=> #f))
(let ((temp #t))
(if temp ('ok temp))))
因为局部的=>已经被改变了含义,不能匹配到包含=>的语法规则了。
(syntax-rules <literals> <syntax rule> ... )
Scheme标准R5RS里对Literal identifier的阐释比较晦涩难懂。我根据自己的理解写了一个小例子,大概可以起到补充说明的作用:
;;; 不使用Literal identifier时定义语法z
(define-syntax z
(syntax-rules ()
((z (+ x y)) (+ x y))))
;;; 下面一行的结果是 7
(z (+ 3 4))
;;; 下面一行的结果是 -1,在局部改变意义后的加号起了作用
(let ((+ -)) (z (+ 3 4)))
;;; 使用Literal identifier时定义语法z
(define-syntax z
(syntax-rules (+)
((z (+ x y)) (+ x y))))
;;; 下面一行的结果仍是 7
(z (+ 3 4))
;;; 下面这一行报错:z: bad syntax in: (z (+ 3 4))
;;; 与定义语法时含义不同(其实是绑定不同)的加号无法应用到这样的语法中
(let ((+ -)) (z (+ 3 4)))
有了上面这个例子,R5RS里提到的那个较复杂的例子就比较好理解了:
(define-syntax cond
(syntax-rules (else =>)
((cond (else result1 result2 ...))
(begin result1 result2 ...))
((cond (test => result))
(let ((temp test))
(if temp (result temp))))
((cond (test => result) clause1 clause2 ...)
(let ((temp test))
(if temp
(result temp)
(cond clause1 clause2 ...))))
((cond (test)) test)
((cond (test) clause1 clause2 ...)
(let ((temp test))
(if temp
temp
(cond clause1 clause2 ...))))
((cond (test result1 result2 ...))
(if test (begin result1 result2 ...)))
((cond (test result1 result2 ...)
clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(cond clause1 clause2 ...)))))
在上面这样的cond定义基础上,下面的代码
(let ((=> #f))
(cond (#t => 'ok))) ; =) ok
将被解释为(这里的=>被视为变量而不是语法元素)
(let ((=> #f))
(if #t (begin => 'ok)))
而不是
(let ((=> #f))
(let ((temp #t))
(if temp ('ok temp))))
因为局部的=>已经被改变了含义,不能匹配到包含=>的语法规则了。
相关文章推荐
- Scheme语言自定义语法结构时的Literal identifier
- IOS开发语言OC的基本语法以及结构
- C#语言参考--(2)语法结构-1
- C#语言语法结构
- Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库 自定义日志记录功能,按日记录,很方便 C#常量和字段以及各种方法的语法总结 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法 asp.net webapi 自定义身份验证
- ASP脚本语言jscript基本结构与语法
- Go语言基础知识总结(语法、变量、数值类型、表达式、控制结构等)
- ASP脚本语言jscript基本结构与语法
- 【OC-2】OC语言基础二(自定义初始化、点语法)(连载二)
- Java语言语法-控制结构
- Linux&C语言知识结构图
- 通过自定义的URL Scheme启动你的App
- 我的Java之旅 第四课 JAVA 语言语法 基础
- PostgreSql 添加语言语法
- c 语言语法
- C语言结构、共用体、Typedef
- 黑马程序员——高新技术---Java基础语法-循环结构和跳转语句
- XML入门精解之结构与语法
- Verilog HDL语言的用户自定义元件