Grammars
Grammars are a way to specify which structures are possible. There are a lot of formal definitions of grammars. We on the other hand will go for a working knowledge. I.e. we will describe how to specify a grammar, and how to implement it in rust.
Grammar Game
We will view grammars as a kind of game. Like any game the grammar game has some
objects to manipulate. The objects to manipulate will be sequences of symbols.
There will be two types of symbols: terminal symbols and non-terminal
symbols. The reason why the symbols are called that way will be given shortly.
Terminal symbols will be written with lowercase words. E.g a, by or cat.
Non-terminal symbols on the other hand will be written starting with an
uppercase letter, followed by lowercase letters.
E.g A, By, Cat.
Besides symbols also have production rules. A production rule is written as follows
1 A -> aAb
It has a single non-terminal symbol on the left of an arrow. To the right of the
arrow is a sequence of symbols. A grammar game can have multiple production
rules, even with the same non-terminal symbol to the left of an arrow. If that
is the case, one is allowed to list the alternative sequences of symbols to the
right of the arrow separated by a pipe |. E.g. given a grammar with two
production rules A -> aA and A -> b, we are allowed to write this as:
1 A -> aA
2 | b
There is an other convention that we will use. Sometimes we will want to replace
a non-terminal symbol with the empty string. This will be represented by a
production rule like A -> ''.
Below you find an example of a grammar that will play a role in the exercises.
1 A -> aAb
2 | B
3 B -> c
4 | ''
How to play?
We are discussing the grammar game, but we failed to mention how to play this game. The game is played by starting with a non terminal symbol. That will be are current sequence of symbols. Next we chose a non terminal symbol from our current sequence, find a production rule which has that symbol to the left of an arrow and apply it. We apply it by replacing the occurrence of the left side of the arrow by the sequence of symbols to the right. This will give us a new current sequence and we can choose a new production rule. We continue as long as there are non-terminal symbols to choose from our current sequence of symbols.
Let’s work out an example. Take the grammar above. We start with the
non-terminal symbol A. We choose the production rule A -> aAb. Applying it
results in the follow sequence of symbols aAb. We choose the same production
rule again and apply it again, resulting in aaAbb. Next we choose the
alternative production rule for A. I.e. A -> B, and apply it to aaAbb.
This transforms into aaBbb. As a last application we choose the production
rule B -> '' resulting in aabb, and we are finished.
We call the act of applying production rules deriving, and when we come to a sequence of only terminal symbols, we say that this sequence can be derived from the non-terminal symbol we started with.
Nadezhda
For the Nadezhda project we are going to look into the following grammar.
1 Program -> forward Program
2 -> backward Program
3 -> stop
This grammar models the decisions our robot cockroach will make in finding her virtual food supply.
Exercises
- Which of the following sequences can be derived from the non-terminal symbol
Agiven the grammar1A -> aAb2| B3B -> c4| ''- ’’
- c
- cc
- ab
- abb
- aab
- aabb
- aacbb
- aaccbb
- For the Nadezhda grammar, is there a limit on the number of forward symbols in a sequence that is derived?
- Create a grammar that is capable of expressing calculations.