Beginning Student Language (BSL) is a programming language in DrRacket. This repository provides some useful BSL-Tools, such as
- Abstract Syntax Tree
- Stepper (Auswertungskontext)
- BSL "Try out" box (Generator)
and semantical support for other grammars.
The module is distributed as a single JavaScript file and an optional additional Racket file for use with Scribble.
The documentation and demos are available at https://se-tuebingen.github.io/bsl-tools/.
You can download them from Releases, the current test build shows the "Development Build" and corresponds to the state of the main branch, you can download semantic versioned editions.
BSL Abstract Syntax Tree
Here we provide the grammar of the BSL Core Language from the Info 1 script, which was our motivation to develop these tools.
<program> ::= <def-or-expr>*
<def-or-expr> ::= <definition> | <e>
<definition> ::= ( define ( <name> <name>+ ) <e> )
| ( define <name> <e> )
| ( define-struct <name> ( <name>* ) )
<e> ::= ( <name> <e>*)
| ( cond {[<e>,<e>]}+)
| <name>
| <v>
For reference see also the Racket webpage for BSL and the Info 1 script at 8.3
Building the project
For building the project, you need to have CMake or a similar tool that can handle
the Makefile
installed. For Linux and MacOS, this should already be the case.
You also need to have NodeJS and NPM installed. On Ubuntu, it is recommended to install it via NodeSource.
You need to run npm install
in a newly cloned project and
anytime dependencies might have changed.
Then, you can run:
make build
to compile and bundle everything undersrc
- grammar, TypeScript sources and assets - intodist/bsl_tools.js
. (Note that the command does not terminate, the TypeScript compiler keeps watching the source for changes.)make test
to compile the Scribble Demo (requires Racket as described below). This also copies the current version of the JavaScript file to the HTML Test files directory (which is not required for them to load the latest version locally, but for distribution e.g. via Github workflow to test on mobile devices).make doc
to compile the documentation underdocs/src
anddocs/demo
todocs/book
(result is opened in your browser automatically). For the scribble demo to be included, you need to have runmake test
first.
Dependencies
Install the latest TypeScript version via npm
. Also see https://www.typescriptlang.org/download.
We are using esbuild to compile TypeScript and bundle all resources into one single JavaScript file.
For generating a BSL parser, we are using the ts-pegjs
package, which builds upon pegjs
.
This package installs a node script which compiles the grammar found in src/grammar/bsl.pegjs
to a TypeScript parser module. The best way to test and edit the grammar is the pegjs online version, since it has syntax highlighting and live testing.
In order to generate a NodeJS-independent binary
(effectively, a binary with
NodeJS bundled, so not exactly lightweight) for the fallback build
out of ts-pegjs
, we are using
the pkg
package.
If you want to contribute to the scribble part of bsl-tools
you need to install Racket first. See https://download.racket-lang.org/
You also need to install dependencies for Scribble, the Racket Documentation Tool, preferably with the racket package manager raco. On Linux distributions you can install Scribble with raco pkg install --deps search-auto scribble-math
.
Fallback build
In the branch fallback_build
, there are binaries of tspegjs
, esbuild
and
mdbook
for Mac, Windows and Linux 64bit systems as well as Makefile entries
for using (fallback_build
and fallback_doc
) and updating them.
This is to future-proof the toolchain, if updates
break something or a tool is no longer supported.
If the regular build does
still work, it might be a good idea to checkout the branch and
run make update_fallback_build
to keep the binaries up-to-date from time to time.
We split this to a separate branch, however, to make the repo a little bit more
lightweight and spare you unnecessary megabytes of downloads.
Testing
Running make test
copies the generated JavaScript file and the latest version
of the Scribble Plugin to the test folders and renders the Scribble test.
In order to be able to render the Scribble test pages, you need to have Racket installed.
The HTML test pages load the JavaScript plugin from the dist
folder if opened
locally (served via file://
), so you do not need to run make test
to update
it - leaving the make build
command running works fine.
Publishing a version
Everytime a tag starting with v
is published, a github workflow similar to the one running when
something is pushed on main will kick off, compile and test the code.
If the tag has the form vX.X.X
(3 numbers), the module will be released under
this name, otherwise, the workflow will fail.
AST View
The Abstract Syntax Tree View shows the Abstract Syntax Tree of a given expression in the BSL grammar (or another given grammar in JSON).
Using AST View with HTML
Including bsl_tools.js
To use the AST-View, you need to add the script anywhere in your document as follows:
<!-- import the bsl_tools script somewhere on the page, ideally in the head -->
<script src="bsl_tools.js"></script>
Note that if you add one or more of the following tools to your page, the script
will add stylesheets to the <head>
of your document which set styles for the
.bsl-tools-stepper
and .bsl-tools-tree
classes.
Planting the <bsltree>
The collapsible AST view can be used with BSL code, which will be parsed for you, or you can provide your own JSON structure.
The interface is as follows:
<bsltree> (valid bsl syntax) </bsltree>
The collapsible AST view also provides an optional "quiz" mode that starts the tree collapsed and expands if you select the correct production and mark all subexpressions ('holes').
<!-- if you want to display it in quiz mode, do -->
<bsltree quiz="true"> (valid bsl syntax) </bsltree>
<!-- for displaying user text in german, do -->
<bsltree quiz="true" lang="de"> (valid bsl syntax) </bsltree>
<!-- displaying code trees for stuff that is not BSL -->
<jsontree quiz="true" lang="de">
<!-- same options as for bsltree -->
{ "production": "Subtraction", "code": "(|2| - |3|)", "holes": [ {
"production": "Number", "code": "2"}, { "production": "Number", "code": "3"} ]
}
</jsontree>
Anything inside the <bsltree>
tag is parsed according to the BSL Core Language as documented below.
<
and >
need to be replaced with <
and >
in order to not break your HTML!
If you want to use <jsontree>
, you need to provide valid JSON - so use double quotes ("
)!
"code"
always needs to be a string, mark holes (code of children) by putting |
s
around it. If you want to, you can provide your own grammar in the "grammar"
field
of the root node, like this:
...
"grammar": {
"production name": ["rule 1", "rule 2"],
...,
"terminal symbol": [],
...
}
...
Note that the object keys need to match exactly the productions you use in your nodes. The Rules are shown as tooltips on hover, and the keys are used as options in quiz mode. If no grammar is specified, quiz mode options are inferred from all occurring productions.
The lang
attribute is only applicable for Quiz mode, since the regular tree does not display any text in natural language. Currently implemented codes are en
(English, default) and de
(German).
Custom Styling
If, for example, your production labels are significantly larger than the text in
your nodes, you can give the nodes (represented by <span>
elements)
greater horizontal spacing with
jsontree .bsl-tools-tree span {
margin-left: 5em;
margin-right: 5em;
}
Note that you need to scope your styles to .bsl-tools-tree
, or they are less
specific than those in the general stylesheet and will be overridden.
Also note that inline CSS is not scoped and will apply to all your jsontree
elements (or whatever you specify).
If you want to change colours, you can also provide css that is more specific than
just .bsl-tools-tree
and override the CSS variables set at the top of
src/ressources/tree.css
.
Using AST View with Scribble
Including the Files
To use the provided scribble module, you need to import it in your document:
@(require "bsl_tools.rkt")
The scribble module does only very little input sanitation and mostly just adds
the JavaScript-Module to your rendered HTML as well as wrapping the input in
the correct custom HTML tags. Both files (bsl_tools.rkt
AND bsl_tools.js
)
need to be in the same folder as well as your scribble file so that everything works.
Scribbling the Trees
For the collapsible AST Production Trees, the interface in Scribble is as follows:
- For BSL Expressions, we use Rackets Syntax Objects, which have a similar structure as S-Expressions
- For other Expressions, you need to provide a JSON object with the correct structure, which will not be checked at compile-time!
@bsltree[
#:quiz #t @; optional keyword argument, default is #f
#:lang "de" @; optional keyword argument, default is "en"
#'((valid bsl syntax))
]
@jsontree[
#:quiz #t @; optional keyword argument, default is #f
#:lang "de" @; optional keyword argument, default is "en"
]{
{
"production": "Subtraction",
"code": "(|2| - |3|)",
"holes": [
{ "production": "Number", "code": "2"},
{ "production": "Number", "code": "3"}
]
}
}
It is necessary to wrap the BSL-Syntax with a #'()
, especially when there are multiple <def-or-expr>
,
however literal values, such as 2
don't need to be wrapped.
The Scribble module parses the BSL-Syntax to a string in a <bsltree>
and adds the javascript module as dependency.
The JSON structure for non-BSL-Syntax needs to contain
- a
"production"
name (string) - some
"code"
(string) optionally with holes fenced by|
- optionally under
"holes"
a list of children with the same structure - optionally the root node can contain a custom
"grammar"
as described in the html API above
If you set the optional keyword argument #:quiz
to #t
, it will add quiz="true"
which displays the tree in quiz mode.
Similarly, the #:lang
keyword argument can be used to set the language code. This is only applicable for Quiz mode, since the regular tree does not display any text in natural language. Currently implemented codes are en
(English, default) and de
(German).
For the @jsontree
-helper, there also is the #:extrastyle
option, whose string
argument will be added inside a HTML <style>
tag above the HTML that is processed
by the Javascript part. This way, you can override some styles, but not set CSS
variables (--
will be converted to –
, sadly).
If, for example, your production labels are significantly larger than the text in
your nodes, you can give the nodes (represented by <span>
elements)
greater horizontal spacing with
#:extrastyle "jsontree .bsl-tools-tree span { margin-left: 2em; margin-right: 2em;}"
Note that you need to scope your styles to .bsl-tools-tree
, or they are less
specific than those in the general stylesheet and will be overridden.
Also note that inline CSS is not scoped and will apply to all your jsontree
elements (or whatever you specify).
Example AST View
Here you can see a few examples of valid Abstract Syntax Trees in BSL Core Language.
AST as a quiz
AST in German
Build your own grammar!
Given is the following Grammar:
"grammar": {
"<FavouriteNumber>": ["<RoundedNumber>", "<Mystery>"],
"<RoundedNumber>": ["0", "3", "6", "8", "9"],
"<Mystery>": ["<Pair>+", "7"],
"<Pair>": ["<RoundedNumber><RoundedNumber>"],
}
We can also make quizzes based on this custom Grammar. For example, why is 68087 a FavouriteNumber?
Small Step Interpreter (Stepper)
The Small Step Interpreter (Stepper) shows each step of BSL programs.
The stepper accepts only syntactic valid BSL programs. It precomputes the evaluation steps and allows users to step through the evaluation of each expression until the program is finished.
Using the Stepper with HTML
Including bsl_tools.js
To use the AST-View, you need to add the script anywhere in your document as follows:
<!-- import the bsl_tools script somewhere on the page, ideally in the head -->
<script src="bsl_tools.js"></script>
Note that if you add one or more of the following tools to your page, the script
will add stylesheets to the <head>
of your document which set styles for the
.bsl-tools-stepper
and .bsl-tools-tree
classes.
Reducing BSL programs with <stepper>
The interface is as follows:
<stepper> (valid bsl syntax) </stepper>
<!-- for displaying user text in german, do -->
<stepper lang="de"> (valid bsl syntax) </stepper>
<
and >
need to be replaced with <
and >
in order to not break your HTML!
Font sizes and styles are deliberately left unset wherever possible in order to just conform to the styling of the rest of the document.
For the code and explanation formats, however, setting the font-family
attributes
is a must. The current stylesheets has chosen some specific fonts, if you do not
agree with them or want to choose your own font, you simply need to override the CSS
variable:
.bsl-tools-stepper {
--font-family-monospace: monospace; /* to use the system default */
--font-family-rule-description: "My fancy font", serif; /* to use your own choice */
}
Place this somewhere where it overrides the default stylesheet that is added to the
document head, e.g. in a style
tag above the first stepper. Other CSS variables
that can be set can be found at the head of src/ressources/small-interpreter.css
.
Using the Stepper with Scribble
Including the Files
To use the provided scribble module, you need to import it in your document:
@(require "bsl_tools.rkt")
The scribble module does only very little input sanitation and mostly just adds
the JavaScript-Module to your rendered HTML as well as wrapping the input in
the correct custom HTML tags. Both files (bsl_tools.rkt
AND bsl_tools.js
)
need to be in the same folder as well as your scribble file so that everything works.
Similar to the AST view functionality, programs are entered as Racket Syntax Objects.
@stepper[
#'((* (+ 1 2 (- 3 9 12) (/ 200 4 5)) (/ 1 2 3) 2)
(cond [(>= 5 5) "isThree"]
[#false 3]
[(or #true #false) (* 2 3 4)]))
]
For German Language support add #:lang "de"
as additional parameter:
@stepper[ #:lang "de"
#'((_ (+ 1 2 (- 3 9 12) (/ 200 4 5)) (/ 1 2 3) 2)
(cond [(>= 5 5) "isThree"]
[#false 3]
[(or #true #false) (_ 2 3 4)]))
]
Stepper Example
Generator
Adding a simple bsltoolsgenerator
tag in your HTML, like so:
<!-- import the bsl_tools script somewhere on the page, ideally in the head -->
<script src="bsl_tools.js"></script>
<bsltoolsgenerator></bsltoolsgenerator>
gives you the textarea
and buttons below, which you can use to generate your
your own Stepper and AST Views, if you give valid BSL programs!
Unfortunately there is no support for Scribble yet.