#lang scribble/manual

@title{BSL Grammar}

This is the full BSL grammar. For a gentler introduction to the language,
please see the programs in the @tt{examples} folder.

NOTE: braces are not part of the grammar -- they are used to indicate
groupings of tokens.

@verbatim|{

<program>                     ::= <def-expr-test-bang-newline>*
<def-expr-test-bang-newline>  ::= <def-expr-test-bang>
                               |  <newline>
<def-expr-test-bang>          ::= <definition>
                               |  <expr>
                               |  <test-case>
                               |  <big-bang>


<definition>                  ::= <def-style-definition>
                               |  <fun-style-definition>
                               |  struct: <id> (<id-list>?) <newline>
<def-style-definition>        ::= def <id>: <expr>
<fun-style-definition>        ::= fun <id> (<id-list>?): <test-expr> <newline>
                               |  fun <id> (<id-list>?): <newline> <local-defs>* <expr>
<id-list>                     ::= <id> {, <id>}*
<local-defs>                  ::= <def-style-definition>
                               |  <fun-style-definition>


<expr>                        ::= <test-expr> <newline>
                               |  <compound-expr>
<test-expr>                   ::= <simple-expr>
                               |  <boolean-comparison>
                               |  <test-expr> and <test-expr>
                               |  <test-expr> or <test-expr>
                               |  not <test-expr>
<boolean-comparison>          ::= <simple-expr> <boolean-comp-simple>+
<boolean-comp-simple>         ::= <boolean-comp-op> <simple-expr>
<boolean-comp-op>             ::= < | <= | = | != | >= | > | in 
                               |  not in
<simple-expr>                 ::= <value-expr>
                               |  + <simple-expr>
                               |  - <simple-expr>
                               |  <simple-expr> + <simple-expr>
                               |  <simple-expr> - <simple-expr>
                               |  <simple-expr> * <simple-expr>
                               |  <simple-expr> / <simple-expr>
                               |  <simple-expr> % <simple-expr>
                               |  <simple-expr> ** <simple-expr>
                               |  <value-expr>[<index-expr>]
                               |  <template-expr>
<index-expr>          ::= <simple-expr>
                       |  <simple-expr>:<simple-expr>
                       |  <simple-expr>:<simple-expr>:<simple-expr>
<template-expr>               ::= ..
                               |  ...
                               |  ....
                               |  .....
                               |  ......
<value-expr>                  ::= empty
                               |  True
                               |  False
                               |  <id>
                               |  <number>
                               |  <image>
                               |  <string>
                               |  <list-expr>
                               |  (<test-expr>)
                               |  <id> (<id-list>?)
<list-expr>                   ::= [ ]
                               |  [<simple-expr>{, <simple-expr>}*]
<compound-expr>               ::= <conditional>
<conditional>                 ::= <if-expr> <else-expr>
                               |  <if-expr> <elif-expr>+ <if-end-marker>
<if-end-marker>               ::= <else-expr>
                               |  :done
<if-expr>                     ::= if <test-expr>: <newline>? <expr>
<elif-expr>                   ::= elif <test-expr>: <newline>? <expr>
<else-expr>                   ::= else: <newline>? <expr>


                               
<test-case>                   ::= test: <test-expr> is: <test-expr>


<big-bang>                    ::= big_bang(<big-bang-clause>*) <newline>
<big-bang-clause>             ::= <id> = <test-expr> {, <big-bang-clause>}*

}|

@include-section{grammar/literals.scrbl}

