S-表达式在Lisp中既用作代码,也用作数据(见McCarthy Recursive Functions of Symbolic Expressions )。S-表达式原本被用于将被M-表达式处理的数据,但Lisp的首个实现是一个S-表达式的解释器,以S-表达式编码M-表达式,而Lisp程序员很快习惯于对代码和数据都使用S-表达式。
所谓“S-表达式/运算式”或“sexp”(其中“S”代表“符号的”),是指一种以人类可读的文本形式表达半结构化数据的约定。S-表达式可能以其在Lisp家族的编程语言中的使用而为人所知。其他应用则见于由Lisp衍生的语言,如DSSSL,以及如IMAP之类通信协议中作为标记出现和约翰·麦卡锡的CBCL。语法细节和所支持的数据类型虽因语言而异,但这些语言间最通用的特性则是使用S-表达式作为括号化的前缀表示法(有时亦作剑桥波兰表示法)。
S-表达式可以是如数字这样的单个对象,包括特殊原子nil和t在内的LISP 原子,或写作 (x . y)的cons pair。更长的列表则由嵌套的cons pair组成,例如(1 . (2 . (3 . nil)))(,亦可写作更易理解的(1 2 3))。
1997年5月,Ron Rivest 提交了一份 Internet-草案 ,拟作为
RFC出版。该草案定义了基于Lisp S-表达式的语法,但旨在用于一般目的的数据存储及交换(类似
XML)而非仅限于编程。尽管未被批准为
RFC,但此草案已被其他RFC(如
RFC2693)和数种出版物[3]引用。最原始的用途则是在SPKI中。
Rivest的格式定义了S-表达式为一个八位元组-串(一系列字节)或其他S-表达式的有限列表。此定义描述了三种表达这种结构的互换格式。一种为“advanced transport”——以格式而言具有很大弹性,且语法上近似于Lisp-风格表达式,但并不等同。例如,advanced transport允许八位元组-串逐字表示(串的长度后跟随一分号及整个原始的串),引号形式允许转义字符,十六进制,Base64,或者在满足一定条件时直接作为“token”。(Rivest的token与Lisp token不同之处在于前者仅仅为了方便与审美,像其他字符串一样对待,而后者有特别的语法意义。)为了更为紧密,更便于语法分析,独立于任何抽象的S-表达式,另一种交换格式“canonical presentation”仅允许逐字表示的字符串,格式上禁止字符串以外的空白。