The syntax of R5RS Scheme in Backus-Naur form

Course links

<program> ::= {<command-or-definition>}*

<command-or-definition> ::= <command>
                          | <definition>
                          | <syntax-definition>
                          | "("  "begin" {<command-or-definition>}+ ")"

<command> ::= <expression>

<expression> ::= <variable>
               | <literal>
               | <procedure-call>
               | <lambda-expression>
               | <conditional>
               | <assignment>
               | <derived-expression>
               | <macro-use>
               | <macro-block>

<literal> ::= <quotation>
            | <self-evaluating>

<quotation> ::= "'" <datum>
              | "(" "quote" <datum> ")"

<datum> ::= <simple-datum>
          | <compound-datum>

<simple-datum> ::= <boolean>
                 | <number>
                 | <character>
                 | <string>
                 | <symbol>

<compound-datum> ::= <list>
                   | <vector>

<list> ::= "(" {<datum>}* ")"
         | "(" {<datum>}+ "." <datum> ")"
         | <abbreviation>

<abbreviation> ::= <abbreviation-prefix> <datum>

<abbreviation-prefix> ::= "'"
                        | "`"
                        | ","
                        | ",@"

<vector> ::= "#(" {<datum>}* ")"

<self-evaluating> ::= <boolean>
                    | <number>
                    | <character>
                    | <string>

<procedure-call> ::= "(" <operator> {<operand>}* ")"

<operator> ::= <expression>

<operand> ::= <expression>

<lambda-expression> ::= "(" "lambda" <formals> <body> ")"

<formals> ::= "(" {<variable>}* ")"
            | <variable>
            | "(" {<variable>}+ "." <variable> ")"

<body> ::= {<definition>}* <sequence>

<sequence> ::= {<command>}* <expression>

<conditional> ::= "(" "if" <test> <consequent> {<alternate>}? ")"

<test> ::= <expression>

<consequent> ::= <expression>

<alternate> ::= <expression>

<assignment> ::= "(" "set!" <variable> <expression> ")"

<derived-expression> ::= "(" "cond" {<cond-clause>}+ ")"
                       | "(" "cond" {<cond-clause>}* "(" "else" <sequence> ")" ")"
                       | "(" "case" <expression> {<case-clause>}+ ")"
                       | "(" "case" <expression> {<case-clause>}* "(" "else" <sequence> ")" ")"
                       | "(" "and" {<test>}* ")"
                       | "(" "or" {<test>}* ")"
                       | "(" "let" "(" {<binding-specification>}* ")" <body> }
                       | "(" "let" <variable> "(" {<binding-specification>}* ")" <body> }
                       | "(" "let*" "(" {<binding-specification>}* ")" <body> }
                       | "(" "letrec" "(" {<binding-specification>}* ")" <body> }
                       | "(" "begin" <sequence> ")"
                       | "(" "do" "(" {<iteration-specification>}* ")" "(" <test> {<do-result>}? ")" {<command>}* ")"
                       | "(" "delay" <expression> ")"
                       | <quasiquotation>

<cond-clause> ::= "(" <test> <sequence> ")"
                | "(" <test> ")"
                | "(" <test> "=>" <recipient> ")"

<recipient> ::= <expression>

<case-clause> ::= "(" "(" {<datum>}* ")" <sequence> ")"

<binding-specification> ::= "(" <variable> <expression> ")"

<iteration-specification> ::= "(" <variable> <init> {<step>}? ")"

<init> ::= <expression>

<step> ::= <expression>

<do-result> ::= <sequence>

<quasiquotation> ::= "`" <quasiquotation-template>
                   | "(" quasiquote <quasiquotation-template> ")"

<quasiquotation-template> ::= <expression>
                            | <simple-datum>
                            | <list-quasiquotation-template>
                            | <vector-quasiquotation-template>
                            | <unquotation>

<list-quasiquotation-template> ::= "(" {<quasiquotation-template-or-splice>}* ")"

<quasiquotation-template-or-splice> ::= <quasiquotation-template>
                                      | <splicing-unquotation>

<splicing-unquotation> ::= ",@" <quasiquotation-template>
                         | "(" unquote-splicing <quasiquotation-template> ")"

<vector-quasiquotation-template> ::= "#(" {<quasiquotation-template-or-splice>}* ")"

<unquotation> ::= "," <quasiquotation-template>
                | "(" unquote <quasiquotation-template> ")"

<macro-use> ::= "(" <keyword> {<datum>}* ")"

<macro-block> ::= "(" "let-syntax" "(" {<syntax-specification>}* ")" <body> ")"
                | "(" "letrec-syntax" "(" {<syntax-specification>}* ")" <body> ")"

<syntax-specification> ::= "(" <keyword> <transformer-specification> ")"

<transformer-specification> ::= "(" "syntax-rules" "(" {<identifier>}* ")" {<syntax-rule>}* ")"

<syntax-rule> ::= "(" <pattern> <template> ")"

<pattern> ::= <pattern-identifier>
            | "(" {<pattern>}* ")"
            | "(" {<pattern>}+ "." <pattern> ")"
            | "(" {<pattern>}* <pattern> <ellipsis> ")"
            | #( {<pattern>}* ")"
            | #( {<pattern>}* <pattern> <ellipsis> ")"
            | <pattern-datum>

<pattern-identifier> ::= <any-identifier-except-the-ellipsis>

<ellipsis> ::= "..."

<pattern-datum> ::= <string>
                  | <character>
                  | <boolean>
                  | <number>

<template> ::= <pattern-identifier>
             | "(" {<template-element>}* ")"
             | "(" {<template-element>}+ "." <template-element> ")"
             | #( {<template-element>}* ")"
             | <template-datum>

<template-element> ::= <template>
                     | <template> <ellipsis>

<template-datum> ::= <pattern-datum>

<definition> ::= "(" "define" <variable> <expression> ")"
               | "(" "define" "(" <variable> <definition-formals> ")" <body> ")"
               | "(" "begin" {<definition>}* ")"

<definition-formals> ::= {<variable>}*
                       | {<variable>}* "." <variable>

<syntax-definition> ::= "(" "define-syntax" <keyword> <transformer-specification> ")"

This grammar was adapted from the one in section 7.1 of Revised5 report on the algorithmic language Scheme, edited by Richard Kelsey, William Clinger, and Jonathan Rees (n.p: published 1998).